package com.vincent.rsf.server.api.service.impl; import com.vincent.rsf.server.api.config.RemotesInfoProperties; import com.vincent.rsf.server.api.controller.erp.params.DapIlcwmsCompletionLine; import com.vincent.rsf.server.api.controller.erp.params.DapIlcwmsCompletionRequest; import com.vincent.rsf.server.api.controller.erp.params.InOutResultReportParam; import com.vincent.rsf.server.api.controller.erp.params.InventoryAdjustReportParam; import com.vincent.rsf.server.api.feign.CloudWmsErpFeignClient; import com.vincent.rsf.server.api.integration.dap.DapIlcwmsResponseNormalizer; import com.vincent.rsf.server.api.service.CloudWmsReportService; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 立库侧请求云仓:9.1 鼎捷 ilcwmsplus 入/出库两接口;9.2 仍为 /api/report/inventoryAdjust,报文与 9.1 同为 {data:[]}。 */ @Slf4j @Service public class CloudWmsReportServiceImpl implements CloudWmsReportService { @Autowired private RemotesInfoProperties erpApi; @Autowired private CloudWmsErpFeignClient cloudWmsErpFeignClient; @Override public Map syncMatnrsToCloud(Object body) { if (!isCloudWmsConfigured()) { log.warn("ErpApi(云仓WMS) 未配置 host,跳过物料基础信息同步"); return stubSuccess("云仓地址未配置,未实际同步"); } return cloudWmsErpFeignClient.syncMatnrs(body != null ? body : new HashMap<>()); } @Override public Map reportInOutResult(InOutResultReportParam param) { if (param == null) { return resultMap(400, "参数不能为空", null); } if (!isCloudWmsConfigured()) { log.warn("ErpApi(云仓WMS) 未配置 host,跳过 9.1 入/出库结果上报,订单:{}", param.getOrderNo()); return stubSuccess("云仓地址未配置,未实际上报"); } String err = validateDapBase(); if (err != null) { return resultMap(400, err, null); } boolean inbound = param.getInbound() == null || Boolean.TRUE.equals(param.getInbound()); DapIlcwmsCompletionRequest req = new DapIlcwmsCompletionRequest() .setData(Collections.singletonList(buildInOutLine(param, inbound))); Map raw = inbound ? cloudWmsErpFeignClient.cusInventoryCompletionReport(req) : cloudWmsErpFeignClient.cusOutboundCompletionReport(req); return DapIlcwmsResponseNormalizer.toNotifyFormat(raw); } @Override public Map reportInventoryAdjust(InventoryAdjustReportParam param) { if (param == null) { return resultMap(400, "参数不能为空", null); } if (!isCloudWmsConfigured()) { log.warn("ErpApi(云仓WMS) 未配置 host,跳过 9.2 库存调整上报,物料:{}", param.getMatNr()); return stubSuccess("云仓地址未配置,未实际上报"); } String err = validateDapBase(); if (err != null) { return resultMap(400, err, null); } Integer changeType = param.getChangeType(); if (changeType == null) { return resultMap(400, "changeType 不能为空", null); } DapIlcwmsCompletionRequest req = new DapIlcwmsCompletionRequest(); if (changeType == 3) { String baseSeq = StringUtils.isNotBlank(param.getDocSeqNo()) ? param.getDocSeqNo() : "1"; List lines = new ArrayList<>(2); lines.add(buildAdjustLine(param, false, true, baseSeq + "-O")); lines.add(buildAdjustLine(param, true, false, baseSeq + "-I")); req.setData(lines); } else if (changeType == 1) { req.setData(Collections.singletonList(buildAdjustLine(param, true, false, null))); } else if (changeType == 2) { req.setData(Collections.singletonList(buildAdjustLine(param, false, true, null))); } else { return resultMap(400, "不支持的 changeType:" + changeType, null); } Map raw = cloudWmsErpFeignClient.reportInventoryAdjust(req); return DapIlcwmsResponseNormalizer.toNotifyFormatFlexible(raw); } private DapIlcwmsCompletionLine buildInOutLine(InOutResultReportParam param, boolean inbound) { RemotesInfoProperties.Dap dap = erpApi.getDap(); DapIlcwmsCompletionLine line = new DapIlcwmsCompletionLine() .setOrgNo(dap.getOrgNo()) .setDocType(inbound ? dap.getDocTypeIn() : dap.getDocTypeOut()) .setDocNo(param.getOrderNo()) .setDocSeqNo(StringUtils.isNotBlank(param.getLineId()) ? param.getLineId() : "1") .setItemNo(param.getMatNr()) .setQty(parseQty(param.getQty())) .setUnitNo(dap.getUnitNo()) .setCombinationLotNo(param.getBatch()) .setBarcode(resolveBarcode(param)); if (inbound) { line.setInWarehouseNo(param.getWareHouseId()).setInCellNo(param.getLocId()); } else { line.setOutWarehouseNo(param.getWareHouseId()).setOutCellNo(param.getLocId()); } return line; } /** * @param fillIn 是否填入库储位 * @param fillOut 是否填出库储位 * @param docSeqOverride 非空时用作项次(移库第二行等) */ private DapIlcwmsCompletionLine buildAdjustLine(InventoryAdjustReportParam param, boolean fillIn, boolean fillOut, String docSeqOverride) { RemotesInfoProperties.Dap dap = erpApi.getDap(); String docType = resolveAdjustDocType(param, dap); String docNo = StringUtils.isNotBlank(param.getDocNo()) ? param.getDocNo() : "ADJ"; String docSeq = docSeqOverride != null ? docSeqOverride : (StringUtils.isNotBlank(param.getDocSeqNo()) ? param.getDocSeqNo() : "1"); String unit = StringUtils.isNotBlank(param.getUnitNo()) ? param.getUnitNo() : dap.getUnitNo(); DapIlcwmsCompletionLine line = new DapIlcwmsCompletionLine() .setOrgNo(dap.getOrgNo()) .setDocType(docType) .setDocNo(docNo) .setDocSeqNo(docSeq) .setItemNo(param.getMatNr()) .setQty(parseQty(param.getQty())) .setUnitNo(unit) .setCombinationLotNo(param.getBatch()) .setBarcode(resolveAdjustBarcode(param)); if (fillIn) { line.setInWarehouseNo(param.getWareHouseId()); line.setInCellNo(StringUtils.isNotBlank(param.getTargetLocId()) ? param.getTargetLocId() : param.getSourceLocId()); } if (fillOut) { line.setOutWarehouseNo(param.getWareHouseId()); line.setOutCellNo(StringUtils.isNotBlank(param.getSourceLocId()) ? param.getSourceLocId() : param.getTargetLocId()); } return line; } private static String resolveAdjustDocType(InventoryAdjustReportParam param, RemotesInfoProperties.Dap dap) { if (StringUtils.isNotBlank(param.getDocType())) { return param.getDocType(); } Integer ct = param.getChangeType(); if (ct != null && ct == 2) { return dap.getDocTypeOut(); } if (ct != null && ct == 3) { return dap.getDocTypeAdj(); } return dap.getDocTypeIn(); } private static String resolveBarcode(InOutResultReportParam param) { if (StringUtils.isNotBlank(param.getBarcode())) { return param.getBarcode(); } if (StringUtils.isNotBlank(param.getPalletId())) { return param.getPalletId(); } if (param.getMatNr() != null && param.getLocId() != null) { return param.getMatNr() + ":" + param.getLocId(); } return param.getMatNr(); } private static String resolveAdjustBarcode(InventoryAdjustReportParam param) { if (StringUtils.isNotBlank(param.getBarcode())) { return param.getBarcode(); } if (StringUtils.isNotBlank(param.getPalletId())) { return param.getPalletId(); } return param.getMatNr(); } private static Double parseQty(String q) { if (StringUtils.isBlank(q)) { return 0d; } try { return Double.parseDouble(q.trim()); } catch (NumberFormatException e) { return 0d; } } private String validateDapBase() { RemotesInfoProperties.Dap d = erpApi.getDap(); if (d == null || StringUtils.isBlank(d.getOrgNo())) { return "未配置 platform.erp.dap.org-no"; } return null; } private boolean isCloudWmsConfigured() { String host = erpApi.getHost(); return host != null && !host.trim().isEmpty(); } private Map stubSuccess(String msg) { Map data = new HashMap<>(); data.put("result", "SUCCESS"); return resultMap(200, msg, data); } private Map resultMap(int code, String msg, Map data) { Map map = new HashMap<>(); map.put("code", code); map.put("msg", msg); map.put("data", data); return map; } }