Browse Source

新品流程ok

master
常熟吴彦祖 2 weeks ago
parent
commit
acd1fb7a69
  1. 26
      src/main/java/com/xujie/modules/inspection/service/impl/InspectionRequestServiceImpl.java
  2. 58
      src/main/java/com/xujie/modules/order/service/Impl/PODetailServiceImpl.java
  3. 21
      src/main/java/com/xujie/modules/order/service/Impl/POHeaderServiceImpl.java
  4. 6
      src/main/java/com/xujie/modules/qms/service/impl/QcServiceImpl.java
  5. 1
      src/main/resources/mapper/order/POHeaderMapper.xml

26
src/main/java/com/xujie/modules/inspection/service/impl/InspectionRequestServiceImpl.java

@ -287,9 +287,12 @@ public class InspectionRequestServiceImpl extends ServiceImpl<InspectionRequestH
);
}
// 修改header状态
baseMapper.cancel(site, requestNo);
int headerUpdateCount = baseMapper.cancel(site, requestNo);
// 修改detail状态
inspectionRequestDetailMapper.cancel(site, requestNo);
int detailUpdateCount = inspectionRequestDetailMapper.cancel(site, requestNo);
if (headerUpdateCount == 0 || detailUpdateCount == 0) {
throw new RuntimeException("取消验货申请失败,header/detail状态未同步更新");
}
}
@Transactional(rollbackFor = Exception.class)
@ -413,10 +416,13 @@ public class InspectionRequestServiceImpl extends ServiceImpl<InspectionRequestH
validateInspectionTemplate(site, requestNos);
// 2. 修改头表状态为已确认
baseMapper.confirm(site, requestNo);
int headerUpdateCount = baseMapper.confirm(site, requestNo);
// 3. 修改detail状态为已确认
inspectionRequestDetailMapper.confirm(site, requestNo);
int detailUpdateCount = inspectionRequestDetailMapper.confirm(site, requestNo);
if (headerUpdateCount == 0 || detailUpdateCount == 0) {
throw new RuntimeException("确认验货申请失败,header/detail状态未同步更新");
}
}
@Transactional(rollbackFor = Exception.class)
@ -437,10 +443,13 @@ public class InspectionRequestServiceImpl extends ServiceImpl<InspectionRequestH
}
// 2. 修改头表状态为已下达
baseMapper.audit(site, requestNo);
int headerUpdateCount = baseMapper.audit(site, requestNo);
// 3. 修改detail状态为已下达
inspectionRequestDetailMapper.audit(site, requestNo);
int detailUpdateCount = inspectionRequestDetailMapper.audit(site, requestNo);
if (headerUpdateCount == 0 || detailUpdateCount == 0) {
throw new RuntimeException("审核验货申请失败,header/detail状态未同步更新");
}
}
@Override
@ -691,7 +700,10 @@ public class InspectionRequestServiceImpl extends ServiceImpl<InspectionRequestH
// 更新明细表状态为已排程单条处理
for (String requestNo : vo.getRequestNos()) {
inspectionRequestDetailMapper.schedule(site, requestNo);
int detailUpdateCount = inspectionRequestDetailMapper.schedule(site, requestNo);
if (detailUpdateCount == 0) {
throw new RuntimeException("排程失败:申请单" + requestNo + "未更新到明细状态");
}
}
}
private String getUserName() {

58
src/main/java/com/xujie/modules/order/service/Impl/PODetailServiceImpl.java

@ -112,10 +112,18 @@ public class PODetailServiceImpl extends ServiceImpl<PODetailMapper, PODetail> i
if(model.getId() != null){
// 编辑保存更新 c_edit修改时间 c_end_planner修改人
PODetail existing = baseMapper.selectById(model.getId());
if (existing == null) {
throw new RuntimeException("未找到订单明细,无法保存");
}
applyCrdOriOnUpdate(existing, model, poDetail);
poDetail.setEdit(currentTimeStr);
poDetail.setEndPlanner(currentUserName);
baseMapper.updateById(poDetail);
if (StringUtils.hasText(poDetail.getStatus())
&& !poDetail.getStatus().equals(existing.getStatus())) {
// 订单管理当前为 header/detail 1:1明细状态变化时必须同步头状态
syncPoHeaderStatus(existing.getSite(), existing.getOrderNo(), poDetail.getStatus());
}
} else {
// 新增保存设置 create_time创建时间
applyCrdOriOnCreate(model, poDetail);
@ -471,7 +479,6 @@ public class PODetailServiceImpl extends ServiceImpl<PODetailMapper, PODetail> i
}
validateNeedSubmitTestBeforeShip(existingDetail);
updatePoDetailStatus(existingDetail, "已发货");
syncPoHeaderStatusForShip(existingDetail);
}
private void validateNewProductAuditBeforeIssue(PODetail detail) {
@ -590,38 +597,43 @@ public class PODetailServiceImpl extends ServiceImpl<PODetailMapper, PODetail> i
update.setEdit(currentTimeStr);
update.setEndPlanner(currentUserName);
baseMapper.updateById(update);
return;
}
baseMapper.update(null, new LambdaUpdateWrapper<PODetail>()
.eq(PODetail::getOrderNo, existingDetail.getOrderNo())
.eq(PODetail::getSite, existingDetail.getSite())
.eq(PODetail::getItemNo, existingDetail.getItemNo())
.set(PODetail::getStatus, newStatus)
.set(PODetail::getEdit, currentTimeStr)
.set(PODetail::getEndPlanner, currentUserName));
} else {
baseMapper.update(null, new LambdaUpdateWrapper<PODetail>()
.eq(PODetail::getOrderNo, existingDetail.getOrderNo())
.eq(PODetail::getSite, existingDetail.getSite())
.eq(PODetail::getItemNo, existingDetail.getItemNo())
.set(PODetail::getStatus, newStatus)
.set(PODetail::getEdit, currentTimeStr)
.set(PODetail::getEndPlanner, currentUserName));
}
// 订单管理当前为 header/detail 1:1统一在状态变更后同步头状态
syncPoHeaderStatus(existingDetail.getSite(), existingDetail.getOrderNo(), newStatus);
}
/**
* @Description 发货动作后同步更新订单头状态
* @Title syncPoHeaderStatusForShip
* @param detail 当前被发货的订单行必须包含 siteorderNo
* @Description 按订单号同步 POHeader 状态
* @Title syncPoHeaderStatus
* @param site 站点
* @param orderNo 订单号
* @param status 目标状态
* @author rqrq
* @date 2026/07/23
* @date 2026/07/31
*
* 业务说明
* 1) 用户从明细行执行 shipped 除了 PODetail.status 变更为已发货POHeader.status 也必须同步为已发货
* 2) 此处只处理 shipped 场景不改变下达/关闭/打开等其他状态流转逻辑避免引入额外业务口径变化
* 1) 当前订单管理按 header/detail 1:1 维护任意明细状态变更都要同步头状态
* 2) 统一收口到该方法避免关闭/打开/下达/发货等动作出现状态不一致
* 3) 更新条件按 site + orderNo 精确命中保证仅影响当前订单头记录
*/
private void syncPoHeaderStatusForShip(PODetail detail) {
if (detail == null || !StringUtils.hasText(detail.getSite()) || !StringUtils.hasText(detail.getOrderNo())) {
private void syncPoHeaderStatus(String site, String orderNo, String status) {
if (!StringUtils.hasText(site)
|| !StringUtils.hasText(orderNo)
|| !StringUtils.hasText(status)) {
return;
}
poHeaderMapper.update(null, new LambdaUpdateWrapper<POHeader>()
.eq(POHeader::getSite, detail.getSite())
.eq(POHeader::getOrderNo, detail.getOrderNo())
.set(POHeader::getStatus, "已发货"));
.eq(POHeader::getSite, site)
.eq(POHeader::getOrderNo, orderNo)
.set(POHeader::getStatus, status));
}
@Override
@ -856,6 +868,7 @@ public class PODetailServiceImpl extends ServiceImpl<PODetailMapper, PODetail> i
|| model.getBuyer() != null
|| model.getCustomer() != null
|| model.getPoNo() != null
|| StringUtils.hasText(model.getStatus())
|| model.getDeparture() != null
|| model.getDestination() != null
|| model.getShipVia() != null
@ -876,6 +889,7 @@ public class PODetailServiceImpl extends ServiceImpl<PODetailMapper, PODetail> i
header.setBuyer(model.getBuyer());
header.setCustomer(model.getCustomer());
header.setPoNo(model.getPoNo());
header.setStatus(model.getStatus());
header.setDeparture(model.getDeparture());
header.setDestination(model.getDestination());
header.setShipVia(model.getShipVia());

21
src/main/java/com/xujie/modules/order/service/Impl/POHeaderServiceImpl.java

@ -2,11 +2,14 @@ package com.xujie.modules.order.service.Impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xujie.common.utils.PageUtils;
import com.xujie.modules.order.dao.PODetailMapper;
import com.xujie.modules.order.dao.POHeaderMapper;
import com.xujie.modules.order.entity.PODetail;
import com.xujie.modules.order.entity.POHeader;
import com.xujie.modules.order.service.Iface.IPOHeaderService;
import com.xujie.modules.srm.mapper.SrmSupplierMapper;
@ -18,6 +21,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.time.LocalDate;
import java.util.List;
@ -38,12 +42,29 @@ public class POHeaderServiceImpl extends ServiceImpl<POHeaderMapper, POHeader> i
@Autowired
private SrmSupplierMapper srmSupplierMapper;
@Autowired
private PODetailMapper poDetailMapper;
@Override
@Transactional
public void saveModel(POHeader model){
if(model.getId() != null){
POHeader existingHeader = baseMapper.selectById(model.getId());
if (existingHeader == null) {
throw new RuntimeException("订单头不存在,无法保存");
}
baseMapper.updateById(model);
if (StringUtils.hasText(model.getStatus())
&& !model.getStatus().equals(existingHeader.getStatus())
&& StringUtils.hasText(existingHeader.getSite())
&& StringUtils.hasText(existingHeader.getOrderNo())) {
// 订单管理当前按 header/detail 1:1 维护头状态变化必须同步到明细
poDetailMapper.update(null, new LambdaUpdateWrapper<PODetail>()
.eq(PODetail::getSite, existingHeader.getSite())
.eq(PODetail::getOrderNo, existingHeader.getOrderNo())
.set(PODetail::getStatus, model.getStatus()));
}
return;
}

6
src/main/java/com/xujie/modules/qms/service/impl/QcServiceImpl.java

@ -3768,11 +3768,15 @@ public class QcServiceImpl implements QcService {
try {
Integer poItemNo = Integer.valueOf(qcData.getPoItemNo());
// 回滚明细
inspectionRequestDetailMapper.rollbackInspectRequestDetail(
int rollbackCount = inspectionRequestDetailMapper.rollbackInspectRequestDetail(
qcData.getSite(),
qcData.getPoOrderNo(),
poItemNo
);
if (rollbackCount == 0) {
throw new RuntimeException("回滚验货明细失败,未命中明细记录: requestNo="
+ qcData.getPoOrderNo() + ", itemNo=" + poItemNo);
}
// 查询明细
List<InspectionRequestDetail> detailList =

1
src/main/resources/mapper/order/POHeaderMapper.xml

@ -162,6 +162,7 @@
<if test="buyer != null">buyer = #{buyer},</if>
<if test="customer != null">c_customer = #{customer},</if>
<if test="poNo != null">po_no = #{poNo},</if>
<if test="status != null and status != ''">status = #{status},</if>
<if test="departure != null">c_departure = #{departure},</if>
<if test="destination != null">c_destination = #{destination},</if>
<if test="shipVia != null">ship_via = #{shipVia},</if>

Loading…
Cancel
Save