|
|
|
@ -180,7 +180,7 @@ public class InspectionRequestServiceImpl extends ServiceImpl<InspectionRequestH |
|
|
|
// 4.1 生成Sub |
|
|
|
for (InspectionRequestItemVO item : subList) { |
|
|
|
// 查询当前PO明细的待验货数量信息 |
|
|
|
java.util.Map<String, Object> poInfo = poDetailMapper.getPoDetailInspectInfo( |
|
|
|
Map<String, Object> poInfo = poDetailMapper.getPoDetailInspectInfo( |
|
|
|
site, item.getOrderNo(), item.getItemNo()); |
|
|
|
|
|
|
|
int updateCount = poDetailMapper.lockInspectQty( |
|
|
|
@ -279,6 +279,271 @@ public class InspectionRequestServiceImpl extends ServiceImpl<InspectionRequestH |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@Transactional(rollbackFor = Exception.class) |
|
|
|
@Override |
|
|
|
public void addDetails(InspectionRequestAddDetailVO vo) { |
|
|
|
if (vo == null || !StringUtils.hasText(vo.getRequestNo())) { |
|
|
|
throw new RuntimeException("申请单号不能为空"); |
|
|
|
} |
|
|
|
if (vo.getItems() == null || vo.getItems().isEmpty()) { |
|
|
|
throw new RuntimeException("明细列表不能为空"); |
|
|
|
} |
|
|
|
|
|
|
|
String site = vo.getSite(); |
|
|
|
if (!StringUtils.hasText(site)) { |
|
|
|
SysUserEntity user = (SysUserEntity) SecurityUtils.getSubject().getPrincipal(); |
|
|
|
site = user.getSite(); |
|
|
|
} |
|
|
|
String requestNo = vo.getRequestNo().trim(); |
|
|
|
|
|
|
|
// 1. 校验头表是否存在 |
|
|
|
InspectionRequestHeader header = baseMapper.selectByRequestNo(site, requestNo); |
|
|
|
if (header == null) { |
|
|
|
throw new RuntimeException("检验申请单不存在: " + requestNo); |
|
|
|
} |
|
|
|
|
|
|
|
// 2. 只有草稿和待审核状态允许新增明细 |
|
|
|
if (!"Draft".equals(header.getStatusDb()) && !"Confirmed".equals(header.getStatusDb())) { |
|
|
|
throw new RuntimeException("只有草稿和待审核状态的验货申请允许新增明细,当前状态:" + header.getStatus()); |
|
|
|
} |
|
|
|
|
|
|
|
log.info("开始新增验货申请明细: site={}, requestNo={}", site, requestNo); |
|
|
|
|
|
|
|
// 3. 获取当前最大的itemNo,用于生成新的行号 |
|
|
|
Integer maxItemNo = inspectionRequestDetailMapper.selectMaxItemNo(site, requestNo); |
|
|
|
int requestItemNo = (maxItemNo == null ? 0 : maxItemNo) + 1; |
|
|
|
|
|
|
|
// 4. 按真正的PO明细(orderNo + itemNo)分组,相同的PO明细累加数量 |
|
|
|
// 如果itemNo为null,则使用poItemNo |
|
|
|
Map<String, List<InspectionRequestItemVO>> groupMap = |
|
|
|
vo.getItems() |
|
|
|
.stream() |
|
|
|
.peek(item -> { |
|
|
|
// 如果itemNo为null,使用poItemNo作为备选 |
|
|
|
if (item.getItemNo() == null && item.getPoItemNo() != null) { |
|
|
|
item.setItemNo(item.getPoItemNo()); |
|
|
|
} |
|
|
|
}) |
|
|
|
.collect(Collectors.groupingBy( |
|
|
|
item -> item.getOrderNo() + "|" + item.getItemNo(), |
|
|
|
LinkedHashMap::new, |
|
|
|
Collectors.toList() |
|
|
|
)); |
|
|
|
|
|
|
|
// 5. 遍历分组,生成Detail和Sub |
|
|
|
for (Map.Entry<String, List<InspectionRequestItemVO>> entry : groupMap.entrySet()) { |
|
|
|
List<InspectionRequestItemVO> subList = entry.getValue(); |
|
|
|
InspectionRequestItemVO firstItem = subList.get(0); |
|
|
|
|
|
|
|
// 计算该PO明细的总数量(累加) |
|
|
|
BigDecimal totalQty = BigDecimal.ZERO; |
|
|
|
for (InspectionRequestItemVO item : subList) { |
|
|
|
totalQty = totalQty.add(item.getQty()); |
|
|
|
} |
|
|
|
|
|
|
|
// 使用第一条数据的其他字段,但数量用累加后的总数 |
|
|
|
InspectionRequestItemVO mergedItem = new InspectionRequestItemVO(); |
|
|
|
mergedItem.setOrderNo(firstItem.getOrderNo()); |
|
|
|
mergedItem.setItemNo(firstItem.getItemNo()); |
|
|
|
mergedItem.setOrderRef1(firstItem.getOrderRef1()); |
|
|
|
mergedItem.setOrderRef2(firstItem.getOrderRef2()); |
|
|
|
mergedItem.setPartNo(firstItem.getPartNo()); |
|
|
|
mergedItem.setQty(totalQty); // 使用累加后的数量 |
|
|
|
mergedItem.setShipMethod(firstItem.getShipMethod()); |
|
|
|
mergedItem.setCrd(firstItem.getCrd()); |
|
|
|
|
|
|
|
// 查询当前PO明细的待验货数量信息 |
|
|
|
java.util.Map<String, Object> poInfo = poDetailMapper.getPoDetailInspectInfo( |
|
|
|
site, mergedItem.getOrderNo(), mergedItem.getItemNo()); |
|
|
|
|
|
|
|
// 锁定验货数量(使用累加后的总数量) |
|
|
|
int updateCount = poDetailMapper.lockInspectQty( |
|
|
|
site, |
|
|
|
mergedItem.getOrderNo(), |
|
|
|
mergedItem.getItemNo(), |
|
|
|
mergedItem.getQty() |
|
|
|
); |
|
|
|
|
|
|
|
if (updateCount == 0) { |
|
|
|
log.error("锁定验货数量失败: orderNo={}, itemNo={}, qty={}", |
|
|
|
mergedItem.getOrderNo(), mergedItem.getItemNo(), mergedItem.getQty()); |
|
|
|
throw new RuntimeException( |
|
|
|
"PO:" + mergedItem.getOrderNo() |
|
|
|
+ " 行:" + mergedItem.getItemNo() |
|
|
|
+ " 待验货数量不足" |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
// 保存Sub |
|
|
|
InspectionRequestDetailSub sub = new InspectionRequestDetailSub(); |
|
|
|
sub.setSite(site); |
|
|
|
sub.setRequestNo(requestNo); |
|
|
|
sub.setItemNo(requestItemNo); |
|
|
|
sub.setPoNo(mergedItem.getOrderNo()); |
|
|
|
sub.setPoItemNo(mergedItem.getItemNo()); |
|
|
|
sub.setPartNo(mergedItem.getPartNo()); |
|
|
|
sub.setQty(mergedItem.getQty()); // 使用累加后的数量 |
|
|
|
sub.setOrderRef1(mergedItem.getOrderRef1()); |
|
|
|
sub.setOrderRef2(mergedItem.getOrderRef2()); |
|
|
|
sub.setShipMothod(mergedItem.getShipMethod()); |
|
|
|
sub.setCrd(mergedItem.getCrd()); |
|
|
|
|
|
|
|
// 计算数量是否变更 |
|
|
|
Object qtyObj = poInfo.get("waitInspectQty"); |
|
|
|
BigDecimal originQty = qtyObj == null ? BigDecimal.ZERO : new BigDecimal(qtyObj.toString()); |
|
|
|
BigDecimal reqQty = mergedItem.getQty() == null ? BigDecimal.ZERO : mergedItem.getQty(); |
|
|
|
boolean isChanged = reqQty.compareTo(originQty) != 0; |
|
|
|
sub.setIsChanged(isChanged ? "Y" : "N"); |
|
|
|
|
|
|
|
inspectionRequestDetailSubMapper.insert(sub); |
|
|
|
|
|
|
|
// 5.2 保存Detail汇总 |
|
|
|
InspectionRequestDetail detail = new InspectionRequestDetail(); |
|
|
|
detail.setSite(site); |
|
|
|
detail.setRequestNo(requestNo); |
|
|
|
detail.setItemNo(requestItemNo); |
|
|
|
detail.setOrderRef1(mergedItem.getOrderRef1()); |
|
|
|
detail.setPartNo(mergedItem.getPartNo()); |
|
|
|
detail.setQty(totalQty); // 使用累加后的数量 |
|
|
|
detail.setStatus("草稿"); |
|
|
|
detail.setStatusDb("Draft"); |
|
|
|
inspectionRequestDetailMapper.insert(detail); |
|
|
|
|
|
|
|
requestItemNo++; |
|
|
|
} |
|
|
|
|
|
|
|
log.info("新增验货申请明细完成: site={}, requestNo={}, 新增明细数量={}", |
|
|
|
site, requestNo, vo.getItems().size()); |
|
|
|
} |
|
|
|
|
|
|
|
@Transactional(rollbackFor = Exception.class) |
|
|
|
@Override |
|
|
|
public void editDetails(InspectionRequestEditVO vo) { |
|
|
|
if (vo == null || !StringUtils.hasText(vo.getRequestNo())) { |
|
|
|
throw new RuntimeException("申请单号不能为空"); |
|
|
|
} |
|
|
|
if (vo.getItems() == null || vo.getItems().isEmpty()) { |
|
|
|
throw new RuntimeException("明细列表不能为空"); |
|
|
|
} |
|
|
|
|
|
|
|
String site = vo.getSite(); |
|
|
|
if (!StringUtils.hasText(site)) { |
|
|
|
SysUserEntity user = (SysUserEntity) SecurityUtils.getSubject().getPrincipal(); |
|
|
|
site = user.getSite(); |
|
|
|
} |
|
|
|
String requestNo = vo.getRequestNo().trim(); |
|
|
|
|
|
|
|
// 1. 校验头表是否存在 |
|
|
|
InspectionRequestHeader header = baseMapper.selectByRequestNo(site, requestNo); |
|
|
|
if (header == null) { |
|
|
|
throw new RuntimeException("检验申请单不存在: " + requestNo); |
|
|
|
} |
|
|
|
|
|
|
|
// 2. 只有草稿和待审核状态允许编辑明细 |
|
|
|
if (!"Draft".equals(header.getStatusDb()) && !"Confirmed".equals(header.getStatusDb())) { |
|
|
|
throw new RuntimeException("只有草稿和待审核状态的验货申请允许编辑明细,当前状态:" + header.getStatus()); |
|
|
|
} |
|
|
|
|
|
|
|
log.info("开始编辑验货申请明细: site={}, requestNo={}", site, requestNo); |
|
|
|
|
|
|
|
// 3. 回滚原明细数量并删除 |
|
|
|
List<InspectionRequestDetailSub> oldSubList = |
|
|
|
inspectionRequestDetailSubMapper.selectByRequestNo(site, requestNo); |
|
|
|
|
|
|
|
for (InspectionRequestDetailSub sub : oldSubList) { |
|
|
|
int count = poDetailMapper.rollbackInspectQty( |
|
|
|
site, |
|
|
|
sub.getPoNo(), |
|
|
|
sub.getPoItemNo(), |
|
|
|
sub.getQty() |
|
|
|
); |
|
|
|
|
|
|
|
if (count == 0) { |
|
|
|
throw new RuntimeException( |
|
|
|
"回退PO待验货数量失败:" + sub.getPoNo() |
|
|
|
+ "-" + sub.getPoItemNo() |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 4. 删除原有明细记录 |
|
|
|
int subDeleteCount = inspectionRequestDetailSubMapper.deleteByRequestNo(site, requestNo); |
|
|
|
int detailDeleteCount = inspectionRequestDetailMapper.deleteByRequestNo(site, requestNo); |
|
|
|
|
|
|
|
log.info("删除原有明细完成: subDeleteCount={}, detailDeleteCount={}", subDeleteCount, detailDeleteCount); |
|
|
|
|
|
|
|
// 5. 插入新明细并锁定数量(不复用addDetails,避免分组合并) |
|
|
|
int requestItemNo = 1; |
|
|
|
for (InspectionRequestItemVO item : vo.getItems()) { |
|
|
|
// 如果itemNo为null,使用poItemNo作为备选 |
|
|
|
if (item.getItemNo() == null && item.getPoItemNo() != null) { |
|
|
|
item.setItemNo(item.getPoItemNo()); |
|
|
|
} |
|
|
|
|
|
|
|
// 查询当前PO明细的待验货数量信息 |
|
|
|
java.util.Map<String, Object> poInfo = poDetailMapper.getPoDetailInspectInfo( |
|
|
|
site, item.getOrderNo(), item.getItemNo()); |
|
|
|
|
|
|
|
// 锁定验货数量 |
|
|
|
int updateCount = poDetailMapper.lockInspectQty( |
|
|
|
site, |
|
|
|
item.getOrderNo(), |
|
|
|
item.getItemNo(), |
|
|
|
item.getQty() |
|
|
|
); |
|
|
|
|
|
|
|
if (updateCount == 0) { |
|
|
|
log.error("锁定验货数量失败: orderNo={}, itemNo={}, qty={}", |
|
|
|
item.getOrderNo(), item.getItemNo(), item.getQty()); |
|
|
|
throw new RuntimeException( |
|
|
|
"PO:" + item.getOrderNo() |
|
|
|
+ " 行:" + item.getItemNo() |
|
|
|
+ " 待验货数量不足" |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
// 保存Sub |
|
|
|
InspectionRequestDetailSub sub = new InspectionRequestDetailSub(); |
|
|
|
sub.setSite(site); |
|
|
|
sub.setRequestNo(requestNo); |
|
|
|
sub.setItemNo(requestItemNo); |
|
|
|
sub.setPoNo(item.getOrderNo()); |
|
|
|
sub.setPoItemNo(item.getItemNo()); |
|
|
|
sub.setPartNo(item.getPartNo()); |
|
|
|
sub.setQty(item.getQty()); |
|
|
|
sub.setOrderRef1(item.getOrderRef1()); |
|
|
|
sub.setOrderRef2(item.getOrderRef2()); |
|
|
|
sub.setShipMothod(item.getShipMethod()); |
|
|
|
sub.setCrd(item.getCrd()); |
|
|
|
|
|
|
|
// 计算数量是否变更 |
|
|
|
Object qtyObj = poInfo.get("waitInspectQty"); |
|
|
|
BigDecimal originQty = qtyObj == null ? BigDecimal.ZERO : new BigDecimal(qtyObj.toString()); |
|
|
|
BigDecimal reqQty = item.getQty() == null ? BigDecimal.ZERO : item.getQty(); |
|
|
|
boolean isChanged = reqQty.compareTo(originQty) != 0; |
|
|
|
sub.setIsChanged(isChanged ? "Y" : "N"); |
|
|
|
|
|
|
|
inspectionRequestDetailSubMapper.insert(sub); |
|
|
|
|
|
|
|
// 保存Detail汇总 |
|
|
|
InspectionRequestDetail detail = new InspectionRequestDetail(); |
|
|
|
detail.setSite(site); |
|
|
|
detail.setRequestNo(requestNo); |
|
|
|
detail.setItemNo(requestItemNo); |
|
|
|
detail.setOrderRef1(item.getOrderRef1()); |
|
|
|
detail.setPartNo(item.getPartNo()); |
|
|
|
detail.setQty(item.getQty()); |
|
|
|
detail.setStatus("草稿"); |
|
|
|
detail.setStatusDb("Draft"); |
|
|
|
inspectionRequestDetailMapper.insert(detail); |
|
|
|
|
|
|
|
requestItemNo++; |
|
|
|
} |
|
|
|
|
|
|
|
log.info("编辑验货申请明细完成: site={}, requestNo={}, 新明细数量={}", |
|
|
|
site, requestNo, vo.getItems().size()); |
|
|
|
} |
|
|
|
|
|
|
|
@Transactional(rollbackFor = Exception.class) |
|
|
|
@Override |
|
|
|
public void cancel(String requestNo) { |
|
|
|
|