|
@@ -31,19 +31,25 @@ public class ErpPickMaterialService {
|
|
|
private final ErpInventoryLotService erpInventoryLotService;
|
|
private final ErpInventoryLotService erpInventoryLotService;
|
|
|
private final MesErpPickKcService mesErpPickKcService;
|
|
private final MesErpPickKcService mesErpPickKcService;
|
|
|
private final ErpInteractionLogService erpInteractionLogService;
|
|
private final ErpInteractionLogService erpInteractionLogService;
|
|
|
|
|
+ private final ErpStockLocService erpStockLocService;
|
|
|
|
|
+ private final ErpProductionOrderService erpProductionOrderService;
|
|
|
|
|
|
|
|
public ErpPickMaterialService(KingdeeErpClient erpClient,
|
|
public ErpPickMaterialService(KingdeeErpClient erpClient,
|
|
|
KingdeeErpProperties erpProperties,
|
|
KingdeeErpProperties erpProperties,
|
|
|
ErpProductionMaterialService erpProductionMaterialService,
|
|
ErpProductionMaterialService erpProductionMaterialService,
|
|
|
ErpInventoryLotService erpInventoryLotService,
|
|
ErpInventoryLotService erpInventoryLotService,
|
|
|
MesErpPickKcService mesErpPickKcService,
|
|
MesErpPickKcService mesErpPickKcService,
|
|
|
- ErpInteractionLogService erpInteractionLogService) {
|
|
|
|
|
|
|
+ ErpInteractionLogService erpInteractionLogService,
|
|
|
|
|
+ ErpStockLocService erpStockLocService,
|
|
|
|
|
+ ErpProductionOrderService erpProductionOrderService) {
|
|
|
this.erpClient = erpClient;
|
|
this.erpClient = erpClient;
|
|
|
this.erpProperties = erpProperties;
|
|
this.erpProperties = erpProperties;
|
|
|
this.erpProductionMaterialService = erpProductionMaterialService;
|
|
this.erpProductionMaterialService = erpProductionMaterialService;
|
|
|
this.erpInventoryLotService = erpInventoryLotService;
|
|
this.erpInventoryLotService = erpInventoryLotService;
|
|
|
this.mesErpPickKcService = mesErpPickKcService;
|
|
this.mesErpPickKcService = mesErpPickKcService;
|
|
|
this.erpInteractionLogService = erpInteractionLogService;
|
|
this.erpInteractionLogService = erpInteractionLogService;
|
|
|
|
|
+ this.erpStockLocService = erpStockLocService;
|
|
|
|
|
+ this.erpProductionOrderService = erpProductionOrderService;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public ErpPickMaterialResult submit(ErpPickMaterialSubmitRequest request) {
|
|
public ErpPickMaterialResult submit(ErpPickMaterialSubmitRequest request) {
|
|
@@ -66,6 +72,12 @@ public class ErpPickMaterialService {
|
|
|
return ErpPickMaterialResult.fail("未找到对应的生产用料清单");
|
|
return ErpPickMaterialResult.fail("未找到对应的生产用料清单");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ String statusMsg = erpProductionOrderService.validatePickableBusinessStatus(
|
|
|
|
|
+ request.getBillNo(), request.getEntryId());
|
|
|
|
|
+ if (StringUtils.isNotBlank(statusMsg)) {
|
|
|
|
|
+ return ErpPickMaterialResult.fail(statusMsg);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
List<PickLineContext> pickLines = new ArrayList<>();
|
|
List<PickLineContext> pickLines = new ArrayList<>();
|
|
|
for (ErpPickMaterialSubmitRequest.Line line : request.getLines()) {
|
|
for (ErpPickMaterialSubmitRequest.Line line : request.getLines()) {
|
|
|
if (line == null || StringUtils.isBlank(line.getPpbomEntryId())) {
|
|
if (line == null || StringUtils.isBlank(line.getPpbomEntryId())) {
|
|
@@ -84,11 +96,32 @@ public class ErpPickMaterialService {
|
|
|
return ErpPickMaterialResult.fail("物料 " + material.getMaterialNumber()
|
|
return ErpPickMaterialResult.fail("物料 " + material.getMaterialNumber()
|
|
|
+ " 领料数量不能超过未领数量 " + noPickedQty);
|
|
+ " 领料数量不能超过未领数量 " + noPickedQty);
|
|
|
}
|
|
}
|
|
|
- String validateMsg = validateMaterial(material, pickQty, firstNonBlank(line.getLotNumber(), material.getLotNumber()));
|
|
|
|
|
|
|
+ erpProductionMaterialService.resolveBatchManageFlag(material);
|
|
|
|
|
+ String lotNumber = resolvePickLotNumber(material, pickQty,
|
|
|
|
|
+ firstNonBlank(line.getLotNumber(), material.getLotNumber()));
|
|
|
|
|
+ String validateMsg = validateMaterial(material, pickQty, lotNumber);
|
|
|
if (StringUtils.isNotBlank(validateMsg)) {
|
|
if (StringUtils.isNotBlank(validateMsg)) {
|
|
|
return ErpPickMaterialResult.fail(validateMsg);
|
|
return ErpPickMaterialResult.fail(validateMsg);
|
|
|
}
|
|
}
|
|
|
- pickLines.add(new PickLineContext(material, pickQty, firstNonBlank(line.getLotNumber(), material.getLotNumber())));
|
|
|
|
|
|
|
+ String locNumber = StringUtils.trim(line.getStockLocNumber());
|
|
|
|
|
+ String locKey = StringUtils.trim(line.getStockLocKey());
|
|
|
|
|
+ String locMsg = resolveAndValidateStockLoc(material, locNumber, locKey);
|
|
|
|
|
+ if (StringUtils.isNotBlank(locMsg)) {
|
|
|
|
|
+ return ErpPickMaterialResult.fail(locMsg);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (StringUtils.isBlank(locNumber) && erpStockLocService.requiresStockLocation(material.getStockNumber())) {
|
|
|
|
|
+ List<ErpStockLocOption> locations = erpStockLocService.findLocationsByStock(material.getStockNumber());
|
|
|
|
|
+ locNumber = erpStockLocService.resolveDefaultLocNumber(material.getStockNumber(), locations);
|
|
|
|
|
+ if (StringUtils.isBlank(locKey) && locations != null) {
|
|
|
|
|
+ for (ErpStockLocOption option : locations) {
|
|
|
|
|
+ if (option != null && locNumber.equals(option.getLocNumber())) {
|
|
|
|
|
+ locKey = option.getLocKey();
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ pickLines.add(new PickLineContext(material, pickQty, lotNumber, locNumber, locKey));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (pickLines.isEmpty()) {
|
|
if (pickLines.isEmpty()) {
|
|
@@ -170,7 +203,27 @@ public class ErpPickMaterialService {
|
|
|
return "物料 " + materialLabel
|
|
return "物料 " + materialLabel
|
|
|
+ " ERP 即时库存无批号(与 ERP 查询一致),无法领料。请先在 ERP 做采购入库/生产入库/调拨后再领";
|
|
+ " ERP 即时库存无批号(与 ERP 查询一致),无法领料。请先在 ERP 做采购入库/生产入库/调拨后再领";
|
|
|
}
|
|
}
|
|
|
- return "物料 " + materialLabel + " 启用了批号管理,请先点击「选批号」选择批号后再提交";
|
|
|
|
|
|
|
+ return "物料 " + materialLabel + " 启用了批号管理,发料仓无可用批号可自动带出,无法领料";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * PDA 可不传仓库/仓位/批号:仓库用用料清单发料仓,仓位用仓库默认,批号按发料仓库存自动推荐。
|
|
|
|
|
+ */
|
|
|
|
|
+ private String resolvePickLotNumber(ErpProductionMaterial material, BigDecimal pickQty, String requestedLot) {
|
|
|
|
|
+ String lotNumber = StringUtils.trim(requestedLot);
|
|
|
|
|
+ if (StringUtils.isNotBlank(lotNumber)) {
|
|
|
|
|
+ return lotNumber;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (material == null || !material.isBatchManage()) {
|
|
|
|
|
+ return "";
|
|
|
|
|
+ }
|
|
|
|
|
+ List<ErpInventoryLotOption> lots = erpInventoryLotService.findAvailableLots(
|
|
|
|
|
+ material.getMaterialNumber(),
|
|
|
|
|
+ material.getStockNumber(),
|
|
|
|
|
+ material.getStockStatusNumber(),
|
|
|
|
|
+ material.getStockOrgNumber());
|
|
|
|
|
+ return StringUtils.trimToEmpty(erpInventoryLotService.suggestLotNumber(
|
|
|
|
|
+ lots, pickQty, material.getStockNumber()));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private String formatQty(BigDecimal qty) {
|
|
private String formatQty(BigDecimal qty) {
|
|
@@ -270,6 +323,7 @@ public class ErpPickMaterialService {
|
|
|
entity.put("FStockUnitId", numberObject(stockUnit, false));
|
|
entity.put("FStockUnitId", numberObject(stockUnit, false));
|
|
|
putPickQuantities(entity, qty);
|
|
putPickQuantities(entity, qty);
|
|
|
entity.put("FStockId", numberObject(material.getStockNumber(), false));
|
|
entity.put("FStockId", numberObject(material.getStockNumber(), false));
|
|
|
|
|
+ putStockLoc(entity, material.getStockNumber(), pickLine.stockLocNumber, pickLine.stockLocKey);
|
|
|
entity.put("FStockStatusId", numberObject(stockStatus, false));
|
|
entity.put("FStockStatusId", numberObject(stockStatus, false));
|
|
|
entity.put("FMoBillNo", material.getBillNo());
|
|
entity.put("FMoBillNo", material.getBillNo());
|
|
|
if (StringUtils.isNotBlank(material.getMoId())) {
|
|
if (StringUtils.isNotBlank(material.getMoId())) {
|
|
@@ -326,6 +380,48 @@ public class ErpPickMaterialService {
|
|
|
&& unitNumber.equals(stockUnit);
|
|
&& unitNumber.equals(stockUnit);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ private String resolveAndValidateStockLoc(ErpProductionMaterial material, String locNumber, String locKey) {
|
|
|
|
|
+ String stockNumber = material == null ? "" : material.getStockNumber();
|
|
|
|
|
+ if (!erpStockLocService.requiresStockLocation(stockNumber)) {
|
|
|
|
|
+ return "";
|
|
|
|
|
+ }
|
|
|
|
|
+ String loc = StringUtils.trim(locNumber);
|
|
|
|
|
+ String key = StringUtils.trim(locKey);
|
|
|
|
|
+ if (StringUtils.isBlank(loc)) {
|
|
|
|
|
+ List<ErpStockLocOption> locations = erpStockLocService.findLocationsByStock(stockNumber);
|
|
|
|
|
+ loc = erpStockLocService.resolveDefaultLocNumber(stockNumber, locations);
|
|
|
|
|
+ }
|
|
|
|
|
+ String msg = erpStockLocService.validateStockLocForSave(stockNumber, loc, key);
|
|
|
|
|
+ if (StringUtils.isBlank(msg)) {
|
|
|
|
|
+ return "";
|
|
|
|
|
+ }
|
|
|
|
|
+ return "物料 " + material.getMaterialNumber() + " 发料仓已启用仓位管理," + msg;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void putStockLoc(JSONObject entity, String stockNumber, String locNumber, String locKey) {
|
|
|
|
|
+ if (!erpStockLocService.requiresStockLocation(stockNumber)) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ String loc = StringUtils.trim(locNumber);
|
|
|
|
|
+ String key = StringUtils.trim(locKey);
|
|
|
|
|
+ if (StringUtils.isBlank(loc)) {
|
|
|
|
|
+ List<ErpStockLocOption> locations = erpStockLocService.findLocationsByStock(stockNumber);
|
|
|
|
|
+ loc = erpStockLocService.resolveDefaultLocNumber(stockNumber, locations);
|
|
|
|
|
+ if (StringUtils.isBlank(key) && locations != null) {
|
|
|
|
|
+ for (ErpStockLocOption option : locations) {
|
|
|
|
|
+ if (option != null && loc.equals(option.getLocNumber())) {
|
|
|
|
|
+ key = option.getLocKey();
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ Long stockLocId = erpStockLocService.resolveStockLocIdForSave(stockNumber, loc, key);
|
|
|
|
|
+ if (stockLocId != null && stockLocId > 0L) {
|
|
|
|
|
+ entity.put("FStockLocId", stockLocId);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private JSONArray buildEntityLink(ErpProductionMaterial material, BigDecimal qty) {
|
|
private JSONArray buildEntityLink(ErpProductionMaterial material, BigDecimal qty) {
|
|
|
Object erpQty = ErpKingdeeParseUtils.toErpQty(qty);
|
|
Object erpQty = ErpKingdeeParseUtils.toErpQty(qty);
|
|
|
JSONObject link = new JSONObject(true);
|
|
JSONObject link = new JSONObject(true);
|
|
@@ -407,11 +503,16 @@ public class ErpPickMaterialService {
|
|
|
private final ErpProductionMaterial material;
|
|
private final ErpProductionMaterial material;
|
|
|
private final BigDecimal pickQty;
|
|
private final BigDecimal pickQty;
|
|
|
private final String lotNumber;
|
|
private final String lotNumber;
|
|
|
|
|
+ private final String stockLocNumber;
|
|
|
|
|
+ private final String stockLocKey;
|
|
|
|
|
|
|
|
- private PickLineContext(ErpProductionMaterial material, BigDecimal pickQty, String lotNumber) {
|
|
|
|
|
|
|
+ private PickLineContext(ErpProductionMaterial material, BigDecimal pickQty, String lotNumber,
|
|
|
|
|
+ String stockLocNumber, String stockLocKey) {
|
|
|
this.material = material;
|
|
this.material = material;
|
|
|
this.pickQty = pickQty;
|
|
this.pickQty = pickQty;
|
|
|
this.lotNumber = lotNumber;
|
|
this.lotNumber = lotNumber;
|
|
|
|
|
+ this.stockLocNumber = stockLocNumber;
|
|
|
|
|
+ this.stockLocKey = stockLocKey;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|