From 704265308b1227dbada5a36b2027b588c062ded2 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期一, 12 十月 2026 09:14:37 +0800
Subject: [PATCH] feat(mes): 新增业务码支持并优化追溯查询功能
---
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesServiceImpl.java | 224 +++++++++++++++++++++++++++++++++++++------------------
1 files changed, 151 insertions(+), 73 deletions(-)
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesServiceImpl.java
index 628720f..b72e8f0 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesServiceImpl.java
@@ -52,7 +52,13 @@
import org.springframework.validation.annotation.Validated;
import java.math.BigDecimal;
-import java.util.List;
+import java.util.*;
+import java.util.stream.Collectors;
+import cn.iocoder.yudao.module.mes.dal.mysql.pro.bagcode.MesProBagCodeMapper;
+import cn.iocoder.yudao.module.mes.dal.mysql.pro.pallet.MesProPalletMapper;
+import cn.iocoder.yudao.module.mes.dal.mysql.pro.batch.MesProBatchMapper;
+import cn.iocoder.yudao.module.mes.dal.mysql.wm.materialstockbag.MesWmMaterialStockBagMapper;
+import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstockbag.MesWmMaterialStockBagDO;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
@@ -103,6 +109,10 @@
@Resource
private MesTraceIntegrityService integrityService;
+ @Resource private MesProBagCodeMapper pickingBagMapper;
+ @Resource private MesProPalletMapper pickingPalletMapper;
+ @Resource private MesProBatchMapper pickingBatchMapper;
+ @Resource private MesWmMaterialStockBagMapper pickingStockBagMapper;
@Override
public Long createProductSales(MesWmProductSalesSaveReqVO createReqVO) {
@@ -222,83 +232,150 @@
return true;
}
+ private record PickingScope(String type, Long id, MesProBatchDO batch, List<MesProBagCodeDO> bags) { }
+
+ private PickingScope pickingScope(String code, String type, boolean lock) {
+ if (type == null || type.isBlank()) {
+ type = palletService.getPalletByScanCode(code) != null ? "PALLET"
+ : bagCodeService.getBagCodeByScanCode(code) != null ? "BAG" : "BATCH";
+ }
+ MesProBatchDO batch;
+ List<MesProBagCodeDO> bags;
+ Long id;
+ switch (type) {
+ case "BAG" -> {
+ MesProBagCodeDO bag = lock ? pickingBagMapper.selectByScanCodeForUpdate(code) : bagCodeService.getBagCodeByScanCode(code);
+ if (bag == null || Integer.valueOf(30).equals(bag.getStatus())) throw new IllegalArgumentException("琚嬬爜涓嶅瓨鍦ㄦ垨宸蹭綔搴�");
+ id = bag.getId(); batch = proBatchService.getBatch(bag.getBatchId()); bags = List.of(bag);
+ }
+ case "PALLET" -> {
+ MesProPalletDO pallet = lock ? pickingPalletMapper.selectByScanCodeForUpdate(code) : palletService.getPalletByScanCode(code);
+ if (pallet == null || Integer.valueOf(20).equals(pallet.getStatus())) throw new IllegalArgumentException("鎵樼洏涓嶅瓨鍦ㄦ垨宸蹭綔搴�");
+ if (pallet.getBatchId() == null) throw exception(PRO_PALLET_NOT_BIND_BATCH);
+ id = pallet.getId(); batch = proBatchService.getBatch(pallet.getBatchId());
+ bags = lock ? pickingBagMapper.selectListByPalletIdForUpdate(id) : bagCodeService.getBagCodeListByPalletId(id);
+ }
+ case "BATCH" -> {
+ batch = lock ? pickingBatchMapper.selectByScanCodeForUpdate(code) : proBatchService.getBatchByScanCode(code);
+ if (batch == null) throw new IllegalArgumentException("鐢熶骇鎵规鐮佷笉瀛樺湪");
+ id = batch.getId(); bags = lock ? pickingBagMapper.selectListByBatchIdForUpdate(id) : bagCodeService.getBagCodeListByBatchId(id);
+ }
+ default -> throw new IllegalArgumentException("涓嶆敮鎸佺殑鎷h揣鎵爜绫诲瀷");
+ }
+ if (batch == null || batch.getItemId() == null || Integer.valueOf(40).equals(batch.getStatus()))
+ throw new IllegalArgumentException("鏈粦瀹氭湁鏁堝搧绉嶆垨鐢熶骇鎵规宸蹭綔搴�");
+ return new PickingScope(type, id, batch, bags.stream().filter(b -> !Integer.valueOf(30).equals(b.getStatus()))
+ .sorted(Comparator.comparing(MesProBagCodeDO::getId)).toList());
+ }
+
+ private String unavailable(MesProBagCodeDO bag, MesWmMaterialStockBagDO stockBag,
+ Map<Long, MesWmMaterialStockDO> stocks, List<MesWmProductSalesDetailDO> occupied, MesProBatchDO batch) {
+ if (!Objects.equals(bag.getBatchId(), batch.getId())) return "琚嬬爜鎵规褰掑睘寮傚父";
+ if (bag.getItemId() != null && !Objects.equals(bag.getItemId(), batch.getItemId())) return "琚嬬爜鍝佺褰掑睘寮傚父";
+ if (!MesProBagCodeQcStatusEnum.QUALIFIED.getStatus().equals(bag.getQcStatus())) return "灏氭湭璐ㄦ鍚堟牸";
+ if (stockBag == null || !Integer.valueOf(1).equals(stockBag.getStatus())) return "涓嶅湪搴撴垨宸插嚭搴�";
+ if (Boolean.TRUE.equals(stockBag.getFrozen())) return "琚嬬爜宸插喕缁�";
+ if (!Integer.valueOf(20).equals(stockBag.getStockState()) || !Objects.equals(stockBag.getItemId(), batch.getItemId())
+ || !stocks.containsKey(stockBag.getMaterialStockId()) || stockBag.getQuantity() == null || BigDecimal.ONE.compareTo(stockBag.getQuantity()) != 0)
+ return "琚嬬爜涓嶅湪鏈夋晥鍚堟牸搴撳瓨涓�";
+ if (occupied.stream().anyMatch(d -> Objects.equals(d.getBagCodeId(), bag.getId())
+ || d.getBagCodeId() == null && bag.getPalletId() != null && Objects.equals(d.getPalletCodeId(), bag.getPalletId())))
+ return "宸插姞鍏ュ嚭搴撳崟鎷h揣";
+ return null;
+ }
+
+ @Override
+ public MesWmProductSalesScanRespVO previewScan(String code) { return previewScan(code, null, null); }
+
+ /** 鍙璇嗗埆锛屽苟杩斿洖姣忚鐨勫彲閫夌姸鎬侊紝涓嶅垱寤哄簱瀛樻壒娆℃垨鎷h揣璁板綍銆� */
+ @Override
+ public MesWmProductSalesScanRespVO previewScan(String code, String scanType, Long salesId) {
+ PickingScope scope = pickingScope(code, scanType, false);
+ if (salesId != null) {
+ MesWmProductSalesDO sales = validateProductSalesExists(salesId);
+ if (!Integer.valueOf(2).equals(sales.getStatus())) throw exception(WM_PRODUCT_SALES_CANNOT_PICK);
+ if (productSalesLineService.getProductSalesLineListBySalesId(salesId).stream()
+ .noneMatch(l -> Objects.equals(l.getItemId(), scope.batch().getItemId()))) throw exception(WM_PRODUCT_SALES_DETAIL_ITEM_MISMATCH);
+ }
+ MesWmBatchDO wmBatch = mesWmBatchService.getBatchByCode(scope.batch().getCode());
+ Map<Long, MesWmMaterialStockDO> stocks = wmBatch == null ? Map.of() : materialStockService
+ .getQualifiedMaterialStockListByItemAndBatch(scope.batch().getItemId(), wmBatch.getId()).stream()
+ .collect(Collectors.toMap(MesWmMaterialStockDO::getId, x -> x));
+ Map<Long, MesWmMaterialStockBagDO> stockBags = pickingStockBagMapper.selectByBagIds(scope.bags().stream().map(MesProBagCodeDO::getId).toList(), false)
+ .stream().collect(Collectors.toMap(MesWmMaterialStockBagDO::getBagCodeId, x -> x));
+ List<MesWmProductSalesDetailDO> occupied = productSalesDetailMapper.selectPickingByBatchCode(scope.batch().getCode());
+ List<MesWmProductSalesScanRespVO.BagOption> options = scope.bags().stream().map(b -> {
+ String reason = unavailable(b, stockBags.get(b.getId()), stocks, occupied, scope.batch());
+ return new MesWmProductSalesScanRespVO.BagOption().setId(b.getId()).setCode(b.getCode()).setBusinessCode(b.getBusinessCode())
+ .setPalletId(b.getPalletId()).setSelectable(reason == null).setUnavailableReason(reason);
+ }).toList();
+ return new MesWmProductSalesScanRespVO().setScanType(scope.type()).setCodeId(scope.id()).setScanContent(code)
+ .setBatchCode(scope.batch().getCode()).setItemId(scope.batch().getItemId()).setBagCount(options.size()).setBags(options)
+ .setScanQuantity(BigDecimal.valueOf(options.stream().filter(o -> Boolean.TRUE.equals(o.getSelectable())).count()));
+ }
+
@Override
@Transactional(rollbackFor = Exception.class)
public MesWmProductSalesScanRespVO scanProductSales(MesWmProductSalesScanReqVO reqVO) {
- MesWmProductSalesDO sales = validateProductSalesExists(reqVO.getSalesId());
- if (ObjUtil.notEqual(MesWmProductSalesStatusEnum.APPROVING.getStatus(), sales.getStatus())) {
- throw exception(WM_PRODUCT_SALES_CANNOT_PICK);
+ MesWmProductSalesDO sales = productSalesMapper.selectByIdForUpdate(reqVO.getSalesId());
+ if (sales == null) throw exception(WM_PRODUCT_SALES_NOT_EXISTS);
+ if (!Integer.valueOf(2).equals(sales.getStatus())) throw exception(WM_PRODUCT_SALES_CANNOT_PICK);
+ PickingScope scope = pickingScope(reqVO.getScanContent(), reqVO.getScanType(), true);
+ List<Long> ids = reqVO.getBagIds();
+ if (ids == null && "BAG".equals(scope.type())) ids = List.of(scope.id());
+ if (ids == null || ids.isEmpty() || new HashSet<>(ids).size() != ids.size())
+ throw new IllegalArgumentException("璇烽�夋嫨鍏蜂綋琚嬬爜锛屼笉鍏佽閲嶅琚嬬爜");
+ BigDecimal quantity = BigDecimal.valueOf(ids.size());
+ if (reqVO.getQuantity() != null && quantity.compareTo(reqVO.getQuantity()) != 0)
+ throw new IllegalArgumentException("鎷h揣鏁伴噺蹇呴』涓庢墍閫夎鐮佹暟閲忎竴鑷�");
+ Set<Long> selectedIds = new HashSet<>(ids);
+ List<MesProBagCodeDO> selected = scope.bags().stream().filter(b -> selectedIds.contains(b.getId())).toList();
+ if (selected.size() != ids.size()) throw new IllegalArgumentException("鎵�閫夎鐮佷笉灞炰簬褰撳墠鎵爜瀵硅薄鎴栧凡浣滃簾锛岃閲嶆柊鏍稿");
+ // 閿佸畾瀹為檯琚嬬爜鍜屽簱瀛樿鏄庣粏锛岃法鍑哄簱鍗曠殑鎵爜涔熶笉鑳介噸澶嶆嫞閫夊悓涓�琚嬨��
+ List<MesWmMaterialStockBagDO> stockBagRows = pickingStockBagMapper.selectByBagIds(ids, true);
+ Map<Long, MesWmMaterialStockBagDO> stockBags = stockBagRows.stream().collect(Collectors.toMap(MesWmMaterialStockBagDO::getBagCodeId, x -> x));
+ List<MesWmProductSalesDetailDO> occupied = productSalesDetailMapper.selectPickingByBatchCodeForUpdate(scope.batch().getCode());
+ List<MesWmProductSalesDetailDO> own = occupied.stream().filter(d -> Objects.equals(d.getSalesId(), sales.getId())).toList();
+ long already = selected.stream().filter(b -> own.stream().anyMatch(d -> Objects.equals(d.getBagCodeId(), b.getId()))).count();
+ if (already == selected.size()) return new MesWmProductSalesScanRespVO().setScanType(scope.type()).setCodeId(scope.id())
+ .setScanContent(reqVO.getScanContent()).setSelectedBagIds(ids).setAlreadyScanned(true).setOutboundQuantity(quantity)
+ .setDetailId(own.stream().filter(d -> selectedIds.contains(d.getBagCodeId())).findFirst().orElseThrow().getId()).setMessage("鎵�閫夎鐮佸凡鍦ㄦ湰鍗曟嫞璐ф槑缁嗕腑");
+ if (already > 0) throw new IllegalArgumentException("鎵�閫夎鐮侀儴鍒嗗凡鍔犲叆鏈崟锛岃閲嶆柊閫夋嫨鏈嫞琚嬬爜");
+ MesWmBatchDO wmBatch = mesWmBatchService.getBatchByCode(scope.batch().getCode());
+ if (wmBatch == null) throw exception(WM_TRANSACTION_BATCH_NOT_EXISTS);
+ Map<Long, MesWmMaterialStockDO> stocks = materialStockService.getQualifiedMaterialStockListByItemAndBatch(scope.batch().getItemId(), wmBatch.getId())
+ .stream().collect(Collectors.toMap(MesWmMaterialStockDO::getId, x -> x));
+ for (MesProBagCodeDO bag : selected) {
+ String reason = unavailable(bag, stockBags.get(bag.getId()), stocks, occupied, scope.batch());
+ if (reason != null) throw new IllegalArgumentException("琚嬬爜 " + bag.getCode() + "锛�" + reason);
}
- MesProPalletDO pallet = palletService.getPalletByCode(reqVO.getScanContent());
- MesProBagCodeDO bag = pallet == null ? bagCodeService.getBagCodeByCode(reqVO.getScanContent()) : null;
- if (pallet == null && bag == null) {
- throw exception(WM_MATERIAL_STOCK_NOT_EXISTS);
- }
- // 鏈粦瀹氱敓浜ф壒娆$殑涓存椂鎵樼洏涓嶅厑璁稿弬涓庨攢鍞嚭搴�
- if (pallet != null && pallet.getBatchId() == null) {
- throw exception(PRO_PALLET_NOT_BIND_BATCH);
- }
- // 绉嶅瓙璐ㄦ鎸夎鐮佺矑搴︽祦杞悗锛屽嚭搴撳彧鍏佽宸茶川妫�鍚堟牸鐨勮鐮�/鎵樼洏
- if (pallet != null) {
- List<MesProBagCodeDO> palletBags = bagCodeService.getBagCodeListByPalletId(pallet.getId());
- if (palletBags.stream().anyMatch(b -> !MesProBagCodeQcStatusEnum.QUALIFIED.getStatus().equals(b.getQcStatus()))) {
- throw exception(WM_PRODUCT_SALES_SCAN_PALLET_NOT_ALL_QUALIFIED);
- }
- } else if (!MesProBagCodeQcStatusEnum.QUALIFIED.getStatus().equals(bag.getQcStatus())) {
- throw exception(WM_PRODUCT_SALES_SCAN_BAG_NOT_QUALIFIED);
- }
- Long codeId = pallet != null ? pallet.getId() : bag.getId();
- MesWmProductSalesDetailDO existed = pallet != null
- ? productSalesDetailMapper.selectBySalesIdAndPalletCodeId(reqVO.getSalesId(), codeId)
- : productSalesDetailMapper.selectBySalesIdAndBagCodeId(reqVO.getSalesId(), codeId);
- if (existed != null) {
- return new MesWmProductSalesScanRespVO().setScanType(pallet != null ? "PALLET" : "BAG")
- .setCodeId(codeId).setScanContent(reqVO.getScanContent()).setAlreadyScanned(true)
- .setDetailId(existed.getId()).setOutboundQuantity(existed.getQuantity()).setMessage("璇ョ爜宸叉壂鎻�");
- }
- Long proBatchId = pallet != null ? pallet.getBatchId() : bag.getBatchId();
- MesProBatchDO batch = proBatchService.getBatch(proBatchId);
- if (batch == null) {
- throw exception(WM_TRANSACTION_BATCH_NOT_EXISTS);
- }
- // 鐢熶骇鎵规妗ユ帴浠撳簱鎵规锛氭壂鐮佸叆搴撳啓鍏ョ殑鏄粨搴撴壒娆★紙mes_wm_batch锛夛紝姝ゅ蹇呴』鐢ㄤ粨搴撴壒娆� id 鏌ュ簱瀛�
- MesWmBatchDO wmBatch = mesWmBatchService.getOrCreateByProBatch(batch);
- if (wmBatch == null) {
- throw exception(WM_TRANSACTION_BATCH_NOT_EXISTS);
- }
- List<MesWmProductSalesLineDO> lines = productSalesLineService.getProductSalesLineListBySalesId(reqVO.getSalesId());
- MesWmProductSalesLineDO line = lines.stream().filter(item -> ObjUtil.equal(item.getItemId(), batch.getItemId())).findFirst().orElse(null);
- if (line == null) {
- throw exception(WM_PRODUCT_SALES_DETAIL_ITEM_MISMATCH);
- }
- BigDecimal quantity = reqVO.getQuantity();
- if (quantity == null) {
- quantity = line.getQuantity();
- }
- // 鍙粠鍚堟牸搴撹褰曚腑閫夊簱瀛橈紙鍚屾壒娆℃殏瀛樺簱璁板綍涓嶅彲鍑哄簱锛�
- List<MesWmMaterialStockDO> stocks = materialStockService.getQualifiedMaterialStockListByItemAndBatch(batch.getItemId(), wmBatch.getId());
- BigDecimal outboundQuantity = quantity;
- MesWmMaterialStockDO stock = stocks.stream().filter(item -> item.getQuantity().compareTo(outboundQuantity) >= 0).findFirst().orElse(null);
- if (stock == null) {
- throw exception(WM_MATERIAL_STOCK_INSUFFICIENT);
- }
+ MesWmProductSalesLineDO line = productSalesLineService.getProductSalesLineListBySalesId(sales.getId()).stream()
+ .filter(l -> Objects.equals(l.getItemId(), scope.batch().getItemId())).findFirst().orElse(null);
+ if (line == null) throw exception(WM_PRODUCT_SALES_DETAIL_ITEM_MISMATCH);
BigDecimal scanned = productSalesDetailService.getProductSalesDetailListByLineId(line.getId()).stream()
.map(MesWmProductSalesDetailDO::getQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
- if (scanned.add(quantity).compareTo(line.getQuantity()) > 0) {
- throw exception(WM_PRODUCT_SALES_LINE_QUANTITY_INVALID);
+ if (line.getQuantity() == null || scanned.add(quantity).compareTo(line.getQuantity()) > 0) throw exception(WM_PRODUCT_SALES_LINE_QUANTITY_INVALID);
+ Map<Long, Long> byStock = selected.stream().collect(Collectors.groupingBy(b -> stockBags.get(b.getId()).getMaterialStockId(), Collectors.counting()));
+ for (var allocation : byStock.entrySet()) {
+ BigDecimal ownStockQty = own.stream().filter(d -> Objects.equals(d.getMaterialStockId(), allocation.getKey()))
+ .map(MesWmProductSalesDetailDO::getQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
+ if (stocks.get(allocation.getKey()).getQuantity().compareTo(ownStockQty.add(BigDecimal.valueOf(allocation.getValue()))) < 0)
+ throw exception(WM_MATERIAL_STOCK_INSUFFICIENT);
}
- MesWmProductSalesDetailDO detail = new MesWmProductSalesDetailDO().setLineId(line.getId())
- .setSalesId(reqVO.getSalesId()).setItemId(batch.getItemId()).setQuantity(quantity)
- .setMaterialStockId(stock.getId()).setBatchId(wmBatch.getId()).setBatchCode(wmBatch.getCode())
- .setWarehouseId(stock.getWarehouseId()).setLocationId(stock.getLocationId()).setAreaId(stock.getAreaId())
- .setBagCodeId(pallet == null ? codeId : null).setPalletCodeId(pallet != null ? codeId : null);
- productSalesDetailMapper.insert(detail);
- return new MesWmProductSalesScanRespVO().setScanType(pallet != null ? "PALLET" : "BAG")
- .setCodeId(codeId).setScanContent(reqVO.getScanContent()).setItemId(batch.getItemId())
- .setBatchId(wmBatch.getId()).setBatchCode(wmBatch.getCode()).setMaterialStockId(stock.getId())
- .setAvailableQuantity(stock.getQuantity()).setScanQuantity(quantity).setOutboundQuantity(quantity)
- .setAlreadyScanned(false).setDetailId(detail.getId()).setWarehouseId(stock.getWarehouseId())
- .setLocationId(stock.getLocationId()).setAreaId(stock.getAreaId()).setMessage("鎵爜鎴愬姛");
+ Long firstDetail = null;
+ for (MesProBagCodeDO bag : selected) {
+ MesWmMaterialStockDO stock = stocks.get(stockBags.get(bag.getId()).getMaterialStockId());
+ MesWmProductSalesDetailDO detail = new MesWmProductSalesDetailDO().setSalesId(sales.getId()).setLineId(line.getId())
+ .setItemId(scope.batch().getItemId()).setQuantity(BigDecimal.ONE).setBagCodeId(bag.getId())
+ .setPalletCodeId(bag.getPalletId()).setBatchId(wmBatch.getId()).setBatchCode(wmBatch.getCode()).setMaterialStockId(stock.getId())
+ .setWarehouseId(stock.getWarehouseId()).setLocationId(stock.getLocationId()).setAreaId(stock.getAreaId())
+ .setRemark("鎵爜绫诲瀷 " + scope.type() + "锛涙潵婧愮爜 " + reqVO.getScanContent() + "锛涜鐮� " + bag.getCode());
+ productSalesDetailMapper.insert(detail);
+ if (firstDetail == null) firstDetail = detail.getId();
+ }
+ return new MesWmProductSalesScanRespVO().setScanType(scope.type()).setCodeId(scope.id()).setScanContent(reqVO.getScanContent())
+ .setItemId(scope.batch().getItemId()).setBatchCode(wmBatch.getCode()).setSelectedBagIds(ids)
+ .setScanQuantity(quantity).setOutboundQuantity(quantity).setAlreadyScanned(false).setDetailId(firstDetail).setMessage("宸叉寜鎵�閫夎鐮佸姞鍏ユ嫞璐�");
}
@Override
@@ -398,7 +475,8 @@
if (detail.getBagCodeId() != null) {
bagCodeService.markOutbound(detail.getBagCodeId(), id);
}
- if (detail.getPalletCodeId() != null) {
+ // 閮ㄥ垎鎵樼洏鎷h揣鍙兘鍒嗙粰澶氫釜缁忛攢鍟嗭紝涓嶈兘鎶婃暣涓墭鐩樻爣璁颁负鏈崟鍑哄簱銆�
+ if (detail.getPalletCodeId() != null && detail.getBagCodeId() == null) {
palletService.markOutbound(detail.getPalletCodeId(), id);
}
}
@@ -428,7 +506,7 @@
.setType(MesWmTransactionTypeEnum.OUT.getType()).setItemId(detail.getItemId())
.setQuantity(detail.getQuantity().negate()) // 鍑哄簱鏁伴噺涓鸿礋鏁�
.setBatchId(detail.getBatchId()).setBatchCode(detail.getBatchCode())
- .setBagCodeId(detail.getBagCodeId()) // 琚嬬爜鍨嬫槑缁嗗嚭搴撴椂缃鐮佸凡鍑哄簱锛涙墭鐩樺瀷鏄庣粏涓嶉�愯澶勭悊
+ .setBagCodeId(detail.getBagCodeId()) // 鏂版壂鐮佹槑缁嗛�愯鍏宠仈锛屾墽琛屽嚭搴撻�愯鏇存柊搴撳瓨鐘舵��
.setWarehouseId(detail.getWarehouseId()).setLocationId(detail.getLocationId()).setAreaId(detail.getAreaId())
.setBizType(MesBizTypeConstants.WM_PRODUCT_SALES).setBizId(sales.getId())
.setBizCode(sales.getCode()).setBizLineId(detail.getLineId())
--
Gitblit v1.9.3