From 1d086bd2cc499a08141f3cd2affbcc5b9e4639ff Mon Sep 17 00:00:00 2001 From: 10002617 Date: Sat, 9 May 2026 09:24:18 +0800 Subject: [PATCH] =?UTF-8?q?1483=20=E5=8F=91=E8=B4=A7=E7=AE=A1=E7=90=86-PDA?= =?UTF-8?q?-=E8=A3=85=E7=AE=B1=E8=8F=9C=E5=8D=95=E4=B8=8B=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E4=BF=AE=E6=94=B9=EF=BC=8C=E6=89=AB=E7=A0=81=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E5=8F=AF=E5=88=A0=E9=99=A4=EF=BC=8C=E6=95=B0=E9=87=8F?= =?UTF-8?q?=E5=8F=AF=E7=BC=96=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wms/common/pojo/dto/BomMaterialDTO.java | 6 +- .../common/pojo/qo/MaterialCodeItemAddQO.java | 17 -- .../pojo/qo/MaterialCodeItemUpdateQO.java | 16 -- .../qo/ShipmentPackingMaterialInfoQO.java | 15 ++ .../wms/common/pojo/qo/ShipmentPackingQO.java | 2 +- .../qo/ShipmentUnPackingMaterialInfoQO.java | 15 ++ .../common/pojo/qo/ShipmentUnpackingQO.java | 4 +- .../pojo/vo/ShipmentMaterialCodeItemVO.java | 5 - .../pojo/vo/ShipmentMaterialCodeQRVO.java | 7 + .../entity/WmsShipmentMaterialCodeItem.java | 30 ++- .../WmsShipmentMaterialCodeItemMapper.java | 2 - .../IWmsShipmentMaterialCodeItemService.java | 10 +- ...ShipmentMaterialCodeItemQrServiceImpl.java | 17 +- ...msShipmentMaterialCodeItemServiceImpl.java | 35 ++- .../WmsShipmentMaterialCodeItemMapper.xml | 20 -- .../WmsShipmentMaterialCodeItemQrMapper.xml | 2 +- .../WmsShipmentPackagingCodeItemMapper.xml | 2 +- .../controller/MaterialCodeController.java | 230 ++++++++---------- .../controller/PackagingCodeController.java | 192 ++++++++++----- .../shipment/pojo/vo/MaterialCodeItemVO.java | 15 -- .../template/物料码打印导入模板.xlsx | Bin 0 -> 12518 bytes 21 files changed, 345 insertions(+), 297 deletions(-) create mode 100644 nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/ShipmentPackingMaterialInfoQO.java create mode 100644 nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/ShipmentUnPackingMaterialInfoQO.java create mode 100644 nflg-wms-shipment/src/main/resources/template/物料码打印导入模板.xlsx diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/BomMaterialDTO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/BomMaterialDTO.java index f4a066c9..2e737819 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/BomMaterialDTO.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/BomMaterialDTO.java @@ -5,7 +5,6 @@ import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import lombok.Data; import lombok.experimental.Accessors; -import org.ttzero.excel.annotation.ExcelColumn; import java.math.BigDecimal; import java.util.List; @@ -76,4 +75,9 @@ public class BomMaterialDTO { */ @NotEmpty private List children; + + /** + * 物料单位 + */ + private String materialUnit; } diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/MaterialCodeItemAddQO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/MaterialCodeItemAddQO.java index a37acc48..bde62beb 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/MaterialCodeItemAddQO.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/MaterialCodeItemAddQO.java @@ -33,12 +33,6 @@ public class MaterialCodeItemAddQO { @NotNull private BigDecimal num; - /** - * 实发数量 - */ - @NotNull - private BigDecimal actualNum; - /** * 单位 */ @@ -62,15 +56,4 @@ public class MaterialCodeItemAddQO { */ @NotBlank private String productionOrderNumber; - - /** - * 箱号 - */ - @NotBlank - private String boxNo; - - /** - * 最小包装量 - */ - private BigDecimal minPackagingNum; } diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/MaterialCodeItemUpdateQO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/MaterialCodeItemUpdateQO.java index 9f46a6eb..279eb3c3 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/MaterialCodeItemUpdateQO.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/MaterialCodeItemUpdateQO.java @@ -24,12 +24,6 @@ public class MaterialCodeItemUpdateQO { @NotNull private BigDecimal num; - /** - * 实发数量 - */ - @NotNull - private BigDecimal actualNum; - /** * 单位 */ @@ -54,14 +48,4 @@ public class MaterialCodeItemUpdateQO { @NotBlank private String productionOrderNumber; - /** - * 箱号 - */ - @NotBlank - private String boxNo; - - /** - * 最小包装量 - */ - private BigDecimal minPackagingNum; } diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/ShipmentPackingMaterialInfoQO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/ShipmentPackingMaterialInfoQO.java new file mode 100644 index 00000000..637d4b46 --- /dev/null +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/ShipmentPackingMaterialInfoQO.java @@ -0,0 +1,15 @@ +package com.nflg.wms.common.pojo.qo; + +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class ShipmentPackingMaterialInfoQO { + @NotNull + private Long materialQRId; + + @NotNull + private BigDecimal actualNum; +} diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/ShipmentPackingQO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/ShipmentPackingQO.java index f1b98b8d..b3bff3cf 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/ShipmentPackingQO.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/ShipmentPackingQO.java @@ -19,5 +19,5 @@ public class ShipmentPackingQO { * 物料二维码ID列表 */ @NotEmpty - private List materialQRIds; + private List materialInfos; } diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/ShipmentUnPackingMaterialInfoQO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/ShipmentUnPackingMaterialInfoQO.java new file mode 100644 index 00000000..2419fa0c --- /dev/null +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/ShipmentUnPackingMaterialInfoQO.java @@ -0,0 +1,15 @@ +package com.nflg.wms.common.pojo.qo; + +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class ShipmentUnPackingMaterialInfoQO { + @NotNull + private Long materialQRId; + + @NotNull + private BigDecimal actualNum; +} diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/ShipmentUnpackingQO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/ShipmentUnpackingQO.java index 9fe8a0ef..60e1f603 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/ShipmentUnpackingQO.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/ShipmentUnpackingQO.java @@ -15,9 +15,9 @@ public class ShipmentUnpackingQO { private Long packagingCodeId; /** - * 要添加的物料二维码ID列表 + * 要添加的物料信息列表 */ - private List materialQRIdsForAdd; + private List materialInfosForAdd; // /** // * 要删除的物料二维码ID列表 diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/ShipmentMaterialCodeItemVO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/ShipmentMaterialCodeItemVO.java index 7f82121a..ce9454b0 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/ShipmentMaterialCodeItemVO.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/ShipmentMaterialCodeItemVO.java @@ -55,11 +55,6 @@ public class ShipmentMaterialCodeItemVO { */ private String boxNo; - /** - * 最小包装量 - */ - private BigDecimal minPackagingNum; - /** * 状态,0:未装箱;1:已装箱;5:已安装 */ diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/ShipmentMaterialCodeQRVO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/ShipmentMaterialCodeQRVO.java index e3c1ff97..862eb69b 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/ShipmentMaterialCodeQRVO.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/ShipmentMaterialCodeQRVO.java @@ -11,6 +11,8 @@ public class ShipmentMaterialCodeQRVO { private Long id; + private Long itemId; + /** * 序号 */ @@ -90,4 +92,9 @@ public class ShipmentMaterialCodeQRVO { */ private String orderDate; + /** + * 剩余数量 + */ + private BigDecimal leftNum; + } diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsShipmentMaterialCodeItem.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsShipmentMaterialCodeItem.java index 33bc2dba..52e72de4 100644 --- a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsShipmentMaterialCodeItem.java +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsShipmentMaterialCodeItem.java @@ -12,6 +12,7 @@ import lombok.experimental.Accessors; import java.io.Serializable; import java.math.BigDecimal; import java.time.LocalDateTime; +import java.util.Objects; /** *

@@ -79,26 +80,11 @@ public class WmsShipmentMaterialCodeItem implements Serializable { */ private String boxNo; - /** - * 最小包装量 - */ - private BigDecimal minPackagingNum; - /** * 状态,0:未装箱;1:装箱中;2:已装箱; */ private Integer status; - /** - * 打包箱数量 - */ - private Integer packingNum; - - /** - * 剩余打包箱数量 - */ - private Integer packingLeft; - /** * 创建人 */ @@ -123,6 +109,18 @@ public class WmsShipmentMaterialCodeItem implements Serializable { private String key; public String getKey() { - return this.materialNo + "|" + this.productionOrderNumber + "|" + this.boxNo; + return this.materialNo + "|" + this.productionOrderNumber + "|" + this.parentMaterialDescribe; + } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) return false; + WmsShipmentMaterialCodeItem that = (WmsShipmentMaterialCodeItem) o; + return Objects.equals(materialCodeId, that.materialCodeId) && Objects.equals(materialNo, that.materialNo) && Objects.equals(parentMaterialDescribe, that.parentMaterialDescribe) && Objects.equals(productionOrderNumber, that.productionOrderNumber); + } + + @Override + public int hashCode() { + return Objects.hash(materialCodeId, materialNo, parentMaterialDescribe, productionOrderNumber); } } diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/mapper/WmsShipmentMaterialCodeItemMapper.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/mapper/WmsShipmentMaterialCodeItemMapper.java index 9ff1427e..f790cbd7 100644 --- a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/mapper/WmsShipmentMaterialCodeItemMapper.java +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/mapper/WmsShipmentMaterialCodeItemMapper.java @@ -20,8 +20,6 @@ public interface WmsShipmentMaterialCodeItemMapper extends BaseMapper getByCodeId(Long codeId); - void updatePackingNum(Set ids); - List getListByMaterialNos(Set materialNos); List getListByItemIds(List ids); diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsShipmentMaterialCodeItemService.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsShipmentMaterialCodeItemService.java index 602f11d1..fb032e90 100644 --- a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsShipmentMaterialCodeItemService.java +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsShipmentMaterialCodeItemService.java @@ -1,11 +1,13 @@ package com.nflg.wms.repository.service; +import com.baomidou.mybatisplus.extension.service.IService; import com.nflg.wms.common.pojo.vo.MaterialItemPrintVO; import com.nflg.wms.common.pojo.vo.ShipmentMaterialCodeItemVO; import com.nflg.wms.repository.entity.WmsShipmentMaterialCodeItem; -import com.baomidou.mybatisplus.extension.service.IService; +import java.math.BigDecimal; import java.util.List; +import java.util.Map; import java.util.Set; /** @@ -20,9 +22,11 @@ public interface IWmsShipmentMaterialCodeItemService extends IService getByCodeId(Long codeId); - void updatePackingNum(Set ids); - List getListByMaterialNos(Set materialNos); List getListByItemIds(List ids); + + void updateStatusAndBoxNoAndActualNum(List items, Integer status, String boxNo, BigDecimal actualNum, Map id2ActualNumMap); + + List getSameMaterialItems(Long materialCodeId, String materialNo, String parentMaterialDescribe, String productionOrderNumber); } diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsShipmentMaterialCodeItemQrServiceImpl.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsShipmentMaterialCodeItemQrServiceImpl.java index bd15e710..417be08c 100644 --- a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsShipmentMaterialCodeItemQrServiceImpl.java +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsShipmentMaterialCodeItemQrServiceImpl.java @@ -1,13 +1,17 @@ package com.nflg.wms.repository.service.impl; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.nflg.wms.common.pojo.vo.ShipmentMaterialCodeQRVO; +import com.nflg.wms.repository.entity.WmsShipmentMaterialCodeItem; import com.nflg.wms.repository.entity.WmsShipmentMaterialCodeItemQr; import com.nflg.wms.repository.mapper.WmsShipmentMaterialCodeItemQrMapper; import com.nflg.wms.repository.mapper.dto.GetQRCodeByMaterialNoAndDeviceNoAndProductionOrderNumberAndStatusParamsDTO; import com.nflg.wms.repository.service.IWmsShipmentMaterialCodeItemQrService; -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.nflg.wms.repository.service.IWmsShipmentMaterialCodeItemService; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.math.BigDecimal; import java.util.List; import java.util.Set; @@ -22,6 +26,9 @@ import java.util.Set; @Service public class WmsShipmentMaterialCodeItemQrServiceImpl extends ServiceImpl implements IWmsShipmentMaterialCodeItemQrService { + @Autowired + private IWmsShipmentMaterialCodeItemService wmsShipmentMaterialCodeItemService; + @Override public String getQRCodeByMaterialNoAndDeviceNoAndProductionOrderNumberAndStatus(GetQRCodeByMaterialNoAndDeviceNoAndProductionOrderNumberAndStatusParamsDTO params) { return baseMapper.getQRCodeByMaterialNoAndDeviceNoAndProductionOrderNumberAndStatus(params); @@ -29,7 +36,13 @@ public class WmsShipmentMaterialCodeItemQrServiceImpl extends ServiceImpl sameMaterialItems = + wmsShipmentMaterialCodeItemService.getSameMaterialItems(item.getMaterialCodeId(), item.getMaterialNo(), item.getParentMaterialDescribe(), item.getProductionOrderNumber()); + BigDecimal totalActualNum = sameMaterialItems.stream().map(WmsShipmentMaterialCodeItem::getActualNum).reduce(BigDecimal.ZERO, BigDecimal::add); + info.setLeftNum(item.getNum().subtract(totalActualNum)); + return info; } @Override diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsShipmentMaterialCodeItemServiceImpl.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsShipmentMaterialCodeItemServiceImpl.java index 818a8141..51a5dab8 100644 --- a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsShipmentMaterialCodeItemServiceImpl.java +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsShipmentMaterialCodeItemServiceImpl.java @@ -1,14 +1,19 @@ package com.nflg.wms.repository.service.impl; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.nflg.wms.common.pojo.vo.MaterialItemPrintVO; import com.nflg.wms.common.pojo.vo.ShipmentMaterialCodeItemVO; +import com.nflg.wms.common.util.UserUtil; import com.nflg.wms.repository.entity.WmsShipmentMaterialCodeItem; import com.nflg.wms.repository.mapper.WmsShipmentMaterialCodeItemMapper; import com.nflg.wms.repository.service.IWmsShipmentMaterialCodeItemService; -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.math.BigDecimal; +import java.time.LocalDateTime; import java.util.List; +import java.util.Map; import java.util.Set; /** @@ -27,11 +32,6 @@ public class WmsShipmentMaterialCodeItemServiceImpl extends ServiceImpl ids) { - baseMapper.updatePackingNum(ids); - } - @Override public List getListByMaterialNos(Set materialNos) { return baseMapper.getListByMaterialNos(materialNos); @@ -41,4 +41,27 @@ public class WmsShipmentMaterialCodeItemServiceImpl extends ServiceImpl getListByItemIds(List ids) { return baseMapper.getListByItemIds(ids); } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateStatusAndBoxNoAndActualNum(List items, Integer status, String boxNo, BigDecimal actualNum, Map id2ActualNumMap) { + for (WmsShipmentMaterialCodeItem item : items) { + item.setStatus(status); + item.setBoxNo(boxNo); + item.setActualNum(actualNum != null ? actualNum : id2ActualNumMap.get(item.getId())); + item.setUpdateBy(UserUtil.getUserName()); + item.setUpdateTime(LocalDateTime.now()); + } + this.updateBatchById(items); + } + + @Override + public List getSameMaterialItems(Long materialCodeId, String materialNo, String parentMaterialDescribe, String productionOrderNumber) { + return lambdaQuery() + .eq(WmsShipmentMaterialCodeItem::getMaterialCodeId, materialCodeId) + .eq(WmsShipmentMaterialCodeItem::getMaterialNo, materialNo) + .eq(WmsShipmentMaterialCodeItem::getParentMaterialDescribe, parentMaterialDescribe) + .eq(WmsShipmentMaterialCodeItem::getProductionOrderNumber, productionOrderNumber) + .list(); + } } diff --git a/nflg-wms-repository/src/main/resources/mapper/WmsShipmentMaterialCodeItemMapper.xml b/nflg-wms-repository/src/main/resources/mapper/WmsShipmentMaterialCodeItemMapper.xml index 76e4110a..3737f121 100644 --- a/nflg-wms-repository/src/main/resources/mapper/WmsShipmentMaterialCodeItemMapper.xml +++ b/nflg-wms-repository/src/main/resources/mapper/WmsShipmentMaterialCodeItemMapper.xml @@ -6,26 +6,6 @@ select * from wms_shipment_material_code_item where material_code_id = #{codeId} - - WITH updated_data AS ( - SELECT - "id", - packing_num, - (packing_num - (SELECT COUNT(1) FROM wms_shipment_material_code_item_qr WHERE item_id = - wms_shipment_material_code_item."id" AND status = 1)) as new_packing_left - FROM wms_shipment_material_code_item - ) - UPDATE wms_shipment_material_code_item t - SET - packing_left = u.new_packing_left, - status = CASE WHEN u.new_packing_left = 0 THEN 2 WHEN u.new_packing_left=u.packing_num THEN 0 ELSE 1 END - FROM updated_data u - WHERE t."id" = u."id" and t."id" IN - - #{id} - - - SELECT ROW_NUMBER() OVER () AS "index",it."id",qr.no,cit.material_no,cit.material_describe,cit.num - ,qr.num as actualNum,cit.unit,d.device_no,d.customer_name + ,cit.actual_num as actualNum,cit.unit,d.device_no,d.customer_name FROM wms_shipment_packaging_code_item it INNER JOIN wms_shipment_material_code_item_qr qr ON it.material_code_item_qr_id=qr."id" INNER JOIN wms_shipment_material_code_item cit ON qr.item_id=cit."id" diff --git a/nflg-wms-shipment/src/main/java/com/nflg/wms/shipment/controller/MaterialCodeController.java b/nflg-wms-shipment/src/main/java/com/nflg/wms/shipment/controller/MaterialCodeController.java index d4e71ff3..3fad717d 100644 --- a/nflg-wms-shipment/src/main/java/com/nflg/wms/shipment/controller/MaterialCodeController.java +++ b/nflg-wms-shipment/src/main/java/com/nflg/wms/shipment/controller/MaterialCodeController.java @@ -16,7 +16,6 @@ import com.nflg.wms.common.pojo.vo.MaterialPdfVO; import com.nflg.wms.common.pojo.vo.ShipmentMaterialCodeItemVO; import com.nflg.wms.common.pojo.vo.ShipmentMaterialCodeQRVO; import com.nflg.wms.common.util.EecExcelUtil; -import com.nflg.wms.common.util.NumberUtil; import com.nflg.wms.common.util.UserUtil; import com.nflg.wms.common.util.VUtil; import com.nflg.wms.repository.entity.*; @@ -187,7 +186,7 @@ public class MaterialCodeController extends BaseController { response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + URLEncoder.encode("物料清单导入模板.xlsx", StandardCharsets.UTF_8)); new Workbook() - .addSheet(new TemplateSheet(new ClassPathResource("template/物料码打印导出模板.xlsx").getInputStream()) + .addSheet(new TemplateSheet(new ClassPathResource("template/物料码打印导入模板.xlsx").getInputStream()) ).writeTo(response.getOutputStream()); } @@ -252,34 +251,31 @@ public class MaterialCodeController extends BaseController { item.setMaterialNo(row.getString(1)); item.setMaterialDescribe(row.getString(2)); item.setNum(row.getDecimal(3)); - item.setActualNum(row.getDecimal(4)); - item.setMinPackagingNum(item.getActualNum()); - item.setUnit(row.getString(5)); - item.setProjectType(row.getString(6)); - item.setParentMaterialDescribe(row.getString(7)); - item.setProductionOrderNumber(row.getString(8)); - item.setBoxNo(row.getString(9)); + item.setActualNum(BigDecimal.ZERO); + item.setUnit(row.getString(4)); + item.setProjectType(row.getString(5)); + item.setParentMaterialDescribe(row.getString(6)); + item.setProductionOrderNumber(row.getString(7)); item.setCreateBy(UserUtil.getUserName()); item.setCreateTime(LocalDateTime.now()); - item.setPackingNum(NumberUtil.calculateLabelNum(item.getNum(), item.getMinPackagingNum())); - item.setPackingLeft(item.getPackingNum()); + items.add(item); qrs.add(new WmsShipmentMaterialCodeItemQr() .setItemId(item.getId()) .setNo(KeyUtil.nextFCode()) - .setNum(item.getMinPackagingNum()) + .setNum(item.getNum()) .setCreateBy(UserUtil.getUserName()) .setCreateTime(LocalDateTime.now()) ); } }); -// Set repeats = items.stream().collect(Collectors.groupingBy(WmsShipmentMaterialCodeItem::getKey)) -// .values() -// .stream().filter(list -> list.size() > 1) -// .map(list -> list.get(0).getMaterialNo()) -// .collect(Collectors.toSet()); -// VUtil.trueThrowBusinessError(CollectionUtil.isNotEmpty(repeats)) -// .throwMessage("以下物料重复:" + StrUtil.join(",", repeats)); + Set repeats = items.stream().collect(Collectors.groupingBy(WmsShipmentMaterialCodeItem::getKey)) + .values() + .stream().filter(list -> list.size() > 1) + .map(list -> list.get(0).getMaterialNo()) + .collect(Collectors.toSet()); + VUtil.trueThrowBusinessError(CollectionUtil.isNotEmpty(repeats)) + .throwMessage("以下物料重复:" + StrUtil.join(",", repeats)); materialCodeService.save(materialCode); materialCodeItemService.saveBatch(items); materialCodeItemQrService.saveBatch(qrs); @@ -293,38 +289,21 @@ public class MaterialCodeController extends BaseController { @Transactional @PostMapping("item/add") public ApiResult addItem(@Valid @RequestBody MaterialCodeItemAddQO qo) { - VUtil.trueThrowBusinessError(materialCodeItemService.lambdaQuery() - .eq(WmsShipmentMaterialCodeItem::getMaterialCodeId, qo.getMaterialCodeId()) - .eq(WmsShipmentMaterialCodeItem::getProductionOrderNumber, qo.getProductionOrderNumber()) - .eq(WmsShipmentMaterialCodeItem::getMaterialNo, qo.getMaterialNo()) - .exists()).throwMessage("物料已存在"); + List sameMaterialItems = + materialCodeItemService.getSameMaterialItems(qo.getMaterialCodeId(), qo.getMaterialNo(), qo.getParentMaterialDescribe(), qo.getProductionOrderNumber()); + VUtil.trueThrowBusinessError(CollectionUtil.isNotEmpty(sameMaterialItems)).throwMessage("物料已存在"); WmsShipmentMaterialCodeItem item = Convert.convert(WmsShipmentMaterialCodeItem.class, qo); - if (Objects.isNull(qo.getMinPackagingNum())) { - item.setMinPackagingNum(qo.getNum()); - } else { - VUtil.trueThrowBusinessError(qo.getMinPackagingNum().compareTo(qo.getNum()) > 0) - .throwMessage("最小包装数量不能大于数量"); - item.setMinPackagingNum(qo.getMinPackagingNum()); - } item.setId(IdUtil.getSnowflakeNextId()); item.setCreateBy(UserUtil.getUserName()); item.setCreateTime(LocalDateTime.now()); -// BigDecimal result = item.getNum().divide(item.getMinPackagingNum(), 3, RoundingMode.HALF_UP); -// BigDecimal decimalValue = result.remainder(BigDecimal.ONE); -// item.setPackingNum(decimalValue.compareTo(BigDecimal.ZERO) > 0 ? result.intValue() + 1 : result.intValue()); - item.setPackingNum(NumberUtil.calculateLabelNum(item.getNum(), item.getMinPackagingNum())); - item.setPackingLeft(item.getPackingNum()); -// int count = decimalValue.compareTo(BigDecimal.ZERO) > 0 ? result.intValue() + 1 : result.intValue(); - for (int i = 1; i <= item.getPackingNum(); i++) { - materialCodeItemQrService.save(new WmsShipmentMaterialCodeItemQr() - .setItemId(item.getId()) - .setNo(KeyUtil.nextFCode()) -// .setNum(i == count && decimalValue.compareTo(BigDecimal.ZERO) > 0 ? decimalValue : item.getMinPackagingNum()) - .setNum(NumberUtil.getPackageNum(item.getNum(), item.getMinPackagingNum(), item.getPackingNum(), i)) - .setCreateBy(UserUtil.getUserName()) - .setCreateTime(LocalDateTime.now()) - ); - } + item.setActualNum(BigDecimal.ZERO); + materialCodeItemQrService.save(new WmsShipmentMaterialCodeItemQr() + .setItemId(item.getId()) + .setNo(KeyUtil.nextFCode()) + .setNum(item.getNum()) + .setCreateBy(UserUtil.getUserName()) + .setCreateTime(LocalDateTime.now()) + ); materialCodeItemService.save(item); materialCodeService.lambdaUpdate() .set(WmsShipmentMaterialCode::getStatus, 1) @@ -342,37 +321,26 @@ public class MaterialCodeController extends BaseController { public ApiResult updateItem(@Valid @RequestBody MaterialCodeItemUpdateQO qo) { WmsShipmentMaterialCodeItem item = materialCodeItemService.getById(qo.getId()); VUtil.trueThrowBusinessError(Objects.isNull(item)).throwMessage("清单明细不存在"); - if (Objects.isNull(qo.getMinPackagingNum())) { - qo.setMinPackagingNum(qo.getNum()); - } else { - VUtil.trueThrowBusinessError(qo.getMinPackagingNum().compareTo(qo.getNum()) > 0) - .throwMessage("最小包装数量不能大于数量"); - qo.setMinPackagingNum(qo.getNum()); - } VUtil.trueThrowBusinessError(item.getStatus() > 0) .throwMessage("已装箱,不能修改"); + + + List sameMaterialItems = + materialCodeItemService.getSameMaterialItems(item.getMaterialCodeId(), item.getMaterialNo(), item.getParentMaterialDescribe(), item.getProductionOrderNumber()); + VUtil.trueThrowBusinessError(sameMaterialItems.size() > 1) + .throwMessage("存在多行物料编码、生产订单号、上级物料描述三个字段相同的情况,不允许修改"); + item = Convert.convert(WmsShipmentMaterialCodeItem.class, qo); + item.setUpdateBy(UserUtil.getUserName()); item.setUpdateTime(LocalDateTime.now()); materialCodeItemService.updateById(item); materialCodeItemQrService.lambdaUpdate() + .set(WmsShipmentMaterialCodeItemQr::getNum, item.getNum()) + .set(WmsShipmentMaterialCodeItemQr::getUpdateBy, UserUtil.getUserName()) + .set(WmsShipmentMaterialCodeItemQr::getUpdateTime, LocalDateTime.now()) .eq(WmsShipmentMaterialCodeItemQr::getItemId, item.getId()) - .remove(); -// BigDecimal result = item.getNum().divide(item.getMinPackagingNum(), 3, RoundingMode.HALF_UP); -// BigDecimal decimalValue = result.remainder(BigDecimal.ONE); -// item.setPackingNum(decimalValue.compareTo(BigDecimal.ZERO) > 0 ? result.intValue() + 1 : result.intValue()); - item.setPackingNum(NumberUtil.calculateLabelNum(item.getNum(), item.getMinPackagingNum())); - item.setPackingLeft(item.getPackingNum()); -// int count = decimalValue.compareTo(BigDecimal.ZERO) > 0 ? result.intValue() + 1 : result.intValue(); - for (int i = 1; i <= item.getPackingNum(); i++) { - materialCodeItemQrService.save(new WmsShipmentMaterialCodeItemQr() - .setItemId(item.getId()) - .setNo(KeyUtil.nextFCode()) - .setNum(NumberUtil.getPackageNum(item.getNum(), item.getMinPackagingNum(), item.getPackingNum(), i)) - .setCreateBy(UserUtil.getUserName()) - .setCreateTime(LocalDateTime.now()) - ); - } + .update(); return ApiResult.success(); } @@ -390,6 +358,9 @@ public class MaterialCodeController extends BaseController { .stream() .map(WmsShipmentMaterialCodeItem::getId) .collect(Collectors.toSet()); + + VUtil.trueThrowBusinessError(deleteIds.size() < ids.size()).throwMessage("已装箱的不可删除"); + if (CollectionUtil.isNotEmpty(deleteIds)) { materialCodeItemService.lambdaUpdate() .in(WmsShipmentMaterialCodeItem::getId, deleteIds) @@ -412,8 +383,7 @@ public class MaterialCodeController extends BaseController { public ApiResult importItemFromExcel(@RequestParam Long materialCodeId, @RequestParam Boolean cover, @RequestParam("file") MultipartFile file) throws IOException { WmsShipmentMaterialCode materialCode = materialCodeService.getById(materialCodeId); VUtil.trueThrowBusinessError(Objects.isNull(materialCode)).throwMessage("清单不存在"); - List dbItems = materialCodeItemService.lambdaQuery() - .select(WmsShipmentMaterialCodeItem::getId, WmsShipmentMaterialCodeItem::getMaterialNo, WmsShipmentMaterialCodeItem::getStatus) + List allDbItems = materialCodeItemService.lambdaQuery() .eq(WmsShipmentMaterialCodeItem::getMaterialCodeId, materialCodeId) .list(); List qrsForAdd = new ArrayList<>(); @@ -422,6 +392,7 @@ public class MaterialCodeController extends BaseController { List itemsForAdd = new ArrayList<>(); List itemsForUpdate = new ArrayList<>(); List repeats = new ArrayList<>(); + List dbExists = new ArrayList<>(); reader.sheet(0).rows().forEach(row -> { log.debug("第{}行:{}", row.getRowNum(), row); if (row.getRowNum() > 4 && StrUtil.isNotBlank(row.getString(1))) { @@ -431,74 +402,77 @@ public class MaterialCodeController extends BaseController { item.setMaterialNo(row.getString(1)); item.setMaterialDescribe(row.getString(2)); item.setNum(row.getDecimal(3)); - item.setActualNum(row.getDecimal(4)); - item.setMinPackagingNum(item.getActualNum()); - item.setUnit(row.getString(5)); - item.setProjectType(row.getString(6)); - item.setParentMaterialDescribe(row.getString(7)); - item.setProductionOrderNumber(row.getString(8)); - item.setBoxNo(row.getString(9)); - item.setPackingNum(1); - item.setPackingLeft(1); + item.setActualNum(BigDecimal.ZERO); + item.setUnit(row.getString(4)); + item.setProjectType(row.getString(5)); + item.setParentMaterialDescribe(row.getString(6)); + item.setProductionOrderNumber(row.getString(7)); if (itemsForAdd.stream().anyMatch(it -> it.getKey().equals(item.getKey()))) { repeats.add(item.getMaterialNo()); } else { + List dbItems = allDbItems.stream() + .filter(it -> it.getKey().equals(item.getKey())) + .collect(Collectors.toList()); if (!cover) { - item.setCreateBy(UserUtil.getUserName()); - item.setCreateTime(LocalDateTime.now()); - itemsForAdd.add(item); - qrsForAdd.add(new WmsShipmentMaterialCodeItemQr() - .setItemId(item.getId()) - .setNo(KeyUtil.nextFCode()) - .setNum(item.getMinPackagingNum()) - .setCreateBy(UserUtil.getUserName()) - .setCreateTime(LocalDateTime.now()) - ); - } else { - WmsShipmentMaterialCodeItem dbItem = dbItems.stream() - .filter(it -> it.getKey().equals(item.getKey())) - .findFirst() - .orElse(null); - if (Objects.isNull(dbItem)) { + if (CollectionUtil.isNotEmpty(dbItems)) { + dbExists.add(dbItems.get(0).getMaterialNo()); + } else { item.setCreateBy(UserUtil.getUserName()); item.setCreateTime(LocalDateTime.now()); itemsForAdd.add(item); qrsForAdd.add(new WmsShipmentMaterialCodeItemQr() .setItemId(item.getId()) .setNo(KeyUtil.nextFCode()) - .setNum(item.getMinPackagingNum()) + .setNum(item.getNum()) .setCreateBy(UserUtil.getUserName()) .setCreateTime(LocalDateTime.now()) ); - } else if (dbItem.getStatus() == 0) { - item.setId(dbItem.getId()); - item.setUpdateBy(UserUtil.getUserName()); - item.setUpdateTime(LocalDateTime.now()); - itemsForUpdate.add(item); - List iqrs = materialCodeItemQrService.lambdaQuery() - .eq(WmsShipmentMaterialCodeItemQr::getItemId, item.getId()) - .list(); - if (iqrs.size() > 1) { - materialCodeItemQrService.lambdaUpdate() + } + } else { + if (CollectionUtil.isEmpty(dbItems)) { + item.setCreateBy(UserUtil.getUserName()); + item.setCreateTime(LocalDateTime.now()); + itemsForAdd.add(item); + qrsForAdd.add(new WmsShipmentMaterialCodeItemQr() + .setItemId(item.getId()) + .setNo(KeyUtil.nextFCode()) + .setNum(item.getNum()) + .setCreateBy(UserUtil.getUserName()) + .setCreateTime(LocalDateTime.now()) + ); + } else { + if (dbItems.size() > 1) { + dbExists.add(dbItems.get(0).getMaterialNo()); + } else if (dbItems.get(0).getStatus() == 0) { + item.setId(dbItems.get(0).getId()); + item.setUpdateBy(UserUtil.getUserName()); + item.setUpdateTime(LocalDateTime.now()); + itemsForUpdate.add(item); + List iqrs = materialCodeItemQrService.lambdaQuery() .eq(WmsShipmentMaterialCodeItemQr::getItemId, item.getId()) - .remove(); - } - if (iqrs.size() == 1) { - qrsForUpdate.add( - new WmsShipmentMaterialCodeItemQr() - .setId(iqrs.get(0).getId()) - .setNum(item.getMinPackagingNum()) - .setCreateBy(UserUtil.getUserName()) - .setCreateTime(LocalDateTime.now()) - ); - } else { - qrsForAdd.add(new WmsShipmentMaterialCodeItemQr() - .setItemId(item.getId()) - .setNo(KeyUtil.nextFCode()) - .setNum(item.getMinPackagingNum()) - .setCreateBy(UserUtil.getUserName()) - .setCreateTime(LocalDateTime.now()) - ); + .list(); + if (iqrs.size() > 1) { + materialCodeItemQrService.lambdaUpdate() + .eq(WmsShipmentMaterialCodeItemQr::getItemId, item.getId()) + .remove(); + } + if (iqrs.size() == 1) { + qrsForUpdate.add( + new WmsShipmentMaterialCodeItemQr() + .setId(iqrs.get(0).getId()) + .setNum(item.getNum()) + .setCreateBy(UserUtil.getUserName()) + .setCreateTime(LocalDateTime.now()) + ); + } else { + qrsForAdd.add(new WmsShipmentMaterialCodeItemQr() + .setItemId(item.getId()) + .setNo(KeyUtil.nextFCode()) + .setNum(item.getNum()) + .setCreateBy(UserUtil.getUserName()) + .setCreateTime(LocalDateTime.now()) + ); + } } } } @@ -507,6 +481,10 @@ public class MaterialCodeController extends BaseController { }); VUtil.trueThrowBusinessError(CollectionUtil.isNotEmpty(repeats)) .throwMessage("以下物料重复:" + StrUtil.join(",", repeats)); + + VUtil.trueThrowBusinessError(CollectionUtil.isNotEmpty(dbExists)) + .throwMessage(!cover ? "以下物料已存在:" + StrUtil.join(",", dbExists) + : "存在多行物料编码、生产订单号、上级物料描述三个字段相同的情况,不允许修改: " + dbExists); if (CollectionUtil.isNotEmpty(itemsForAdd)) { materialCodeItemService.saveBatch(itemsForAdd); materialCodeService.lambdaUpdate() diff --git a/nflg-wms-shipment/src/main/java/com/nflg/wms/shipment/controller/PackagingCodeController.java b/nflg-wms-shipment/src/main/java/com/nflg/wms/shipment/controller/PackagingCodeController.java index 298b1dce..e01d6fdb 100644 --- a/nflg-wms-shipment/src/main/java/com/nflg/wms/shipment/controller/PackagingCodeController.java +++ b/nflg-wms-shipment/src/main/java/com/nflg/wms/shipment/controller/PackagingCodeController.java @@ -1,45 +1,40 @@ package com.nflg.wms.shipment.controller; +import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.convert.Convert; -import cn.hutool.core.util.RandomUtil; +import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.google.common.collect.Lists; import com.nflg.wms.common.pojo.ApiResult; import com.nflg.wms.common.pojo.PageData; -import com.nflg.wms.common.pojo.dto.DeliverNormalOrderItemDTO; import com.nflg.wms.common.pojo.qo.*; import com.nflg.wms.common.pojo.vo.ShipmentMaterialCodeQRVO; import com.nflg.wms.common.pojo.vo.ShipmentPackagingCodeVO; +import com.nflg.wms.common.util.NumberUtil; import com.nflg.wms.common.util.UserUtil; import com.nflg.wms.common.util.VUtil; -import com.nflg.wms.repository.entity.DictionaryItem; -import com.nflg.wms.repository.entity.WmsShipmentMaterialCodeItemQr; -import com.nflg.wms.repository.entity.WmsShipmentPackagingCode; -import com.nflg.wms.repository.entity.WmsShipmentPackagingCodeItem; +import com.nflg.wms.repository.entity.*; import com.nflg.wms.repository.service.*; import com.nflg.wms.shipment.service.BasdeSerialNumberControllerService; -import com.nflg.wms.shipment.util.HtmlToImageUtil; -import com.nflg.wms.shipment.util.KeyUtil; -import com.nflg.wms.shipment.util.PdfGeneratorUtil; -import com.nflg.wms.shipment.util.QRCodeUtil; -import com.nflg.wms.shipment.util.ThymeleafUtil; +import com.nflg.wms.shipment.util.*; import com.nflg.wms.starter.BaseController; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.Valid; import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; +import org.springframework.core.io.ClassPathResource; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.core.io.ClassPathResource; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import java.io.ByteArrayOutputStream; +import java.math.BigDecimal; import java.net.URL; import java.time.LocalDateTime; import java.util.*; @@ -186,10 +181,25 @@ public class PackagingCodeController extends BaseController { WmsShipmentPackagingCode info = packagingCodeService.getById(qo.getPackagingCodeId()); VUtil.trueThrowBusinessError(Objects.isNull(info)).throwMessage("包装箱不存在"); VUtil.trueThrowBusinessError(info.getStatus() == 2).throwMessage("该箱已发车"); - List items = materialCodeItemQrService.listByIds(qo.getMaterialQRIds()); - VUtil.trueThrowBusinessError(items.size() != qo.getMaterialQRIds().size()).throwMessage("数据有变动,请重新扫码"); - items.removeIf(item -> item.getStatus() == 1); - if (CollectionUtil.isNotEmpty(items)) { + List materialQRIds = qo.getMaterialInfos().stream().map(ShipmentPackingMaterialInfoQO::getMaterialQRId).collect(Collectors.toList()); + List itemQrs = materialCodeItemQrService.listByIds(materialQRIds); + VUtil.trueThrowBusinessError(itemQrs.size() != materialQRIds.size()).throwMessage("数据有变动,请重新扫码"); + itemQrs.removeIf(item -> item.getStatus() == 1); + Set itemIdSet = itemQrs.stream().map(WmsShipmentMaterialCodeItemQr::getItemId).collect(Collectors.toSet()); + List items = materialCodeItemService.listByIds(itemIdSet); + + Map qrId2ItemIdMap = itemQrs.stream().collect(Collectors.toMap(WmsShipmentMaterialCodeItemQr::getId, WmsShipmentMaterialCodeItemQr::getItemId, (oldValue, newValue) -> newValue)); + Map itemId2ActualNumMap = new HashMap<>(); + for (ShipmentPackingMaterialInfoQO materialInfoQO : qo.getMaterialInfos()) { + Long qrId = materialInfoQO.getMaterialQRId(); + Long itemId = qrId2ItemIdMap.get(qrId); + itemId2ActualNumMap.put(itemId, materialInfoQO.getActualNum()); + } + + // 校验实际数量 + Map materialCodeItem2NewActualNumMap = checkActualNum(itemId2ActualNumMap, items); + + if (CollectionUtil.isNotEmpty(itemQrs)) { if (info.getStatus() == 0) { packagingCodeService.lambdaUpdate() .set(WmsShipmentPackagingCode::getStatus, 1) @@ -199,25 +209,81 @@ public class PackagingCodeController extends BaseController { .eq(WmsShipmentPackagingCode::getStatus, 0) .update(); } - items.forEach(item -> { + itemQrs.forEach(item -> { item.setStatus(1); item.setUpdateBy(UserUtil.getUserName()); item.setUpdateTime(LocalDateTime.now()); }); packagingCodeItemService.saveBatch( - items.stream().map(it -> new WmsShipmentPackagingCodeItem() + itemQrs.stream().map(it -> new WmsShipmentPackagingCodeItem() .setPackagingCodeId(qo.getPackagingCodeId()) .setMaterialCodeItemQrId(it.getId()) .setCreateBy(UserUtil.getUserName()) .setCreateTime(LocalDateTime.now()) ).toList() ); - materialCodeItemQrService.updateBatchById(items); - materialCodeItemService.updatePackingNum(items.stream().map(WmsShipmentMaterialCodeItemQr::getItemId).collect(Collectors.toSet())); + materialCodeItemQrService.updateBatchById(itemQrs); + materialCodeItemService.updateStatusAndBoxNoAndActualNum(items, 2, info.getNo(), null, itemId2ActualNumMap); + + addMaterialCodeItemIfNumBigThenActualNum(materialCodeItem2NewActualNumMap); } return ApiResult.success(); } + private void addMaterialCodeItemIfNumBigThenActualNum(Map materialCodeItem2NewActualNumMap) { + if (CollectionUtil.isNotEmpty(materialCodeItem2NewActualNumMap)) { + for (WmsShipmentMaterialCodeItem item : materialCodeItem2NewActualNumMap.keySet()) { + if (item.getNum().compareTo(materialCodeItem2NewActualNumMap.get(item)) > 0) { + + List sameMaterialItems = + materialCodeItemService.getSameMaterialItems(item.getMaterialCodeId(), item.getMaterialNo(), item.getParentMaterialDescribe(), item.getProductionOrderNumber()); + + for (WmsShipmentMaterialCodeItem m : sameMaterialItems) { + if (!m.getId().equals(item.getId()) && m.getStatus() == 0) { + return; + } + } + + WmsShipmentMaterialCodeItem newMaterialCodeItem = new WmsShipmentMaterialCodeItem(); + BeanUtil.copyProperties(item, newMaterialCodeItem); + + newMaterialCodeItem.setId(IdUtil.getSnowflakeNextId()); + newMaterialCodeItem.setActualNum(BigDecimal.ZERO); + newMaterialCodeItem.setBoxNo(null); + newMaterialCodeItem.setStatus(0); + newMaterialCodeItem.setCreateBy(UserUtil.getUserName()); + newMaterialCodeItem.setCreateTime(LocalDateTime.now()); + + materialCodeItemQrService.save(new WmsShipmentMaterialCodeItemQr() + .setItemId(newMaterialCodeItem.getId()) + .setNo(KeyUtil.next()) + .setNum(newMaterialCodeItem.getNum()) + .setCreateBy(UserUtil.getUserName()) + .setCreateTime(LocalDateTime.now()) + ); + materialCodeItemService.save(newMaterialCodeItem); + } + } + } + } + + private Map checkActualNum(Map itemId2ActualNumMap, List items) { + Map materialCodeItem2NewActualNumMap = new HashMap<>(); + for (WmsShipmentMaterialCodeItem item : items) { + + List sameMaterialItems = + materialCodeItemService.getSameMaterialItems(item.getMaterialCodeId(), item.getMaterialNo(), item.getParentMaterialDescribe(), item.getProductionOrderNumber()); + BigDecimal totalActualNum = sameMaterialItems.stream().map(WmsShipmentMaterialCodeItem::getActualNum).reduce(BigDecimal.ZERO, BigDecimal::add); + BigDecimal actualNum = itemId2ActualNumMap.get(item.getId()); + BigDecimal newActualNum = totalActualNum.add(actualNum); + if (item.getNum().compareTo(newActualNum) <= 0) { + VUtil.trueThrowBusinessError(true).throwMessage(String.format("物料%s数量不足,剩余数量:%s", item.getMaterialNo(), NumberUtil.format(item.getNum().subtract(totalActualNum)))); + } + materialCodeItem2NewActualNumMap.put(item, newActualNum); + } + return materialCodeItem2NewActualNumMap; + } + /** * 装箱打包(PC使用) */ @@ -229,12 +295,12 @@ public class PackagingCodeController extends BaseController { .filter(Objects::nonNull) .map(ShipmentMaterialCodeQRVO::getId) .toList(); - List items = materialCodeItemQrService.lambdaQuery() + List itemQrs = materialCodeItemQrService.lambdaQuery() .in(WmsShipmentMaterialCodeItemQr::getId, ids) .list(); - VUtil.trueThrowBusinessError(items.size() != ids.size()).throwMessage("数据有变动,请重新扫码"); - items.removeIf(item -> item.getStatus() == 1); - if (CollectionUtil.isEmpty(items)) { + VUtil.trueThrowBusinessError(itemQrs.size() != ids.size()).throwMessage("数据有变动,请重新扫码"); + itemQrs.removeIf(item -> item.getStatus() == 1); + if (CollectionUtil.isEmpty(itemQrs)) { return ApiResult.success(); } WmsShipmentPackagingCode info = packagingCodeService.getById(shipmentPCPackingQO.getPackagingCodeId()); @@ -249,24 +315,29 @@ public class PackagingCodeController extends BaseController { .eq(WmsShipmentPackagingCode::getStatus, 0) .update(); } - items.forEach(item -> { + itemQrs.forEach(item -> { item.setStatus(1); item.setUpdateBy(UserUtil.getUserName()); item.setUpdateTime(LocalDateTime.now()); }); packagingCodeItemService.saveBatch( - items.stream().map(it -> new WmsShipmentPackagingCodeItem() + itemQrs.stream().map(it -> new WmsShipmentPackagingCodeItem() .setPackagingCodeId(shipmentPCPackingQO.getPackagingCodeId()) .setMaterialCodeItemQrId(it.getId()) .setCreateBy(UserUtil.getUserName()) .setCreateTime(LocalDateTime.now()) ).toList() ); - materialCodeItemQrService.updateBatchById(items); - materialCodeItemService.updatePackingNum(items.stream() - .map(WmsShipmentMaterialCodeItemQr::getItemId) - .collect(Collectors.toSet()) - ); + materialCodeItemQrService.updateBatchById(itemQrs); + + Set itemIdSet = itemQrs.stream().map(WmsShipmentMaterialCodeItemQr::getItemId).collect(Collectors.toSet()); + List items = materialCodeItemService.listByIds(itemIdSet); + + Map itemId2ActualNumMap = items.stream() + .collect(Collectors.toMap(WmsShipmentMaterialCodeItem::getId, WmsShipmentMaterialCodeItem::getNum)); + materialCodeItemService.updateStatusAndBoxNoAndActualNum(items, 2, info.getNo(),null, itemId2ActualNumMap); + + return ApiResult.success(); } @@ -306,7 +377,9 @@ public class PackagingCodeController extends BaseController { .eq(WmsShipmentMaterialCodeItemQr::getStatus, 1) .in(WmsShipmentMaterialCodeItemQr::getId, item.getMaterialCodeItemQrId()) .update(); - materialCodeItemService.updatePackingNum(Collections.singleton(qr.getItemId())); + + WmsShipmentMaterialCodeItem materialCodeItem = materialCodeItemService.getById(qr.getItemId()); + materialCodeItemService.updateStatusAndBoxNoAndActualNum(Lists.newArrayList(materialCodeItem), 0, "", BigDecimal.ZERO, null); packagingCodeService.updateStatus(item.getPackagingCodeId()); } } @@ -314,7 +387,7 @@ public class PackagingCodeController extends BaseController { } /** - * 拆箱&添加物料(PDA使用) + * 拆箱下,添加物料(PDA使用) */ @Transactional @PostMapping("unpack") @@ -322,11 +395,28 @@ public class PackagingCodeController extends BaseController { WmsShipmentPackagingCode info = packagingCodeService.getById(qo.getPackagingCodeId()); VUtil.trueThrowBusinessError(Objects.isNull(info)).throwMessage("包装箱不存在"); VUtil.trueThrowBusinessError(info.getStatus() >= 2).throwMessage("该箱已装车"); - if (CollectionUtil.isNotEmpty(qo.getMaterialQRIdsForAdd())) { + + List materialQRIds = qo.getMaterialInfosForAdd().stream().map(ShipmentUnPackingMaterialInfoQO::getMaterialQRId).collect(Collectors.toList()); + + if (CollectionUtil.isNotEmpty(materialQRIds)) { List qrs = materialCodeItemQrService.lambdaQuery() .eq(WmsShipmentMaterialCodeItemQr::getStatus, 0) - .in(WmsShipmentMaterialCodeItemQr::getId, qo.getMaterialQRIdsForAdd()) + .in(WmsShipmentMaterialCodeItemQr::getId, materialQRIds) .list(); + + Set itemIdSet = qrs.stream().map(WmsShipmentMaterialCodeItemQr::getItemId).collect(Collectors.toSet()); + List items = materialCodeItemService.listByIds(itemIdSet); + + Map qrId2ItemIdMap = qrs.stream().collect(Collectors.toMap(WmsShipmentMaterialCodeItemQr::getId, WmsShipmentMaterialCodeItemQr::getItemId, (oldValue, newValue) -> newValue)); + Map itemId2ActualNumMap = new HashMap<>(); + for (ShipmentUnPackingMaterialInfoQO materialInfoQO : qo.getMaterialInfosForAdd()) { + Long qrId = materialInfoQO.getMaterialQRId(); + Long itemId = qrId2ItemIdMap.get(qrId); + itemId2ActualNumMap.put(itemId, materialInfoQO.getActualNum()); + } + // 校验实际数量 + Map materialCodeItem2NewActualNumMap = checkActualNum(itemId2ActualNumMap, items); + if (CollectionUtil.isNotEmpty(qrs)) { if (info.getStatus() == 0) { packagingCodeService.lambdaUpdate() @@ -351,35 +441,11 @@ public class PackagingCodeController extends BaseController { ).toList() ); materialCodeItemQrService.updateBatchById(qrs); - materialCodeItemService.updatePackingNum(qrs.stream().map(WmsShipmentMaterialCodeItemQr::getItemId).collect(Collectors.toSet())); + + materialCodeItemService.updateStatusAndBoxNoAndActualNum(items, 2, info.getNo(), null, itemId2ActualNumMap); + addMaterialCodeItemIfNumBigThenActualNum(materialCodeItem2NewActualNumMap); } } -// if (CollectionUtil.isNotEmpty(qo.getMaterialQRIdsForDel())) { -// List items = packagingCodeItemService.lambdaQuery() -// .eq(WmsShipmentPackagingCodeItem::getPackagingCodeId, qo.getPackagingCodeId()) -// .in(WmsShipmentPackagingCodeItem::getId, qo.getMaterialQRIdsForDel()) -// .list(); -// if (CollectionUtil.isNotEmpty(items)) { -// packagingCodeItemService.lambdaUpdate() -// .eq(WmsShipmentPackagingCodeItem::getPackagingCodeId, qo.getPackagingCodeId()) -// .in(WmsShipmentPackagingCodeItem::getId, qo.getMaterialQRIdsForDel()) -// .remove(); -// List qrs = materialCodeItemQrService.lambdaQuery() -// .eq(WmsShipmentMaterialCodeItemQr::getStatus, 1) -// .in(WmsShipmentMaterialCodeItemQr::getId, items.stream().map(WmsShipmentPackagingCodeItem::getMaterialCodeItemQrId).toList()) -// .list(); -// if (CollectionUtil.isNotEmpty(qrs)) { -// materialCodeItemQrService.lambdaUpdate() -// .set(WmsShipmentMaterialCodeItemQr::getStatus, 0) -// .set(WmsShipmentMaterialCodeItemQr::getUpdateBy, UserUtil.getUserName()) -// .set(WmsShipmentMaterialCodeItemQr::getUpdateTime, LocalDateTime.now()) -// .eq(WmsShipmentMaterialCodeItemQr::getStatus, 1) -// .in(WmsShipmentMaterialCodeItemQr::getId, items.stream().map(WmsShipmentPackagingCodeItem::getMaterialCodeItemQrId).toList()) -// .update(); -// materialCodeItemService.updatePackingNum(qrs.stream().map(WmsShipmentMaterialCodeItemQr::getItemId).collect(Collectors.toSet())); -// } -// } -// } packagingCodeService.updateStatus(qo.getPackagingCodeId()); return ApiResult.success(); } diff --git a/nflg-wms-shipment/src/main/java/com/nflg/wms/shipment/pojo/vo/MaterialCodeItemVO.java b/nflg-wms-shipment/src/main/java/com/nflg/wms/shipment/pojo/vo/MaterialCodeItemVO.java index ba20f7b9..62637598 100644 --- a/nflg-wms-shipment/src/main/java/com/nflg/wms/shipment/pojo/vo/MaterialCodeItemVO.java +++ b/nflg-wms-shipment/src/main/java/com/nflg/wms/shipment/pojo/vo/MaterialCodeItemVO.java @@ -59,26 +59,11 @@ public class MaterialCodeItemVO { */ private String boxNo; - /** - * 最小包装量 - */ - private BigDecimal minPackagingNum; - /** * 状态,0:未装箱;1:装箱中;2:已装箱; */ private Integer status; - /** - * 打包箱数量 - */ - private Integer packingNum; - - /** - * 剩余打包箱数量 - */ - private Integer packingLeft; - /** * 创建人 */ diff --git a/nflg-wms-shipment/src/main/resources/template/物料码打印导入模板.xlsx b/nflg-wms-shipment/src/main/resources/template/物料码打印导入模板.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..2f07d2596cb9e6a2fdb48004b0b85f5bd5cb29ab GIT binary patch literal 12518 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%0D(^G%9C^B4|=BCoT|Fcs8T%(-ZvGs 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