diff --git a/src/main/java/com/gaotao/modules/warehouse/controller/IfsInventoryInitController.java b/src/main/java/com/gaotao/modules/warehouse/controller/IfsInventoryInitController.java index 2f9cd08..f903d8a 100644 --- a/src/main/java/com/gaotao/modules/warehouse/controller/IfsInventoryInitController.java +++ b/src/main/java/com/gaotao/modules/warehouse/controller/IfsInventoryInitController.java @@ -4,6 +4,7 @@ import com.gaotao.common.utils.PageUtils; import com.gaotao.common.utils.R; import com.gaotao.modules.warehouse.entity.InventoryStock; import com.gaotao.modules.warehouse.entity.dto.CreateHuRequestDto; +import com.gaotao.modules.warehouse.entity.dto.BatchCreateHuRequestDto; import com.gaotao.modules.warehouse.service.IfsInventoryInitService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -75,4 +76,27 @@ public class IfsInventoryInitController { return R.error("创建其它入库HandlingUnit失败: " + e.getMessage()); } } + + /** + * 批量创建HandlingUnit + *

功能说明:一次请求创建多个HU,每行数据创建一条HU

+ *

业务规则:

+ * + * + * @param request 批量创建HU请求 + * @return 创建的HU ID列表 + */ + @PostMapping("/batchCreateHandlingUnits") + public R batchCreateHandlingUnits(@RequestBody BatchCreateHuRequestDto request) { + try { + List unitIds = ifsInventoryInitService.batchCreateHandlingUnits(request); + return R.ok().put("unitIds", unitIds).put("msg", "批量创建HU成功"); + } catch (Exception e) { + return R.error("批量创建HandlingUnit失败: " + e.getMessage()); + } + } } diff --git a/src/main/java/com/gaotao/modules/warehouse/dao/WarehouseMapper.java b/src/main/java/com/gaotao/modules/warehouse/dao/WarehouseMapper.java index fafbdd9..df49c80 100644 --- a/src/main/java/com/gaotao/modules/warehouse/dao/WarehouseMapper.java +++ b/src/main/java/com/gaotao/modules/warehouse/dao/WarehouseMapper.java @@ -115,7 +115,7 @@ public interface WarehouseMapper extends BaseMapper { * @param batchNo 批次号 * @param locationId 库位ID * @param wdr WDR - * @param printQty 打印数量 + * @param printQty 打印数量(支持小数) */ void updateIfsPrintQty(@Param("site") String site, @Param("warehouseId") String warehouseId, @@ -123,7 +123,7 @@ public interface WarehouseMapper extends BaseMapper { @Param("batchNo") String batchNo, @Param("locationId") String locationId, @Param("wdr") String wdr, - @Param("printQty") Integer printQty); + @Param("printQty") java.math.BigDecimal printQty); /** * 设置IFS库存的print_qty字段(直接设置,不是累加) diff --git a/src/main/java/com/gaotao/modules/warehouse/entity/dto/BatchCreateHuRequestDto.java b/src/main/java/com/gaotao/modules/warehouse/entity/dto/BatchCreateHuRequestDto.java new file mode 100644 index 0000000..2b5517b --- /dev/null +++ b/src/main/java/com/gaotao/modules/warehouse/entity/dto/BatchCreateHuRequestDto.java @@ -0,0 +1,39 @@ +package com.gaotao.modules.warehouse.entity.dto; + +import lombok.Data; + +import java.util.List; + +/** + * 批量创建HandlingUnit请求DTO + * + *

功能说明:支持一次请求创建多个HU

+ * + * @author System + * @since 2025-01-14 + */ +@Data +public class BatchCreateHuRequestDto { + + /** + * HU创建项列表 + */ + private List items; + + /** + * 批量创建HU项 + */ + @Data + public static class BatchCreateHuItem { + private String site; // 站点 + private String warehouseId; // 仓库ID + private String partNo; // 商品编码 + private String partDesc; // 商品描述 + private String batchNo; // 批次号(使用每行自己的批次号) + private String wdr; // WDR + private String locationId; // 库位 + private String umid; // 单位 + private java.math.BigDecimal qtyOnHand; // 库存数量(作为HU数量) + } +} + diff --git a/src/main/java/com/gaotao/modules/warehouse/entity/dto/CreateHuRequestDto.java b/src/main/java/com/gaotao/modules/warehouse/entity/dto/CreateHuRequestDto.java index 4ac9e5c..d5ce820 100644 --- a/src/main/java/com/gaotao/modules/warehouse/entity/dto/CreateHuRequestDto.java +++ b/src/main/java/com/gaotao/modules/warehouse/entity/dto/CreateHuRequestDto.java @@ -21,6 +21,7 @@ public class CreateHuRequestDto { private String locationId; // 库位 private BigDecimal perPackageQty; // 单包装数量 private Integer packageCount; // 包装数 + private BigDecimal lastPackageQty; // 最后一个HU的数量(如果为null,则所有HU数量相同) private String umid; // 单位 @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") diff --git a/src/main/java/com/gaotao/modules/warehouse/service/IfsInventoryInitService.java b/src/main/java/com/gaotao/modules/warehouse/service/IfsInventoryInitService.java index 527aa06..2750fbf 100644 --- a/src/main/java/com/gaotao/modules/warehouse/service/IfsInventoryInitService.java +++ b/src/main/java/com/gaotao/modules/warehouse/service/IfsInventoryInitService.java @@ -3,6 +3,7 @@ package com.gaotao.modules.warehouse.service; import com.gaotao.common.utils.PageUtils; import com.gaotao.modules.warehouse.entity.InventoryStock; import com.gaotao.modules.warehouse.entity.dto.CreateHuRequestDto; +import com.gaotao.modules.warehouse.entity.dto.BatchCreateHuRequestDto; import java.util.List; @@ -37,4 +38,13 @@ public interface IfsInventoryInitService { * @return 创建的HU ID列表 */ List createOtherInboundHandlingUnits(CreateHuRequestDto request); + + /** + * 批量创建HandlingUnit + *

功能说明:一次请求创建多个HU,每行数据创建一条HU

+ * + * @param request 批量创建HU请求,包含多个创建项 + * @return 创建的HU ID列表 + */ + List batchCreateHandlingUnits(BatchCreateHuRequestDto request); } diff --git a/src/main/java/com/gaotao/modules/warehouse/service/impl/IfsInventoryInitServiceImpl.java b/src/main/java/com/gaotao/modules/warehouse/service/impl/IfsInventoryInitServiceImpl.java index 460254f..2e7d211 100644 --- a/src/main/java/com/gaotao/modules/warehouse/service/impl/IfsInventoryInitServiceImpl.java +++ b/src/main/java/com/gaotao/modules/warehouse/service/impl/IfsInventoryInitServiceImpl.java @@ -10,11 +10,13 @@ import com.gaotao.modules.warehouse.dao.InventoryStockMapper; import com.gaotao.modules.warehouse.dao.WarehouseMapper; import com.gaotao.modules.warehouse.entity.InventoryStock; import com.gaotao.modules.warehouse.entity.dto.CreateHuRequestDto; +import com.gaotao.modules.warehouse.entity.dto.BatchCreateHuRequestDto; import com.gaotao.modules.warehouse.service.IfsInventoryInitService; import com.gaotao.modules.warehouse.service.InventoryStockService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import lombok.extern.slf4j.Slf4j; import java.math.BigDecimal; import java.util.ArrayList; @@ -24,6 +26,7 @@ import java.util.List; /** * IFS库存初始化服务实现类 */ +@Slf4j @Service public class IfsInventoryInitServiceImpl implements IfsInventoryInitService { @@ -49,6 +52,9 @@ public class IfsInventoryInitServiceImpl implements IfsInventoryInitService { @Override @Transactional public List createHandlingUnits(CreateHuRequestDto request) { + log.info("=== 开始创建HU === 包装数: {}, 单包装数量: {}, 最后HU数量: {}", + request.getPackageCount(), request.getPerPackageQty(), request.getLastPackageQty()); + List unitIds = new ArrayList<>(); // 查询IFS库存信息进行校验 InventoryStock ifsStock = warehouseMapper.selectIfsInventoryStock( @@ -59,8 +65,12 @@ public class IfsInventoryInitServiceImpl implements IfsInventoryInitService { request.getLocationId(), request.getWdr() ); - // 根据包装数创建多个HandlingUnit + + // 1. 先创建packageCount个完整HU for (int i = 0; i < request.getPackageCount(); i++) { + BigDecimal currentQty = request.getPerPackageQty(); + log.info("创建第 {} 个完整HU,数量: {}", i + 1, currentQty); + // 生成处理单元ID String unitId = handlingUnitIdGeneratorService.generateUnitId(request.getSite()); @@ -72,7 +82,7 @@ public class IfsInventoryInitServiceImpl implements IfsInventoryInitService { handlingUnit.setUnitTypeDb("ROLL"); handlingUnit.setPartNo(request.getPartNo()); handlingUnit.setPartDesc(request.getPartDesc()); - handlingUnit.setQty(request.getPerPackageQty()); + handlingUnit.setQty(currentQty); // 使用计算后的数量 handlingUnit.setBatchNo(request.getBatchNo()); handlingUnit.setLocationId(request.getLocationId()); handlingUnit.setWarehouseId("TEMP"); @@ -86,9 +96,10 @@ public class IfsInventoryInitServiceImpl implements IfsInventoryInitService { handlingUnit.setCreatedDate(new Date()); handlingUnit.setCreatedBy("SYSTEM"); handlingUnit.setSourceType("IFS_INIT"); - handlingUnit.setOriginalQty(request.getPerPackageQty()); + handlingUnit.setOriginalQty(currentQty); // 使用计算后的数量 handlingUnit.setReceiveDate(ifsStock.getManufactureDate()); handlingUnit.setHeight(request.getHeight()); + // 根据料号和单位计算长宽 BigDecimal width = null; BigDecimal length = null; @@ -107,8 +118,8 @@ public class IfsInventoryInitServiceImpl implements IfsInventoryInitService { } // length就是数量乘以1000再除以width - if (width!=null && width.compareTo(BigDecimal.ZERO) > 0) { - length = request.getPerPackageQty().multiply(BigDecimal.valueOf(1000)) + if (width != null && width.compareTo(BigDecimal.ZERO) > 0) { + length = currentQty.multiply(BigDecimal.valueOf(1000)) .divide(width, 2, java.math.RoundingMode.HALF_UP); } @@ -118,18 +129,92 @@ public class IfsInventoryInitServiceImpl implements IfsInventoryInitService { handlingUnit.setExpiredDate(ifsStock.getExpiredDate()); handlingUnit.setUmId(request.getUmid()); - // 保存HandlingUnit handlingUnitService.save(handlingUnit); unitIds.add(unitId); } - // 生成HU后,更新inventory_stock_ifs的print_qty字段 - // 计算总的打印数量(包装数 * 每包装数量) - Integer totalPrintQty = request.getPackageCount() * request.getPerPackageQty().intValue(); + // 2. 如果有余数,创建1个余数HU + if (request.getLastPackageQty() != null && request.getLastPackageQty().compareTo(BigDecimal.ZERO) > 0) { + BigDecimal remainderQty = request.getLastPackageQty(); + log.info("创建余数HU,数量: {}", remainderQty); + + // 生成处理单元ID + String unitId = handlingUnitIdGeneratorService.generateUnitId(request.getSite()); + // 创建HandlingUnit对象 + HandlingUnit handlingUnit = new HandlingUnit(); + handlingUnit.setUnitId(unitId); + handlingUnit.setSite(request.getSite()); + handlingUnit.setUnitType("ROLL"); + handlingUnit.setUnitTypeDb("ROLL"); + handlingUnit.setPartNo(request.getPartNo()); + handlingUnit.setPartDesc(request.getPartDesc()); + handlingUnit.setQty(remainderQty); // 使用余数数量 + handlingUnit.setBatchNo(request.getBatchNo()); + handlingUnit.setLocationId(request.getLocationId()); + handlingUnit.setWarehouseId("TEMP"); + handlingUnit.setWdr(request.getWdr()); + handlingUnit.setStatus("ACTIVE"); + handlingUnit.setStatusDb("ACTIVE"); + handlingUnit.setFreezeFlag("N"); + handlingUnit.setReserveFlag("N"); + handlingUnit.setMergedFlag("N"); + handlingUnit.setInStockFlag("Y"); + handlingUnit.setCreatedDate(new Date()); + handlingUnit.setCreatedBy("SYSTEM"); + handlingUnit.setSourceType("IFS_INIT"); + handlingUnit.setOriginalQty(remainderQty); + handlingUnit.setReceiveDate(ifsStock.getManufactureDate()); + handlingUnit.setHeight(request.getHeight()); + + // 根据料号和单位计算长宽 + BigDecimal width = null; + BigDecimal length = null; + String partNo = request.getPartNo(); + if (partNo != null && partNo.contains("-")) { + String[] parts = partNo.split("-"); + String suffix = parts[parts.length - 1]; + try { + int widthVal = Integer.parseInt(suffix); + width = BigDecimal.valueOf(widthVal); + } catch (NumberFormatException e) { + // 默认值处理 + } + } + + // length就是数量乘以1000再除以width + if (width != null && width.compareTo(BigDecimal.ZERO) > 0) { + length = remainderQty.multiply(BigDecimal.valueOf(1000)) + .divide(width, 2, java.math.RoundingMode.HALF_UP); + } + + handlingUnit.setWidth(width); + handlingUnit.setLength(length); + handlingUnit.setManufactureDate(ifsStock.getManufactureDate()); + handlingUnit.setExpiredDate(ifsStock.getExpiredDate()); + handlingUnit.setUmId(request.getUmid()); + + // 保存余数HandlingUnit + handlingUnitService.save(handlingUnit); + + unitIds.add(unitId); + + log.info("余数HU创建成功: unitId={}", unitId); + } + + // 生成HU后,更新inventory_stock_ifs的print_qty字段 + // 计算总的打印数量(完整HU的数量 + 余数HU的数量) + BigDecimal totalPrintQty = request.getPerPackageQty() + .multiply(BigDecimal.valueOf(request.getPackageCount())); + + if (request.getLastPackageQty() != null && request.getLastPackageQty().compareTo(BigDecimal.ZERO) > 0) { + totalPrintQty = totalPrintQty.add(request.getLastPackageQty()); + } + + log.info("总打印数量: {}", totalPrintQty); if (ifsStock == null) { throw new RuntimeException("未找到对应的IFS库存记录"); @@ -137,12 +222,12 @@ public class IfsInventoryInitServiceImpl implements IfsInventoryInitService { // 校验打印数量不能超过入库数量 if (ifsStock.getQtyOnHand() != null) { - Integer currentPrintQty = ifsStock.getPrintQty() != null ? ifsStock.getPrintQty().intValue() : 0; - int newPrintQty = currentPrintQty + totalPrintQty; - if (newPrintQty > ifsStock.getQtyOnHand().intValue()) { + BigDecimal currentPrintQty = ifsStock.getPrintQty() != null ? ifsStock.getPrintQty() : BigDecimal.ZERO; + BigDecimal newPrintQty = currentPrintQty.add(totalPrintQty); + if (newPrintQty.compareTo(ifsStock.getQtyOnHand()) > 0) { throw new RuntimeException(String.format( - "打印数量不能超过库存数量!当前已打印:%d,本次打印:%d,库存数量:%d", - currentPrintQty, totalPrintQty, ifsStock.getQtyOnHand().intValue())); + "打印数量不能超过库存数量!当前已打印:%s,本次打印:%s,库存数量:%s", + currentPrintQty, totalPrintQty, ifsStock.getQtyOnHand())); } } @@ -283,4 +368,147 @@ public class IfsInventoryInitServiceImpl implements IfsInventoryInitService { return unitIds; } + + /** + * @Author System + * @Description 批量创建HandlingUnit - 一次请求创建多个HU + * @Date 2025/01/14 + * @Param [BatchCreateHuRequestDto] + * @return List + **/ + @Override + @Transactional + public List batchCreateHandlingUnits(BatchCreateHuRequestDto request) { + log.info("=== 开始批量创建HU ==="); + log.info("批量创建HU数量: {}", request.getItems().size()); + + List allUnitIds = new ArrayList<>(); + + try { + // 逐条创建HU + for (int i = 0; i < request.getItems().size(); i++) { + BatchCreateHuRequestDto.BatchCreateHuItem item = request.getItems().get(i); + + log.info("正在创建第 {}/{} 个HU: 物料={}, 批次={}, 库位={}", + i + 1, request.getItems().size(), + item.getPartNo(), item.getBatchNo(), item.getLocationId()); + + // 查询IFS库存信息进行校验 + InventoryStock ifsStock = warehouseMapper.selectIfsInventoryStock( + item.getSite(), + item.getWarehouseId(), + item.getPartNo(), + item.getBatchNo(), + item.getLocationId(), + item.getWdr() + ); + + if (ifsStock == null) { + log.error("未找到IFS库存记录: site={}, partNo={}, batchNo={}, locationId={}", + item.getSite(), item.getPartNo(), item.getBatchNo(), item.getLocationId()); + throw new RuntimeException(String.format( + "未找到对应的IFS库存记录: 物料=%s, 批次=%s, 库位=%s", + item.getPartNo(), item.getBatchNo(), item.getLocationId())); + } + + // 生成处理单元ID + String unitId = handlingUnitIdGeneratorService.generateUnitId(item.getSite()); + + // 创建HandlingUnit对象 + HandlingUnit handlingUnit = new HandlingUnit(); + handlingUnit.setUnitId(unitId); + handlingUnit.setSite(item.getSite()); + handlingUnit.setUnitType("ROLL"); + handlingUnit.setUnitTypeDb("ROLL"); + handlingUnit.setPartNo(item.getPartNo()); + handlingUnit.setPartDesc(item.getPartDesc()); + handlingUnit.setQty(item.getQtyOnHand()); // HU数量使用库存数量 + handlingUnit.setBatchNo(item.getBatchNo()); // 使用每行自己的批次号 + handlingUnit.setLocationId(item.getLocationId()); + handlingUnit.setWarehouseId("TEMP"); + handlingUnit.setWdr(item.getWdr()); + handlingUnit.setStatus("ACTIVE"); + handlingUnit.setStatusDb("ACTIVE"); + handlingUnit.setFreezeFlag("N"); + handlingUnit.setReserveFlag("N"); + handlingUnit.setMergedFlag("N"); + handlingUnit.setInStockFlag("Y"); + handlingUnit.setCreatedDate(new Date()); + handlingUnit.setCreatedBy("SYSTEM"); + handlingUnit.setSourceType("IFS_INIT"); + handlingUnit.setOriginalQty(item.getQtyOnHand()); + handlingUnit.setReceiveDate(ifsStock.getManufactureDate()); + + // 根据料号和单位计算长宽 + BigDecimal width = null; + BigDecimal length = null; + + String partNo = item.getPartNo(); + if (partNo != null && partNo.contains("-")) { + // 如果料号带尾缀,比如70001234-0250,那么width就是250 + String[] parts = partNo.split("-"); + String suffix = parts[parts.length - 1]; + try { + int widthVal = Integer.parseInt(suffix); + width = BigDecimal.valueOf(widthVal); + } catch (NumberFormatException e) { + // 默认值处理 + log.warn("无法解析料号宽度: {}", partNo); + } + } + + // length就是数量乘以1000再除以width + if (width != null && width.compareTo(BigDecimal.ZERO) > 0) { + length = item.getQtyOnHand().multiply(BigDecimal.valueOf(1000)) + .divide(width, 2, java.math.RoundingMode.HALF_UP); + } + + handlingUnit.setWidth(width); + handlingUnit.setLength(length); + handlingUnit.setManufactureDate(ifsStock.getManufactureDate()); + handlingUnit.setExpiredDate(ifsStock.getExpiredDate()); + handlingUnit.setUmId(item.getUmid()); + + // 保存HandlingUnit + handlingUnitService.save(handlingUnit); + + allUnitIds.add(unitId); + + // 更新打印数量 + BigDecimal totalPrintQty = item.getQtyOnHand(); + + // 校验打印数量不能超过入库数量 + if (ifsStock.getQtyOnHand() != null) { + BigDecimal currentPrintQty = ifsStock.getPrintQty() != null ? ifsStock.getPrintQty() : BigDecimal.ZERO; + BigDecimal newPrintQty = currentPrintQty.add(totalPrintQty); + if (newPrintQty.compareTo(ifsStock.getQtyOnHand()) > 0) { + log.error("打印数量超过库存数量: 当前已打印={}, 本次打印={}, 库存数量={}", + currentPrintQty, totalPrintQty, ifsStock.getQtyOnHand()); + throw new RuntimeException(String.format( + "打印数量不能超过库存数量!当前已打印:%s,本次打印:%s,库存数量:%s", + currentPrintQty, totalPrintQty, ifsStock.getQtyOnHand())); + } + } + + warehouseMapper.updateIfsPrintQty( + item.getSite(), + item.getWarehouseId(), + item.getPartNo(), + item.getBatchNo(), + item.getLocationId(), + item.getWdr(), + totalPrintQty + ); + + log.info("HU创建成功: unitId={}", unitId); + } + + log.info("=== 批量创建HU完成 === 成功创建: {} 个", allUnitIds.size()); + return allUnitIds; + + } catch (Exception e) { + log.error("=== 批量创建HU失败 === 错误信息: {}", e.getMessage(), e); + throw new RuntimeException("批量创建HU失败: " + e.getMessage()); + } + } }