From b60636866953301c7f7c7b8538b8ed57b21a49d6 Mon Sep 17 00:00:00 2001 From: zhangke Date: Sat, 11 Oct 2025 22:57:41 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E9=9B=B6=E9=83=A8=E4=BB=B6=E8=A3=85?= =?UTF-8?q?=E8=BD=A6=E5=8D=95=E5=92=8C=E9=9B=B6=E9=83=A8=E4=BB=B6=E5=87=BA?= =?UTF-8?q?=E5=BA=93=E5=8D=95=E6=B7=BB=E5=8A=A0=E4=BA=86=E5=86=B2=E9=94=80?= =?UTF-8?q?=E7=9A=84=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ComponentOutboundController.java | 95 ++++++++++++++----- .../ComponentPackingController.java | 10 +- .../WmsComponentOutboundScanCodes.java | 5 + ...sComponentOutboundScanCodesRepository.java | 3 + .../ComponentOutboundControllerService.java | 36 +++++++ .../pojo/qo/PackingOutBoundReverseQO.java | 11 +++ .../common/pojo/vo/ComponentOutboundVO.java | 5 + .../common/pojo/vo/ComponentPackingVO.java | 3 +- .../entity/WmsComponentOutbound.java | 5 + .../entity/WmsComponentPacking.java | 4 +- .../mapper/WmsComponentOutboundMapper.xml | 2 +- .../wms/repository/CodeGeneratorTest.java | 2 +- 12 files changed, 150 insertions(+), 31 deletions(-) create mode 100644 nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/PackingOutBoundReverseQO.java diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/ComponentOutboundController.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/ComponentOutboundController.java index 2aefffd3..16f71845 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/ComponentOutboundController.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/ComponentOutboundController.java @@ -35,6 +35,7 @@ import java.time.LocalDateTime; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; +import java.util.stream.Stream; /** * 零部件出库单 @@ -113,6 +114,39 @@ public class ComponentOutboundController { return ApiResult.success(vos); } + /** + * 出库单冲销 + * + * @param request 确认出库单的参数对象 + */ + @PostMapping("reverse") + public ApiResult reverse(@Valid @RequestBody PackingOutBoundReverseQO request) { + // 通过出库单ID获取到出库单 + WmsComponentOutbound outbound = wmsComponentOutboundService.getById(request.getId()); + VUtil.trueThrowBusinessError(Objects.isNull(outbound)).throwMessage("出库单不存在"); + VUtil.trueThrowBusinessError(outbound.getIsReverse()).throwMessage("此出库单已经被冲销,不可以二次冲销"); + List outboundItems = wmsComponentOutboundItemService.lambdaQuery() + .eq(WmsComponentOutboundItem::getOutboundId, request.getId()) + .list(); + VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(outboundItems)).throwMessage("无有效的出库单明细项"); + + // 组装库存信息 + List inventoryDTOS = new ArrayList<>(); + for (WmsComponentOutboundItem item : outboundItems) { + List codes = wmsComponentOutboundScanCodesService.findByOutboundItemId(item.getId()); + VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(codes)).throwMessage("无有效的扫码记录"); + for (WmsComponentOutboundScanCodes code : codes) { + setInventoryDTO(inventoryDTOS, item.getIdnrk(), outbound.getFactoryNo(), item.getLgort(), code.getBatchNumber(), code.getCodeNum()); + } + } + // 组装SAP的信息 + ZWM3A20DTO zwm3a20DTO = new ZWM3A20DTO() + .setIType("B") + .setIvDelivery(outbound.getVbelv()); + componentOutboundControllerService.reverse(outbound.getId(), outbound.getPackingId(), inventoryDTOS, zwm3a20DTO); + return ApiResult.success(); + } + /** * 确认出库单 * @@ -126,16 +160,36 @@ public class ComponentOutboundController { VUtil.trueThrowBusinessError(Objects.isNull(packing)).throwMessage("此装箱单不存在"); VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(request.getItems())).throwMessage("无发货详情信息"); - List packingItemId = request.getItems() - .stream() - .map(ComponentOutboundItemInputQO::getPackingItemId) - .toList(); - List packingItems = wmsComponentPackingItemService .lambdaQuery() - .in(WmsComponentPackingItem::getId, packingItemId) + .eq(WmsComponentPackingItem::getPackingId, packing.getId()) .list(); VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(packingItems)).throwMessage("无法找到有效的装箱单详情"); + //判断是否存在了相同的交货单了 + WmsComponentOutbound outboundSelect = wmsComponentOutboundService.lambdaQuery() + .eq(WmsComponentOutbound::getVbelv, packing.getVbelv()) + .eq(WmsComponentOutbound::getIsReverse, false) + .one(); + VUtil.trueThrowBusinessError(Objects.nonNull(outboundSelect)) + .throwMessage("交货单已出库,单号为【" + outboundSelect.getOutboundNo() + "】"); + //判断数量是否一致,且已经存在了相同的收货单了 + for (WmsComponentPackingItem item : packingItems) { + List items = request.getItems() + .stream() + .filter(d -> d.getPackingItemId().equals(item.getId())) + .toList(); + VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(items)) + .throwMessage("物料【" + item.getIdnrk() + "】的实际出库数量为0,小于了出库数量【" + item.getMenge() + "】"); + + BigDecimal totalCodeNum = request.getItems().stream() + .flatMap(i -> i.getScanCodes() != null ? i.getScanCodes().stream() : Stream.empty()) + .map(ScanCodeQO::getCodeNum) + .filter(Objects::nonNull) + .reduce(BigDecimal.ZERO, BigDecimal::add); + VUtil.trueThrowBusinessError(item.getMenge().subtract(totalCodeNum).compareTo(BigDecimal.ZERO) != 0) + .throwMessage("物料【" + item.getIdnrk() + "】的实际出库数量为【" + totalCodeNum + "】,小于了出库数量【" + item.getMenge() + "】"); + } + WmsComponentOutbound outbound = setWmsComponentOutbound(packing); List outboundItems = new ArrayList<>(); List outboundScanCodes = new ArrayList<>(); @@ -156,19 +210,15 @@ public class ComponentOutboundController { //处理条码,先根据批次号、序列号进行一次数量汇总 if (CollectionUtil.isNotEmpty(item.getScanCodes())) { - List scanCodesGroup=new ArrayList<>(); - for (ScanCodeQO code : item.getScanCodes()) - { - ScanCodeQO codeItem=scanCodesGroup.stream().filter(c->c.getBatchNumber().equals(code.getBatchNumber()) + List scanCodesGroup = new ArrayList<>(); + for (ScanCodeQO code : item.getScanCodes()) { + ScanCodeQO codeItem = scanCodesGroup.stream().filter(c -> c.getBatchNumber().equals(code.getBatchNumber()) && c.getSerialNumber().equals(code.getSerialNumber()) ).findFirst().orElse(null); - if(Objects.isNull(codeItem)) - { + if (Objects.isNull(codeItem)) { scanCodesGroup.add(code); - } - else - { + } else { codeItem.setCodeNum(codeItem.getCodeNum().add(code.getCodeNum())); } } @@ -210,14 +260,12 @@ public class ComponentOutboundController { } } - for (ScanCodeQO code : scanCodesGroup) { -// VUtil.trueThrowBusinessError(codeIds.contains(code.getCodeId())).throwMessage("物料[" + outboundItem.getIdnrk() + "]的条码[" + code.getCodeId() + "]被重复使用"); -// codeIds.add(code.getCodeId()); // 组装条码信息 WmsComponentOutboundScanCodes scanCodes = new WmsComponentOutboundScanCodes(); scanCodes.setOutboundItemId(outboundItem.getId()) .setCodeId(code.getCodeId()) + .setOutboundId(outbound.getId()) .setSerialNumbers(code.getSerialNumber()) .setCodeNum(code.getCodeNum()) .setBatchNumber(code.getBatchNumber()) @@ -226,17 +274,10 @@ public class ComponentOutboundController { //组装下库存信息 setInventoryDTO(inventories, outboundItem.getIdnrk(), packing.getFactoryNo(), outboundItem.getLgort(), code.getBatchNumber(), code.getCodeNum()); - } - } else { - setInventoryDTO(inventories, outboundItem.getIdnrk(), packing.getFactoryNo(), outboundItem.getLgort(), "", outboundItem.getOutQty()); - set3A20Item("", outboundItem, outboundItem.getOutQty(), zwm3a20DTO); } } -// 判断下当前的条码是否有已经使用过得 -// List existScanCodes = wmsComponentOutboundScanCodesService.findByCodeIdIn(codeIds); -// VUtil.trueThrowBusinessError(CollectionUtil.isNotEmpty(existScanCodes)).throwMessage("存在已经使用过的条码"); componentOutboundControllerService.confirmPda(outbound, outboundItems, outboundScanCodes, zwm3a20DTO, inventories); return ApiResult.success(); } @@ -270,6 +311,7 @@ public class ComponentOutboundController { .setPackingId(packing.getId()) .setCreateName(UserUtil.getUserName()) .setCreateId(UserUtil.getUserId()) + .setIsReverse(false) .setCreateTime(LocalDateTime.now()); return outbound; } @@ -308,6 +350,9 @@ public class ComponentOutboundController { return outboundItem; } + /* + 组装库存信息 + */ private void setInventoryDTO(List inventories, String materialNo, String factoryNo, String warehouseNo, String batchNumber, BigDecimal outQty ) { diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/ComponentPackingController.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/ComponentPackingController.java index 72858f83..df381f23 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/ComponentPackingController.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/ComponentPackingController.java @@ -96,6 +96,14 @@ public class ComponentPackingController { */ @PostMapping("getorders") public ApiResult getComponentOrders(@Valid @RequestBody ComponentOrderQO request) { + // 判断交货单号是否已经存在了 + WmsComponentPacking packing = wmscomponentPackingService.lambdaQuery() + .eq(WmsComponentPacking::getVbelv, request.getVbelv()) + .eq(WmsComponentPacking::getIsCompleted, 2) + .one(); + + VUtil.trueThrowBusinessError(Objects.nonNull(packing)) + .throwMessage("已存在相同的交货单,单号为【" + packing.getNo() + "】,状态为【" + (packing.getIsCompleted() == 0 ? "未出库" : "已出库") + "】"); ZWM3A19DTO result = sapService.zwm3a19(request.getVbelv(), request.getWerks()); VUtil.trueThrowBusinessError(StrUtil.isBlank(result.getHeadDTO().getWbstk()) || result.getHeadDTO().getWbstk().equalsIgnoreCase("C")) @@ -137,7 +145,7 @@ public class ComponentPackingController { public ApiResult deletePacking(@Valid @RequestBody List ids) { //首先判断是否存在已完成的单据 List packingList = wmscomponentPackingService.lambdaQuery() - .eq(WmsComponentPacking::getIsCompleted, 2) + .ne(WmsComponentPacking::getIsCompleted, 0) .in(WmsComponentPacking::getId, ids) .list(); VUtil.trueThrowBusinessError(CollectionUtil.isNotEmpty(packingList)).throwMessage("存在已完成的装车单,请勿删除"); diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/pojo/document/WmsComponentOutboundScanCodes.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/pojo/document/WmsComponentOutboundScanCodes.java index 89385196..b322c324 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/pojo/document/WmsComponentOutboundScanCodes.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/pojo/document/WmsComponentOutboundScanCodes.java @@ -15,6 +15,11 @@ public class WmsComponentOutboundScanCodes { @Id private String id; + /** + * 出库单ID + */ + private Long outboundId; + /*** * 出库单的单行ID号 * diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/repository/WmsComponentOutboundScanCodesRepository.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/repository/WmsComponentOutboundScanCodesRepository.java index e007e017..67694994 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/repository/WmsComponentOutboundScanCodesRepository.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/repository/WmsComponentOutboundScanCodesRepository.java @@ -12,6 +12,9 @@ import java.util.List; @Repository public interface WmsComponentOutboundScanCodesRepository extends MongoRepository { List findByOutboundItemId(Long outboundItemId); + + List findByoutboundId(Long outboundId); + List findByCodeIdIn(List attr0); } \ No newline at end of file diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/ComponentOutboundControllerService.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/ComponentOutboundControllerService.java index 8602f3d5..fc1e596e 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/ComponentOutboundControllerService.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/ComponentOutboundControllerService.java @@ -10,7 +10,10 @@ import com.nflg.wms.common.pojo.dto.ZWM3A20DTO; import com.nflg.wms.common.pojo.qo.ComponentOutboundInputQO; import com.nflg.wms.common.pojo.qo.ComponentOutboundItemInputQO; import com.nflg.wms.common.pojo.qo.ComponentOutboundQO; +import com.nflg.wms.common.pojo.qo.PackingOutBoundReverseQO; import com.nflg.wms.common.pojo.vo.ComponentOutboundVO; +import com.nflg.wms.common.util.DateTimeUtil; +import com.nflg.wms.common.util.UserUtil; import com.nflg.wms.common.util.VUtil; import com.nflg.wms.repository.entity.*; import com.nflg.wms.repository.service.*; @@ -19,6 +22,7 @@ import jakarta.validation.Valid; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; +import java.time.LocalDateTime; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; @@ -82,4 +86,36 @@ public class ComponentOutboundControllerService { wmsComponentOutboundScanCodesService.insert(outboundScanCodes); } } + + @Transactional + public void reverse(Long outboundId, Long packingId, List inventories, ZWM3A20DTO zwm3a20DTO) { + //修改出库单的冲销状态为true + wmsComponentOutboundService.lambdaUpdate() + .set(WmsComponentOutbound::getIsReverse, true) + .set(WmsComponentOutbound::getModifyId, UserUtil.getUserId()) + .set(WmsComponentOutbound::getModifyName, UserUtil.getUserName()) + .set(WmsComponentOutbound::getModifyTime, LocalDateTime.now()) + .eq(WmsComponentOutbound::getId, outboundId) + .update(); + // 修改包装单的冲销状态为true + wmscomponentPackingService.lambdaUpdate() + .set(WmsComponentPacking::getIsCompleted, 1) + .set(WmsComponentPacking::getModifyId, UserUtil.getUserId()) + .set(WmsComponentPacking::getModifyName, UserUtil.getUserName()) + .set(WmsComponentPacking::getModifyTime, LocalDateTime.now()) + .eq(WmsComponentPacking::getId, packingId) + .update(); + //修改库存信息 + if (CollectionUtil.isNotEmpty(inventories)) { + inventoryService.in(inventories); + } +//SAP冲销 + Pair result = sapService.zwm3a20(zwm3a20DTO); + wmsComponentOutboundService.lambdaUpdate() + .set(WmsComponentOutbound::getMaterialDoc, result.getKey()) + .set(WmsComponentOutbound::getMaterialDocYear, result.getValue()) + .eq(WmsComponentOutbound::getId, outboundId) + .update(); + } + } diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/PackingOutBoundReverseQO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/PackingOutBoundReverseQO.java new file mode 100644 index 00000000..627f3b83 --- /dev/null +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/PackingOutBoundReverseQO.java @@ -0,0 +1,11 @@ +package com.nflg.wms.common.pojo.qo; + +import lombok.Data; +import lombok.experimental.Accessors; + +@Data +@Accessors(chain = true) +public class PackingOutBoundReverseQO { + // 出库单ID + private Long id; +} diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/ComponentOutboundVO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/ComponentOutboundVO.java index 2756e055..96ae6e9a 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/ComponentOutboundVO.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/ComponentOutboundVO.java @@ -150,4 +150,9 @@ public class ComponentOutboundVO { private String modifyName; private LocalDateTime modifyTime; + + /** + * 是否冲销 + */ + private Boolean isReverse; } diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/ComponentPackingVO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/ComponentPackingVO.java index 3c1606ea..97fa351c 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/ComponentPackingVO.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/ComponentPackingVO.java @@ -124,7 +124,7 @@ public class ComponentPackingVO { private String wbstk; /** - * 0 未出库;1 完成出库 + * 0 未出库;1 对冲;2 出库完成 */ private Short isCompleted; @@ -136,4 +136,5 @@ public class ComponentPackingVO { * 所属工厂 */ private String factoryNo; + } diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsComponentOutbound.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsComponentOutbound.java index a0b994b3..dbc92973 100644 --- a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsComponentOutbound.java +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsComponentOutbound.java @@ -177,4 +177,9 @@ public class WmsComponentOutbound implements Serializable { * 物料年度凭证 */ private String materialDocYear; + + /** + * 是否冲销 + */ + private Boolean isReverse; } diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsComponentPacking.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsComponentPacking.java index a4ec3b2c..5c6e92be 100644 --- a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsComponentPacking.java +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsComponentPacking.java @@ -14,7 +14,7 @@ import java.time.LocalDateTime; /** *

- * + * *

* * @author 代码生成器生成 @@ -160,7 +160,7 @@ public class WmsComponentPacking implements Serializable { private String factoryNo; /** - * 0 未出库;1 部分出库;2 出库完成 + * 0 未出库;1 对冲;2 出库完成 */ private Short isCompleted; } diff --git a/nflg-wms-repository/src/main/resources/mapper/WmsComponentOutboundMapper.xml b/nflg-wms-repository/src/main/resources/mapper/WmsComponentOutboundMapper.xml index 3a50a692..d13844ee 100644 --- a/nflg-wms-repository/src/main/resources/mapper/WmsComponentOutboundMapper.xml +++ b/nflg-wms-repository/src/main/resources/mapper/WmsComponentOutboundMapper.xml @@ -6,7 +6,7 @@ select id,packing_no, outbound_no,matnr,name1,uname,vbeln,maktx,datum,xnum,cnum,bname,zjshz,zchep,tel_number,sernr,huodh,vbelv, p_name,l_bezei,l_name,g_streen,g_str_suppl2,wbstk,create_name,create_time,factory_no,create_id, - create_name,create_time,packing_id + create_name,create_time,packing_id,is_reverse from wms_component_outbound diff --git a/nflg-wms-repository/src/test/java/com/nflg/wms/repository/CodeGeneratorTest.java b/nflg-wms-repository/src/test/java/com/nflg/wms/repository/CodeGeneratorTest.java index 35eae3d8..6c8d92d5 100644 --- a/nflg-wms-repository/src/test/java/com/nflg/wms/repository/CodeGeneratorTest.java +++ b/nflg-wms-repository/src/test/java/com/nflg/wms/repository/CodeGeneratorTest.java @@ -33,7 +33,7 @@ public class CodeGeneratorTest { ) .strategyConfig(builder -> { builder - .addInclude("wms_inventory_barcode_printing") //只生成指定表 + .addInclude("wms_component_outbound") //只生成指定表 .entityBuilder().idType(IdType.ASSIGN_ID) .enableLombok() .enableChainModel()