Browse Source

自动计算标签数,批量创建HU

master
han\hanst 10 months ago
parent
commit
574fdcb202
  1. 24
      src/main/java/com/gaotao/modules/warehouse/controller/IfsInventoryInitController.java
  2. 4
      src/main/java/com/gaotao/modules/warehouse/dao/WarehouseMapper.java
  3. 39
      src/main/java/com/gaotao/modules/warehouse/entity/dto/BatchCreateHuRequestDto.java
  4. 1
      src/main/java/com/gaotao/modules/warehouse/entity/dto/CreateHuRequestDto.java
  5. 10
      src/main/java/com/gaotao/modules/warehouse/service/IfsInventoryInitService.java
  6. 256
      src/main/java/com/gaotao/modules/warehouse/service/impl/IfsInventoryInitServiceImpl.java

24
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
* <p><b>功能说明</b>一次请求创建多个HU每行数据创建一条HU</p>
* <p><b>业务规则</b></p>
* <ul>
* <li>每行数据创建一条HU</li>
* <li>批次号使用每行自己的批次号</li>
* <li>HU数量使用库存数量qtyOnHand</li>
* </ul>
*
* @param request 批量创建HU请求
* @return 创建的HU ID列表
*/
@PostMapping("/batchCreateHandlingUnits")
public R batchCreateHandlingUnits(@RequestBody BatchCreateHuRequestDto request) {
try {
List<String> unitIds = ifsInventoryInitService.batchCreateHandlingUnits(request);
return R.ok().put("unitIds", unitIds).put("msg", "批量创建HU成功");
} catch (Exception e) {
return R.error("批量创建HandlingUnit失败: " + e.getMessage());
}
}
}

4
src/main/java/com/gaotao/modules/warehouse/dao/WarehouseMapper.java

@ -115,7 +115,7 @@ public interface WarehouseMapper extends BaseMapper<InventoryStock> {
* @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<InventoryStock> {
@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字段直接设置不是累加

39
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
*
* <p><b>功能说明</b>支持一次请求创建多个HU</p>
*
* @author System
* @since 2025-01-14
*/
@Data
public class BatchCreateHuRequestDto {
/**
* HU创建项列表
*/
private List<BatchCreateHuItem> 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数量
}
}

1
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")

10
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<String> createOtherInboundHandlingUnits(CreateHuRequestDto request);
/**
* 批量创建HandlingUnit
* <p><b>功能说明</b>一次请求创建多个HU每行数据创建一条HU</p>
*
* @param request 批量创建HU请求包含多个创建项
* @return 创建的HU ID列表
*/
List<String> batchCreateHandlingUnits(BatchCreateHuRequestDto request);
}

256
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<String> createHandlingUnits(CreateHuRequestDto request) {
log.info("=== 开始创建HU === 包装数: {}, 单包装数量: {}, 最后HU数量: {}",
request.getPackageCount(), request.getPerPackageQty(), request.getLastPackageQty());
List<String> 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<String>
**/
@Override
@Transactional
public List<String> batchCreateHandlingUnits(BatchCreateHuRequestDto request) {
log.info("=== 开始批量创建HU ===");
log.info("批量创建HU数量: {}", request.getItems().size());
List<String> 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());
}
}
}
Loading…
Cancel
Save