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
+ * 业务规则:
+ *
+ * - 每行数据创建一条HU
+ * - 批次号使用每行自己的批次号
+ * - HU数量使用库存数量(qtyOnHand)
+ *
+ *
+ * @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());
+ }
+ }
}