diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/CenterOutboundControllerService.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/CenterOutboundControllerService.java index b93a67b5..4a9c6c65 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/CenterOutboundControllerService.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/CenterOutboundControllerService.java @@ -1,17 +1,33 @@ package com.nflg.wms.admin.service; -import com.nflg.wms.common.pojo.dto.SapImportResultDTO; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.IdUtil; +import com.lowagie.text.ImgTemplate; +import com.nflg.wms.common.pojo.dto.*; import com.nflg.wms.common.pojo.qo.C_MaterialOutboundQO; import com.nflg.wms.common.pojo.qo.CommendationItemQO; import com.nflg.wms.common.pojo.vo.C_MaterialOutboundSAPItemVO; import com.nflg.wms.common.pojo.vo.C_MaterialOutboundreCommendationItemVO; +import com.nflg.wms.common.util.UserUtil; +import com.nflg.wms.repository.entity.WmsCenterOutbound; +import com.nflg.wms.repository.entity.WmsCenterOutboundItem; +import com.nflg.wms.repository.entity.WmsCenterOutboundScan; +import com.nflg.wms.repository.entity.WmsInventory; import com.nflg.wms.repository.service.IWmsCenterOutboundItemService; import com.nflg.wms.repository.service.IWmsCenterOutboundScanService; import com.nflg.wms.repository.service.IWmsCenterOutboundService; +import com.nflg.wms.repository.service.IWmsInventoryService; import jakarta.annotation.Resource; +import org.apache.poi.hssf.record.PageBreakRecord; +import org.aspectj.weaver.Utils; import org.springframework.stereotype.Component; -import java.util.List; +import java.lang.ref.ReferenceQueue; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; @Component public class CenterOutboundControllerService { @@ -27,16 +43,189 @@ public class CenterOutboundControllerService { @Resource private SapService sapService; - public List getOrderItem(String reservedNumber) { + @Resource + private IWmsInventoryService wmsInventoryService; + @Resource + private BasdeSerialNumberControllerService basdeSerialNumberControllerService; + + /** + * 根据预留号获取订单项信息 + * + * @param reservedNumber 预留号 + * @return 订单项信息列表 + */ + public List getOrderItem(String reservedNumber) { + // 调用SAP服务获取物料出库查询数据 + C_MaterialOutboundQueryDTO dto = sapService.zwm00_MB026(reservedNumber); + if (Objects.isNull(dto) || Objects.isNull(dto.getItems()) || CollectionUtil.isEmpty(dto.getItems())) + return Collections.emptyList(); + + // 获取仓位信息映射 + Map warehouseMap = getBinNos(dto.getItems()); + + List vos = new ArrayList<>(); + dto.getItems().forEach(item -> { + // 构造仓库映射key + String key = item.getResbWerks() + "_" + item.getResbMatnr() + "_" + item.getResbLgort(); + SAPSyncFromDTO warehouse = warehouseMap.get(key); + + // 转换为VO对象 + C_MaterialOutboundSAPItemVO vo = new C_MaterialOutboundSAPItemVO(); + vo.setReservedNumberId(item.getResbRsnum()) + .setMaterialNo(item.getResbMatnr()) + .setMaterialDesc(item.getMaktx()) + .setUnit(item.getResbMeins()) + .setFactory(item.getResbWerks()) + .setQty(item.getWqyls()) + .setWarehouseNumber(item.getResbLgort()) + .setBinNos(Objects.isNull(warehouse) ? "" : warehouse.getBinNos()); + + // 获取推荐项信息 + List recommendationItems = getCommendationItems(new CommendationItemQO() + .setMaterialNo(item.getResbMatnr()) + .setFactory(item.getResbWerks()) + .setWarehouseNumber(item.getResbLgort()) + .setQty(item.getWqyls()) + ); + if (Objects.nonNull(recommendationItems)) + vo.setRecommendationItems(recommendationItems); + + vos.add(vo); + }); + return vos; } + + private Map getBinNos(List sapItems) { + // 提取并去重所有不为空的工厂编码(ResbWerks) + List distinctResbWerks = sapItems.stream() + .map(C_MaterialOutboundItemQueryDTO::getResbWerks) + .filter(Objects::nonNull) + .distinct() + .toList(); + + // 存储所有工厂对应的仓库信息 + List allWarehouse = new ArrayList<>(); + + // 遍历每个工厂,获取其对应的仓库和物料信息 + for (String werks : distinctResbWerks) { + // 筛选出当前工厂的所有物料退货项 + List filteredItems = sapItems.stream() + .filter(item -> werks.equals(item.getResbWerks())) + .toList(); + + // 收集当前工厂下所有的仓库编号和物料编号 + List warehouseNos = new ArrayList<>(); + List materialNos = new ArrayList<>(); + + for (C_MaterialOutboundItemQueryDTO item : filteredItems) { + if (item.getResbLgort() != null) { + warehouseNos.add(item.getResbLgort()); + } + if (item.getResbMatnr() != null) { + materialNos.add(item.getResbMatnr()); + } + } + // 调用SAP服务获取仓库详细信息 + List warehouseList = sapService.zwm3A01(werks, warehouseNos, materialNos, null, null); + if (CollectionUtil.isNotEmpty(warehouseList)) { + allWarehouse.addAll(warehouseList); + } + + } + // 构建缓存 Map 提高查找效率 + Map warehouseMap = allWarehouse.stream() + .collect(Collectors.toMap( + w -> w.getFactoryNo() + "_" + w.getMaterialNo() + "_" + w.getWarehouseNo(), + Function.identity(), + (existing, replacement) -> existing + )); + return warehouseMap; + } + + public void confirmOutbound(C_MaterialOutboundQO request) { + if (Objects.isNull(request) || Objects.isNull(request.getItems()) || CollectionUtil.isEmpty(request.getItems())) + return; + //首先要保存SAP的信息 + C_MaterialOutboundDTO outboundDTO = sapService.ZWM00_MB115(request); + Long outBoundId = IdUtil.getSnowflakeNextId(); + String orderNumber = basdeSerialNumberControllerService.generateSerialNumber(1); + + WmsCenterOutbound wmsCenterOutbound = new WmsCenterOutbound() + .setId(outBoundId) + .setOrderNumber(orderNumber) + .setReservedNumber(request.getResbRsNum()) + .setMaterialDoc(outboundDTO.getEMblnr()) + .setMaterialDocYear(outboundDTO.getEMJahr()) + .setCreateTime(LocalDateTime.now()) + .setCreateUserName(UserUtil.getUserName()) + .setCreateUserId(UserUtil.getUserId()) + .setWorkstation(request.getRkpfWempf()); + + List wmsCenterOutboundItems = new ArrayList<>(); + List wmsCenterOutboundScans = new ArrayList<>(); + request.getItems().forEach(item -> { + Long itemId = IdUtil.getSnowflakeNextId(); + WmsCenterOutboundItem wmsCenterOutboundItem = new WmsCenterOutboundItem() + .setId(itemId) + .setOrderId(outBoundId) + .setMaterialNo(item.getResbMatnr()) + .setMaterialDesc(item.getMaktx()) + .setUnit(item.getResbMeins()) + .setFactory(item.getResbWerks()) + .setQty(item.getResbErfmg()) + .setWarehouseNumber(item.getResbLgort()) + .setReservedNumberId(item.getResbRspos()); + + if (CollectionUtil.isNotEmpty(item.getScanCodes())) { + item.getScanCodes().forEach(scanCode -> { + WmsCenterOutboundScan wmsCenterOutboundScan = new WmsCenterOutboundScan() + .setId(IdUtil.getSnowflakeNextId()) + .setItemId(itemId) + .setCodeId(scanCode.getCodeId()) + .setCodeNum(scanCode.getCodeNum()) + .setBatchNumber(scanCode.getBatchNumber()) + .setSerialNumber(scanCode.getSerialNumber()); + }); + } + }); + wmsCenterOutboundService.confirmOutbound(wmsCenterOutbound, wmsCenterOutboundItems, wmsCenterOutboundScans); } + /** + * 根据推荐条件获取物料出库推荐批次项列表 + * + * @param request 推荐项查询条件对象,包含物料编号、工厂、仓库编号和需求数量等信息 + * @return 物料出库推荐项VO列表,包含推荐的批次号和推荐数量;如果无匹配库存则返回空列表 + */ public List getCommendationItems(CommendationItemQO request) { + // 查询符合条件的库存记录:物料号、工厂、仓库匹配且数量大于0的记录,按批次号升序排列 + List inventories = wmsInventoryService.lambdaQuery() + .eq(WmsInventory::getMaterialNo, request.getMaterialNo()) + .eq(WmsInventory::getFactoryNo, request.getFactory()) + .eq(WmsInventory::getWarehouseNo, request.getWarehouseNumber()) + .gt(WmsInventory::getNum, 0) + .orderByAsc(WmsInventory::getBatchNumber) + .list(); + if (Objects.isNull(inventories) || CollectionUtil.isEmpty(inventories)) + return Collections.emptyList(); + List vos = new ArrayList<>(); + BigDecimal qty = request.getQty(); + // 遍历库存记录,按批次号顺序推荐出库批次,直到满足需求数量 + for (WmsInventory inventory : inventories) { + qty = qty.subtract(inventory.getNum()); + C_MaterialOutboundreCommendationItemVO vo = new C_MaterialOutboundreCommendationItemVO(); + vo.setRecommendationBatchCode(inventory.getBatchNumber()); + // 如果剩余需求数量小于等于0,说明已满足需求,推荐数量为剩余需求数量;否则推荐当前批次的全部数量 + vo.setRecommendationBatchNum(qty.compareTo(BigDecimal.ZERO) <= 0 ? qty : inventory.getNum()); + vos.add(vo); + if (qty.compareTo(BigDecimal.ZERO) <= 0) + break; + } + return vos; } - } diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/C_MaterialOutboundDTO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/C_MaterialOutboundDTO.java index 7cea55fc..38fb0b83 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/C_MaterialOutboundDTO.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/C_MaterialOutboundDTO.java @@ -17,5 +17,5 @@ public class C_MaterialOutboundDTO { private String eMJahr; //中心退库的物料详情信息 - private C_MaterialOutboundQO requestQO; + // private C_MaterialOutboundQO requestQO; } diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/C_MaterialOutboundQueryDTO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/C_MaterialOutboundQueryDTO.java index afcf232d..65354595 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/C_MaterialOutboundQueryDTO.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/C_MaterialOutboundQueryDTO.java @@ -9,6 +9,7 @@ import java.util.List; @Accessors(chain = true) public class C_MaterialOutboundQueryDTO { private String resbRsnum; + // 预留项目号 RKPF-WEMPF private String rkpfWempf; diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/C_MaterialOutboundItemQO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/C_MaterialOutboundItemQO.java index a31bcba6..917e9931 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/C_MaterialOutboundItemQO.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/C_MaterialOutboundItemQO.java @@ -28,6 +28,11 @@ public class C_MaterialOutboundItemQO { // 单位 private String resbMeins; + /** + * 实际领料数量 + */ + private BigDecimal qty; + // 实际出库数量 private BigDecimal resbErfmg; diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/C_MaterialOutboundQO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/C_MaterialOutboundQO.java index a557b68f..c671c6ac 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/C_MaterialOutboundQO.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/C_MaterialOutboundQO.java @@ -11,9 +11,8 @@ public class C_MaterialOutboundQO { //预留号 private String resbRsNum; - //PDA操作员 - private String pdaOperator; - + // 工位 + private String rkpfWempf; // 预留单退料详情信息 private List items; } diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsCenterOutbound.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsCenterOutbound.java index a5fb4099..da1f0b44 100644 --- a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsCenterOutbound.java +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsCenterOutbound.java @@ -66,20 +66,6 @@ public class WmsCenterOutbound implements Serializable { */ private LocalDateTime createTime; - /** - * sap导入的状态 - */ - private Boolean sapStatus; - - /** - * sap导入异常信息 - */ - private String sapMsg; - - /** - * 流水号 - */ - private Integer serialNumber; /** * 工位 diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsCenterOutboundItem.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsCenterOutboundItem.java index 11d8ce3e..69e2b95a 100644 --- a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsCenterOutboundItem.java +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsCenterOutboundItem.java @@ -66,6 +66,8 @@ public class WmsCenterOutboundItem implements Serializable { */ private BigDecimal qty; + + /** * 默认仓库 */ diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsCenterOutboundService.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsCenterOutboundService.java index 6a79a4df..908f9448 100644 --- a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsCenterOutboundService.java +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsCenterOutboundService.java @@ -4,8 +4,12 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.nflg.wms.common.pojo.qo.C_MaterialOutboundSearchQO; import com.nflg.wms.repository.entity.WmsCenterOutbound; import com.baomidou.mybatisplus.extension.service.IService; +import com.nflg.wms.repository.entity.WmsCenterOutboundItem; +import com.nflg.wms.repository.entity.WmsCenterOutboundScan; import jakarta.validation.Valid; +import java.util.List; + /** *

* 服务类 @@ -17,4 +21,8 @@ import jakarta.validation.Valid; public interface IWmsCenterOutboundService extends IService { IPage search(@Valid C_MaterialOutboundSearchQO request); + + void confirmOutbound(WmsCenterOutbound wmsCenterOutbound, + List wmsCenterOutboundItems, + List wmsCenterOutboundScans); } diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsCenterOutboundServiceImpl.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsCenterOutboundServiceImpl.java index b710f95c..1e304370 100644 --- a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsCenterOutboundServiceImpl.java +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsCenterOutboundServiceImpl.java @@ -5,16 +5,26 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.nflg.wms.common.pojo.qo.C_MaterialOutboundSearchQO; +import com.nflg.wms.common.util.VUtil; import com.nflg.wms.repository.entity.WmsCenterOutbound; +import com.nflg.wms.repository.entity.WmsCenterOutboundItem; +import com.nflg.wms.repository.entity.WmsCenterOutboundScan; import com.nflg.wms.repository.entity.WmsCenterReturn; import com.nflg.wms.repository.mapper.WmsCenterOutboundMapper; +import com.nflg.wms.repository.service.IWmsCenterOutboundItemService; +import com.nflg.wms.repository.service.IWmsCenterOutboundScanService; import com.nflg.wms.repository.service.IWmsCenterOutboundService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.nflg.wms.repository.service.IWmsCenterReturnScanService; +import jakarta.annotation.Resource; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; /** *

- * 服务实现类 + * 服务实现类 *

* * @author 代码生成器生成 @@ -23,6 +33,11 @@ import org.springframework.stereotype.Service; @Service public class WmsCenterOutboundServiceImpl extends ServiceImpl implements IWmsCenterOutboundService { + @Resource + private IWmsCenterOutboundItemService wmsCenterOutboundItemService; + @Resource + private IWmsCenterOutboundScanService wmsCenterOutboundScanService; + @Override public IPage search(C_MaterialOutboundSearchQO request) { // 参数非空校验 @@ -48,4 +63,16 @@ public class WmsCenterOutboundServiceImpl extends ServiceImpl(page, pageSize), queryWrapper); } + + @Override + @Transactional + public void confirmOutbound(WmsCenterOutbound wmsCenterOutbound, + List wmsCenterOutboundItems, + List wmsCenterOutboundScans) { + VUtil.trueThrowBusinessError(!this.save(wmsCenterOutbound)).throwMessage("中心领料单保存失败!"); + VUtil.trueThrowBusinessError(!wmsCenterOutboundItemService.saveBatch(wmsCenterOutboundItems)).throwMessage("中心领料单保存失败!"); + VUtil.trueThrowBusinessError(!wmsCenterOutboundScanService.saveBatch(wmsCenterOutboundScans)).throwMessage("中心领料单保存失败!"); +//todo 库存扣减 + } + }