Browse Source

2025-10-14

箱清单的装箱优化
master
fengyuan_yang 5 months ago
parent
commit
96ee884c22
  1. 2
      src/main/java/com/gaotao/modules/boxManage/controller/BoxForNotificationController.java
  2. 2
      src/main/java/com/gaotao/modules/boxManage/dao/BoxForNotificationMapper.java
  3. 2
      src/main/java/com/gaotao/modules/boxManage/service/BoxForNotificationService.java
  4. 138
      src/main/java/com/gaotao/modules/boxManage/service/impl/BoxForNotificationServiceImpl.java
  5. 45
      src/main/resources/mapper/boxManage/BoxForNotificationMapper.xml

2
src/main/java/com/gaotao/modules/boxManage/controller/BoxForNotificationController.java

@ -141,7 +141,7 @@ public class BoxForNotificationController {
@PostMapping(value="/validateAndScanCaseRoll")
@ResponseBody
public R validateAndScanCaseRoll(@RequestBody SoReceiveCasesData data) {
SoReceiveCasesData rollInfo = srmSupplierService.validateAndScanCaseRoll(data);
List<SoReceiveCasesData> rollInfo = srmSupplierService.validateAndScanCaseRoll(data);
return R.ok().put("rollInfo", rollInfo);
}

2
src/main/java/com/gaotao/modules/boxManage/dao/BoxForNotificationMapper.java

@ -46,7 +46,7 @@ public interface BoxForNotificationMapper {
// 盒清单相关方法
List<SoReceiveCasesData> searchSoReceiveCasesData(SoReceiveCasesData data);
void deleteSoReceiveCasesData(SoReceiveCasesData data);
SoReceiveCasesData validateCaseRoll(@Param("site") String site, @Param("partNo") String partNo, @Param("rollNo") String rollNo, @Param("casesNo") String casesNo);
List<SoReceiveCasesData> validateCaseRoll(@Param("site") String site, @Param("partNo") String partNo, @Param("rollNo") String rollNo, @Param("casesNo") String casesNo);
void saveSoReceiveCases(SoReceiveCasesData data);
void updateStockParentRollType(@Param("rollNo") String rollNo, @Param("parentRollNo") String parentRollNo, @Param("parentRollType") String parentRollType, @Param("site") String site, @Param("buNo") String buNo);

2
src/main/java/com/gaotao/modules/boxManage/service/BoxForNotificationService.java

@ -28,7 +28,7 @@ public interface BoxForNotificationService {
// 盒清单相关方法
List<SoReceiveCasesData> searchSoReceiveCasesData(SoReceiveCasesData data);
void deleteSoReceiveCasesData(SoReceiveCasesData data);
SoReceiveCasesData validateAndScanCaseRoll(SoReceiveCasesData data);
List<SoReceiveCasesData> validateAndScanCaseRoll(SoReceiveCasesData data);
void saveCaseRollList(List<SoReceiveCasesData> dataList);
/**

138
src/main/java/com/gaotao/modules/boxManage/service/impl/BoxForNotificationServiceImpl.java

@ -122,53 +122,53 @@ public class BoxForNotificationServiceImpl implements BoxForNotificationService
throw new RuntimeException("卷不存在");
}
// 多个卷取第一个做校验
InventoryStock stock = stocks.get(0);
if(!"在库".equals(stock.getStatus())) {
throw new RuntimeException("卷状态不是在库,无法操作");
}
// 添加检查逻辑检查卷是否已经在其他箱子里
if (stock.getParentRollNo() != null && stock.getParentRollNo().startsWith("BOX")) {
throw new RuntimeException("卷已经在箱子:" + stock.getParentRollNo() + "中,请先取出");
}
List<OutboundNotificationDetailEntity> checkPartNo=boxForNotificationMapper.searchOutboundNotificationDetail(box.getSite(),box.getBuNo(),box.getOrderNo());
// 添加校验逻辑检查checkPartNo中是否至少有一行记录的partNo与卷的partNo相同
boolean partNoMatch = checkPartNo.stream()
.anyMatch(detail -> detail.getPartNo() != null && detail.getPartNo().equals(stock.getPartNo()));
for (InventoryStock stock : stocks) {
data.setFinalRollNo(stock.getRollNo());
// 添加检查逻辑检查卷是否已经在其他箱子里
if (stock.getParentRollNo() != null && stock.getParentRollNo().startsWith("BOX")) {
throw new RuntimeException("卷已经在箱子:" + stock.getParentRollNo() + "中,请先取出");
}
List<OutboundNotificationDetailEntity> checkPartNo=boxForNotificationMapper.searchOutboundNotificationDetail(box.getSite(),box.getBuNo(),box.getOrderNo());
// 添加校验逻辑检查checkPartNo中是否至少有一行记录的partNo与卷的partNo相同
boolean partNoMatch = checkPartNo.stream()
.anyMatch(detail -> detail.getPartNo() != null && detail.getPartNo().equals(stock.getPartNo()));
if (!partNoMatch) {
throw new RuntimeException("该卷的物料编号与销售发货单中的物料编号不匹配");
}
if(stock.getBatchNo()==null||"".equals(stock.getBatchNo())){
throw new RuntimeException("该卷的批次号为空,无法操作");
}
//---*批号的物料可以通吃
if(!"*".equals(stock.getBatchNo())) {
// 校验批次号只要有一行partNo和batchNo都匹配即可
boolean batchNoMatch = checkPartNo.stream()
.filter(detail -> detail.getPartNo() != null && detail.getPartNo().equals(stock.getPartNo()))
.anyMatch(detail -> detail.getOutBatchNo() != null && detail.getOutBatchNo().equals(stock.getBatchNo()));
if (!batchNoMatch) {
throw new RuntimeException("该卷的批次号与销售发货单中的批次号不匹配");
if (!partNoMatch) {
throw new RuntimeException("该卷的物料编号与销售发货单中的物料编号不匹配");
}
if(stock.getBatchNo()==null||"".equals(stock.getBatchNo())){
throw new RuntimeException("该卷的批次号为空,无法操作");
}
//---*批号的物料可以通吃
if(!"*".equals(stock.getBatchNo())) {
// 校验批次号只要有一行partNo和batchNo都匹配即可
boolean batchNoMatch = checkPartNo.stream()
.filter(detail -> detail.getPartNo() != null && detail.getPartNo().equals(stock.getPartNo()))
.anyMatch(detail -> detail.getOutBatchNo() != null && detail.getOutBatchNo().equals(stock.getBatchNo()));
if (!batchNoMatch) {
throw new RuntimeException("该卷的批次号与销售发货单中的批次号不匹配");
}
}
// 检查箱的仓库是否为空如果为空则更新为卷的仓库如果不为空则检查是否一致
if(box.getWareHouseID()==null||"".equals(box.getWareHouseID())){
boxForNotificationMapper.updateBoxWareHouse(data.getSite(),data.getBuNo(),data.getBoxNo(),stock.getWarehouseId());
}else if(!box.getWareHouseID().equals(stock.getWarehouseId())){
throw new RuntimeException("该卷的仓库与箱的仓库不一致");
}
// 改卷上级标签
boxForNotificationMapper.updateStockParentRollNo(data.getFinalRollNo(), data.getBoxNo(), data.getSite(), data.getBuNo());
SysUserEntity currentUser = (SysUserEntity) SecurityUtils.getSubject().getPrincipal();
data.setRollQty(stock.getQtyOnHand());
data.setReceivedBy(currentUser.getUsername());
data.setWareHouseID(stock.getWarehouseId());
data.setPartNo(stock.getPartNo());
// 3. 添加卷到箱子
boxForNotificationMapper.addBoxRoll(data);
boxForNotificationMapper.updateBoxRollQty(data.getSite(),data.getBuNo(),data.getBoxNo());
}
// 检查箱的仓库是否为空如果为空则更新为卷的仓库如果不为空则检查是否一致
if(box.getWareHouseID()==null||"".equals(box.getWareHouseID())){
boxForNotificationMapper.updateBoxWareHouse(data.getSite(),data.getBuNo(),data.getBoxNo(),stock.getWarehouseId());
}else if(!box.getWareHouseID().equals(stock.getWarehouseId())){
throw new RuntimeException("该卷的仓库与箱的仓库不一致");
}
//改卷上级标签
boxForNotificationMapper.updateStockParentRollNo(data.getFinalRollNo(), data.getBoxNo(), data.getSite(), data.getBuNo());
SysUserEntity currentUser = (SysUserEntity) SecurityUtils.getSubject().getPrincipal();
data.setRollQty(stock.getQtyOnHand());
data.setReceivedBy(currentUser.getUsername());
data.setWareHouseID(stock.getWarehouseId());
data.setPartNo(stock.getPartNo());
// 3. 添加卷到箱子
boxForNotificationMapper.addBoxRoll(data);
boxForNotificationMapper.updateBoxRollQty(data.getSite(),data.getBuNo(),data.getBoxNo());
}
@Override
@ -263,37 +263,26 @@ public class BoxForNotificationServiceImpl implements BoxForNotificationService
@Override
@Transactional
public SoReceiveCasesData validateAndScanCaseRoll(SoReceiveCasesData data) {
public List<SoReceiveCasesData> validateAndScanCaseRoll(SoReceiveCasesData data) {
// 参数校验
if (data == null || data.getSite() == null || data.getCasesNo() == null
|| data.getRollNo() == null || data.getPartNo() == null) {
throw new RuntimeException("参数不完整");
}
// 查询卷的信息并进行校验
SoReceiveCasesData rollInfo = boxForNotificationMapper.validateCaseRoll(
// 查询卷的信息并进行校验现在返回的是集合
List<SoReceiveCasesData> rollInfoList = boxForNotificationMapper.validateCaseRoll(
data.getSite(),
data.getPartNo(),
data.getRollNo(),
data.getCasesNo()
);
if (rollInfo == null) {
if (rollInfoList == null || rollInfoList.isEmpty()) {
throw new RuntimeException("未找到对应的卷信息,请检查卷标签和物料编码是否正确");
}
// 校验1: 检查状态是否为"在库"
if (!"在库".equals(rollInfo.getStatus())) {
throw new RuntimeException("该标签状态不是在库(当前状态:" + rollInfo.getStatus() + "),请检查");
}
// 校验2: 检查上级标签类型
if ("盒标签".equals(rollInfo.getParentRollType()) || "箱标签".equals(rollInfo.getParentRollType())) {
throw new RuntimeException("该标签已经装盒/装箱,不允许重复扫描");
}
// 校验3: 检查合约号码
// 需要查询出库单明细获取合约号进行比对
// 查询出库单明细获取合约号进行比对
List<OutboundNotificationDetailEntity> outboundDetails = boxForNotificationMapper.searchOutboundNotificationDetail(
data.getSite(),
data.getBuNo(),
@ -304,17 +293,30 @@ public class BoxForNotificationServiceImpl implements BoxForNotificationService
throw new RuntimeException("未找到对应的出库单明细");
}
// 检查是否有匹配的合约号只要有一行的合约号匹配即可
boolean batchMatched = outboundDetails.stream()
.filter(detail -> detail.getPartNo() != null && detail.getPartNo().equals(data.getPartNo()))
.anyMatch(detail -> detail.getOutBatchNo() != null && detail.getOutBatchNo().equals(rollInfo.getBatchNo()));
// 对每一条卷信息进行校验
for (SoReceiveCasesData rollInfo : rollInfoList) {
// 校验1: 检查状态是否为"在库"
if (!"在库".equals(rollInfo.getStatus())) {
throw new RuntimeException("标签 " + rollInfo.getRollNo() + " 状态不是在库(当前状态:" + rollInfo.getStatus() + "),请检查");
}
// 校验2: 检查上级标签类型
if ("盒标签".equals(rollInfo.getParentRollType()) || "箱标签".equals(rollInfo.getParentRollType())) {
throw new RuntimeException("标签 " + rollInfo.getRollNo() + " 已经装盒/装箱,不允许重复扫描");
}
// 校验3: 检查合约号码
boolean batchMatched = outboundDetails.stream()
.filter(detail -> detail.getPartNo() != null && detail.getPartNo().equals(data.getPartNo()))
.anyMatch(detail -> detail.getOutBatchNo() != null && detail.getOutBatchNo().equals(rollInfo.getBatchNo()));
if (!batchMatched) {
throw new RuntimeException("该标签合约号码(" + rollInfo.getBatchNo() + ")不符,请检查");
if (!batchMatched) {
throw new RuntimeException("标签 " + rollInfo.getRollNo() + " 合约号码(" + rollInfo.getBatchNo() + ")不符,请检查");
}
}
// 校验通过返回卷信息
return rollInfo;
// 校验通过返回卷信息列表
return rollInfoList;
}
@Override

45
src/main/resources/mapper/boxManage/BoxForNotificationMapper.xml

@ -71,7 +71,18 @@
where id=#{id}
</update>
<select id="selectByRollNo" resultType="com.gaotao.modules.inventoryStock.entity.InventoryStock">
SELECT *
SELECT
site,
bu_no,
roll_no,
parent_roll_no,
parent_roll_type,
part_no,
warehouse_id,
location_id,
batch_no,
status,
qty_on_hand
FROM inventory_stock
WHERE roll_no = #{rollNo}
AND site = #{site}
@ -79,23 +90,37 @@
</select>
<select id="selectByRollNo2" resultType="com.gaotao.modules.inventoryStock.entity.InventoryStock">
SELECT *
SELECT
site,
bu_no,
roll_no,
parent_roll_no,
parent_roll_type,
part_no,
warehouse_id,
location_id,
batch_no,
status,
qty_on_hand
FROM inventory_stock
WHERE parent_roll_no = #{rollNo}
AND site = #{site}
AND bu_no = #{buNo}
and status='在库' AND COALESCE(parent_roll_type, '*') NOT IN ('箱标签')
</select>
<update id="updateStockParentRollNo">
UPDATE inventory_stock
SET parent_roll_no = #{parentRollNo}
SET parent_roll_no = #{parentRollNo} , parent_roll_type = '箱标签'
WHERE roll_no = #{rollNo}
AND site = #{site}
AND bu_no = #{buNo}
</update>
<insert id="addBoxRoll">
insert into so_receive_box_rolls(site,box_no,final_roll_no,roll_qty,received_by,received_date,WareHouseID,part_no,bu_no)
values(#{site},#{boxNo},#{finalRollNo},#{rollQty},#{receivedBy},GetDate(),#{wareHouseID},#{partNo},#{buNo})
insert into so_receive_box_rolls
(site,box_no,final_roll_no,roll_qty,received_by,received_date,WareHouseID,part_no,bu_no)
values
(#{site},#{boxNo},#{finalRollNo},#{rollQty},#{receivedBy},GetDate(),#{wareHouseID},#{partNo},#{buNo})
</insert>
<update id="updateBoxRollQty">
@ -194,7 +219,7 @@
AND a.part_no = b.PartNo
WHERE
a.site = #{site}
AND a.roll_no = #{rollNo}
AND a.parent_roll_no = #{rollNo}
AND a.part_no = #{partNo}
</select>
@ -246,8 +271,8 @@
a.order_status as orderStatus,
a.customer_id as customerId,
c.customerName,
a.related_order_no as relatedOrderNo,
a.related_order_line_no as relatedOrderLineNo,
<!-- a.related_order_no as relatedOrderNo,-->
<!-- a.related_order_line_no as relatedOrderLineNo,-->
a.required_outbound_date as requiredOutboundDate,
a.remarks,
a.erp_order_no as erpOrderNo,
@ -281,8 +306,8 @@
b.out_warehouse as detailOutWarehouse,
b.out_batch_no as outBatchNo,
b.order_qty as orderQty,
b.related_order_no as detailRelatedOrderNo,
b.related_order_line_no as detailRelatedOrderLineNo,
b.related_order_no as relatedOrderNo,
b.related_order_line_no as relatedOrderLineNo,
<!-- 已扫描数量和未扫描数量 -->
ISNULL(SUM(e.roll_qty), 0) as rollQty,
CASE WHEN b.required_qty - ISNULL(SUM(e.roll_qty), 0) > 0

Loading…
Cancel
Save