package cn.iocoder.yudao.module.mes.api.wms; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.mes.api.wms.dto.WmsPurchaseInboundReqDTO; import cn.iocoder.yudao.module.mes.api.wms.dto.WmsSalesOutboundReqDTO; import cn.iocoder.yudao.module.mes.api.wms.dto.WmsStockDetailRespDTO; import cn.iocoder.yudao.module.mes.api.wms.dto.WmsStockQueryReqDTO; import cn.iocoder.yudao.module.mes.api.wms.stock.WmsStockApi; import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockListReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO; import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO; import cn.iocoder.yudao.module.mes.dal.mysql.wm.materialstock.MesWmMaterialStockMapper; import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants; import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum; import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService; import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService; import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO; import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseService; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.Collections; import java.util.List; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; /** * WMS 库存 API 实现类 * * 在 MES 模块中实现,内部调用 MesWmTransactionService */ @Service @Validated @Slf4j public class WmsStockApiImpl implements WmsStockApi { @Resource private MesWmTransactionService transactionService; @Resource private MesWmMaterialStockService materialStockService; @Resource private MesWmMaterialStockMapper materialStockMapper; @Resource private MesMdItemService itemService; @Resource private MesWmWarehouseService warehouseService; @Override public Long purchaseInbound(WmsPurchaseInboundReqDTO reqDTO) { log.info("[purchaseInbound] 采购入库,bizId={}, bizCode={}", reqDTO.getBizId(), reqDTO.getBizCode()); List transactionIds = CollUtil.newArrayList(); LocalDateTime receiptTime = reqDTO.getReceiptTime() != null ? reqDTO.getReceiptTime() : LocalDateTime.now(); for (WmsPurchaseInboundReqDTO.Item item : reqDTO.getItems()) { MesWmTransactionSaveReqDTO transaction = new MesWmTransactionSaveReqDTO() .setType(MesWmTransactionTypeEnum.IN.getType()) .setBizType(MesBizTypeConstants.WM_ITEM_RECEIPT_IN) .setBizId(reqDTO.getBizId()) .setBizCode(reqDTO.getBizCode()) .setBizLineId(item.getBizLineId()) .setItemId(item.getItemId()) .setWarehouseId(item.getWarehouseId()) .setLocationId(item.getLocationId()) .setAreaId(item.getAreaId()) .setBatchId(item.getBatchId()) .setBatchCode(item.getBatchCode()) .setVendorId(reqDTO.getVendorId()) .setQuantity(item.getQuantity()) .setReceiptTime(receiptTime) .setCheckFlag(true); transactionIds.add(transactionService.createTransaction(transaction)); } return transactionIds.get(0); } @Override public Long purchaseReturnOutbound(WmsPurchaseInboundReqDTO reqDTO) { log.info("[purchaseReturnOutbound] 采购退货出库,bizId={}, bizCode={}", reqDTO.getBizId(), reqDTO.getBizCode()); List transactionIds = CollUtil.newArrayList(); LocalDateTime receiptTime = reqDTO.getReceiptTime() != null ? reqDTO.getReceiptTime() : LocalDateTime.now(); for (WmsPurchaseInboundReqDTO.Item item : reqDTO.getItems()) { MesWmTransactionSaveReqDTO transaction = new MesWmTransactionSaveReqDTO() .setType(MesWmTransactionTypeEnum.OUT.getType()) .setBizType(MesBizTypeConstants.WM_RETURN_VENDOR) .setBizId(reqDTO.getBizId()) .setBizCode(reqDTO.getBizCode()) .setBizLineId(item.getBizLineId()) .setItemId(item.getItemId()) .setWarehouseId(item.getWarehouseId()) .setLocationId(item.getLocationId()) .setAreaId(item.getAreaId()) .setBatchId(item.getBatchId()) .setBatchCode(item.getBatchCode()) .setVendorId(reqDTO.getVendorId()) .setQuantity(item.getQuantity().negate()) .setReceiptTime(receiptTime) .setCheckFlag(true); transactionIds.add(transactionService.createTransaction(transaction)); } return transactionIds.get(0); } @Override public Long salesOutbound(WmsSalesOutboundReqDTO reqDTO) { log.info("[salesOutbound] 销售出库,bizId={}, bizCode={}", reqDTO.getBizId(), reqDTO.getBizCode()); List transactionIds = CollUtil.newArrayList(); LocalDateTime outboundTime = reqDTO.getOutboundTime() != null ? reqDTO.getOutboundTime() : LocalDateTime.now(); for (WmsSalesOutboundReqDTO.Item item : reqDTO.getItems()) { MesWmTransactionSaveReqDTO transaction = new MesWmTransactionSaveReqDTO() .setType(MesWmTransactionTypeEnum.OUT.getType()) .setBizType(MesBizTypeConstants.WM_PRODUCT_SALES) .setBizId(reqDTO.getBizId()) .setBizCode(reqDTO.getBizCode()) .setBizLineId(item.getBizLineId()) .setItemId(item.getItemId()) .setWarehouseId(item.getWarehouseId()) .setLocationId(item.getLocationId()) .setAreaId(item.getAreaId()) .setBatchId(item.getBatchId()) .setBatchCode(item.getBatchCode()) .setQuantity(item.getQuantity().negate()) .setReceiptTime(outboundTime) .setCheckFlag(true); transactionIds.add(transactionService.createTransaction(transaction)); } return transactionIds.get(0); } @Override public Long salesReturnInbound(WmsSalesOutboundReqDTO reqDTO) { log.info("[salesReturnInbound] 销售退货入库,bizId={}, bizCode={}", reqDTO.getBizId(), reqDTO.getBizCode()); List transactionIds = CollUtil.newArrayList(); LocalDateTime outboundTime = reqDTO.getOutboundTime() != null ? reqDTO.getOutboundTime() : LocalDateTime.now(); for (WmsSalesOutboundReqDTO.Item item : reqDTO.getItems()) { MesWmTransactionSaveReqDTO transaction = new MesWmTransactionSaveReqDTO() .setType(MesWmTransactionTypeEnum.IN.getType()) .setBizType(MesBizTypeConstants.WM_RETURN_SALES) .setBizId(reqDTO.getBizId()) .setBizCode(reqDTO.getBizCode()) .setBizLineId(item.getBizLineId()) .setItemId(item.getItemId()) .setWarehouseId(item.getWarehouseId()) .setLocationId(item.getLocationId()) .setAreaId(item.getAreaId()) .setBatchId(item.getBatchId()) .setBatchCode(item.getBatchCode()) .setQuantity(item.getQuantity()) .setReceiptTime(outboundTime) .setCheckFlag(true); transactionIds.add(transactionService.createTransaction(transaction)); } return transactionIds.get(0); } @Override public BigDecimal getStockQuantity(Long itemId, Long warehouseId) { MesWmMaterialStockListReqVO reqVO = new MesWmMaterialStockListReqVO(); reqVO.setItemId(itemId); reqVO.setWarehouseId(warehouseId); List stockList = materialStockMapper.selectList(reqVO); if (CollUtil.isEmpty(stockList)) { return BigDecimal.ZERO; } return stockList.stream() .map(MesWmMaterialStockDO::getQuantity) .reduce(BigDecimal.ZERO, BigDecimal::add); } @Override public WmsStockDetailRespDTO getStockDetail(WmsStockQueryReqDTO reqDTO) { MesWmMaterialStockListReqVO reqVO = new MesWmMaterialStockListReqVO(); reqVO.setItemId(reqDTO.getItemId()); reqVO.setWarehouseId(reqDTO.getWarehouseId()); reqVO.setLocationId(reqDTO.getLocationId()); reqVO.setAreaId(reqDTO.getAreaId()); reqVO.setBatchId(reqDTO.getBatchId()); reqVO.setVendorId(reqDTO.getVendorId()); List stockList = materialStockMapper.selectList(reqVO); if (CollUtil.isEmpty(stockList)) { return null; } return convertToStockDetailRespDTO(stockList.get(0)); } @Override public List getStockDetailList(WmsStockQueryReqDTO reqDTO) { MesWmMaterialStockListReqVO reqVO = new MesWmMaterialStockListReqVO(); reqVO.setItemId(reqDTO.getItemId()); reqVO.setWarehouseId(reqDTO.getWarehouseId()); reqVO.setLocationId(reqDTO.getLocationId()); reqVO.setAreaId(reqDTO.getAreaId()); reqVO.setBatchId(reqDTO.getBatchId()); reqVO.setVendorId(reqDTO.getVendorId()); List stockList = materialStockMapper.selectList(reqVO); if (CollUtil.isEmpty(stockList)) { return Collections.emptyList(); } return convertList(stockList, this::convertToStockDetailRespDTO); } /** * 转换库存DO为响应DTO */ private WmsStockDetailRespDTO convertToStockDetailRespDTO(MesWmMaterialStockDO stock) { WmsStockDetailRespDTO respDTO = BeanUtils.toBean(stock, WmsStockDetailRespDTO.class); if (stock.getItemId() != null) { MesMdItemDO item = itemService.getItem(stock.getItemId()); if (item != null) { respDTO.setItemCode(item.getCode()); respDTO.setItemName(item.getName()); } } if (stock.getWarehouseId() != null) { MesWmWarehouseDO warehouse = warehouseService.getWarehouse(stock.getWarehouseId()); if (warehouse != null) { respDTO.setWarehouseName(warehouse.getName()); } } return respDTO; } }