|
|
|
@ -62,6 +62,7 @@ public class SampleProofTrackingServiceImpl implements SampleProofTrackingServic |
|
|
|
private static final String DEFAULT_PROCESS_CONFIG_BU = "*"; |
|
|
|
private static final String DELIVERY_PACKAGE_PROCESS_CODE = "deliveryPackage"; |
|
|
|
private static final String DELIVERY_PACKAGE_PROCESS_NAME = "Delivery&Package"; |
|
|
|
private static final int NPI_ID_THRESHOLD = 100000; |
|
|
|
|
|
|
|
/** |
|
|
|
* 工序定义兜底:当配置表未初始化或查询异常时,仍保持页面可用。 |
|
|
|
@ -598,6 +599,8 @@ public class SampleProofTrackingServiceImpl implements SampleProofTrackingServic |
|
|
|
throw new RuntimeException("创建项目信息失败,未返回项目ID"); |
|
|
|
} |
|
|
|
} |
|
|
|
// 复用 NPI 项目ID 时,必须同步补齐 tracking 项目主档,否则后续物料/打样会出现“仅创建打样主表”的断链。 |
|
|
|
ensureProjectTrackingRowExists(data.getProjectId(), data.getSite(), operateUser); |
|
|
|
|
|
|
|
Integer matchedProjectPartId = resolveExistingOneKeyProjectPartId(data); |
|
|
|
if (matchedProjectPartId != null) { |
|
|
|
@ -609,14 +612,41 @@ public class SampleProofTrackingServiceImpl implements SampleProofTrackingServic |
|
|
|
throw new RuntimeException("创建项目物料失败,未返回物料ID"); |
|
|
|
} |
|
|
|
} |
|
|
|
// 同步补齐 tracking 物料主档,确保列表关联字段、颜色判定与修改弹窗查询链路完整。 |
|
|
|
ensureProjectPartTrackingRowExists(data.getProjectId(), data.getProjectPartId(), data.getSite(), operateUser); |
|
|
|
// 打样单号来自 ERF 时,若 NPI 中已存在同项目/物料/打样单,需直接复用 NPI 打样ID,确保列表同步标绿。 |
|
|
|
Integer matchedProofingId = resolveExistingOneKeyProofingId(data); |
|
|
|
if (matchedProofingId != null) { |
|
|
|
// 对齐规则:命中 NPI 打样时,tracking.proofing_id 与 tracking.id 必须同时使用 NPI 打样ID。 |
|
|
|
data.setProofingId(matchedProofingId); |
|
|
|
data.setTrackingId(matchedProofingId); |
|
|
|
} else { |
|
|
|
data.setProofingId(null); |
|
|
|
data.setTrackingId(null); |
|
|
|
} |
|
|
|
|
|
|
|
try { |
|
|
|
sampleProofTrackingMapper.insertProofTracking(data); |
|
|
|
} catch (Exception e) { |
|
|
|
log.warn("一键创建插入追踪信息失败,尝试按项目物料创建空白追踪记录: projectId={}, projectPartId={}", |
|
|
|
data.getProjectId(), data.getProjectPartId(), e); |
|
|
|
boolean trackingPersisted = false; |
|
|
|
if (isTrackingRowExists(data.getTrackingId())) { |
|
|
|
// 并发场景下同一打样可能已被其他请求先创建,直接复用已存在 tracking 记录。 |
|
|
|
trackingPersisted = true; |
|
|
|
log.info("一键创建复用已存在 tracking 记录: trackingId={}, projectId={}, projectPartId={}", |
|
|
|
data.getTrackingId(), data.getProjectId(), data.getProjectPartId()); |
|
|
|
} |
|
|
|
if (data.getTrackingId() == null) { |
|
|
|
if (!trackingPersisted) { |
|
|
|
try { |
|
|
|
sampleProofTrackingMapper.insertProofTracking(data); |
|
|
|
trackingPersisted = true; |
|
|
|
} catch (Exception e) { |
|
|
|
log.warn("一键创建插入追踪信息失败,projectId={}, projectPartId={}, trackingId={}", |
|
|
|
data.getProjectId(), data.getProjectPartId(), data.getTrackingId(), e); |
|
|
|
trackingPersisted = isTrackingRowExists(data.getTrackingId()); |
|
|
|
} |
|
|
|
} |
|
|
|
if (!trackingPersisted && matchedProofingId != null) { |
|
|
|
// 命中 NPI 打样ID时不允许降级到临时 trackingId,否则会破坏“标绿即三表ID一致”规则。 |
|
|
|
throw new RuntimeException("NPI打样单已存在,但tracking主键未能对齐到NPI打样ID: " + matchedProofingId); |
|
|
|
} |
|
|
|
if (!trackingPersisted) { |
|
|
|
ProofTrackingData fallbackTracking = new ProofTrackingData(); |
|
|
|
fallbackTracking.setSite(data.getSite()); |
|
|
|
fallbackTracking.setProjectId(data.getProjectId()); |
|
|
|
@ -625,8 +655,9 @@ public class SampleProofTrackingServiceImpl implements SampleProofTrackingServic |
|
|
|
fallbackTracking.setUpdateBy(operateUser); |
|
|
|
sampleProofTrackingMapper.insertTrackingFromPart(fallbackTracking); |
|
|
|
data.setTrackingId(fallbackTracking.getTrackingId()); |
|
|
|
trackingPersisted = data.getTrackingId() != null; |
|
|
|
} |
|
|
|
if (data.getTrackingId() == null) { |
|
|
|
if (!trackingPersisted || data.getTrackingId() == null) { |
|
|
|
throw new RuntimeException("创建打样跟踪失败,未返回跟踪ID"); |
|
|
|
} |
|
|
|
// 业务要求:打样预计完成日期与 Delivery&Package 工序日期保持同步,避免同一记录出现双日期口径。 |
|
|
|
@ -1657,6 +1688,16 @@ public class SampleProofTrackingServiceImpl implements SampleProofTrackingServic |
|
|
|
if (isBlank(data.getProjectNo())) { |
|
|
|
return null; |
|
|
|
} |
|
|
|
Integer matchedNpiProjectId = sampleTrackingMapper.selectNpiProjectIdBySiteBuNoAndProjectNo( |
|
|
|
data.getSite(), |
|
|
|
data.getBuNo(), |
|
|
|
data.getProjectNo() |
|
|
|
); |
|
|
|
if (isNpiAlignedId(matchedNpiProjectId)) { |
|
|
|
log.info("一键创建命中 NPI 项目,优先复用 NPI 主档ID: site={}, buNo={}, projectNo={}, projectId={}", |
|
|
|
data.getSite(), data.getBuNo(), data.getProjectNo(), matchedNpiProjectId); |
|
|
|
return matchedNpiProjectId; |
|
|
|
} |
|
|
|
Integer matchedProjectId = sampleProofTrackingMapper.selectProjectInfoTrackingIdBySiteBuAndProjectNo( |
|
|
|
data.getSite(), |
|
|
|
data.getBuNo(), |
|
|
|
@ -1674,6 +1715,16 @@ public class SampleProofTrackingServiceImpl implements SampleProofTrackingServic |
|
|
|
if (data.getProjectId() == null || isBlank(data.getTestPartNo())) { |
|
|
|
return null; |
|
|
|
} |
|
|
|
Integer matchedNpiProjectPartId = sampleTrackingMapper.selectNpiProjectPartIdBySiteProjectAndPartNo( |
|
|
|
data.getSite(), |
|
|
|
data.getProjectId(), |
|
|
|
data.getTestPartNo() |
|
|
|
); |
|
|
|
if (isNpiAlignedId(matchedNpiProjectPartId)) { |
|
|
|
log.info("一键创建命中 NPI 项目物料,优先复用 NPI 物料ID: site={}, projectId={}, testPartNo={}, projectPartId={}", |
|
|
|
data.getSite(), data.getProjectId(), data.getTestPartNo(), matchedNpiProjectPartId); |
|
|
|
return matchedNpiProjectPartId; |
|
|
|
} |
|
|
|
Integer matchedProjectPartId = sampleProofTrackingMapper.selectProjectPartTrackingIdBySiteProjectAndPartNo( |
|
|
|
data.getSite(), |
|
|
|
data.getProjectId(), |
|
|
|
@ -1686,6 +1737,77 @@ public class SampleProofTrackingServiceImpl implements SampleProofTrackingServic |
|
|
|
return matchedProjectPartId; |
|
|
|
} |
|
|
|
|
|
|
|
private Integer resolveExistingOneKeyProofingId(ProofTrackingData data) { |
|
|
|
if (isBlank(data.getSite()) |
|
|
|
|| data.getProjectId() == null |
|
|
|
|| data.getProjectPartId() == null |
|
|
|
|| isBlank(data.getProofingNo())) { |
|
|
|
return null; |
|
|
|
} |
|
|
|
String normalizedProofingNo = data.getProofingNo().trim(); |
|
|
|
data.setProofingNo(normalizedProofingNo); |
|
|
|
Integer matchedNpiProofingId = sampleTrackingMapper.selectNpiProofingIdBySiteProjectPartAndProofingNo( |
|
|
|
data.getSite(), |
|
|
|
data.getProjectId(), |
|
|
|
data.getProjectPartId(), |
|
|
|
normalizedProofingNo |
|
|
|
); |
|
|
|
if (isNpiAlignedId(matchedNpiProofingId)) { |
|
|
|
log.info("一键创建命中 NPI 打样单,复用 NPI 打样ID: site={}, projectId={}, projectPartId={}, proofingNo={}, proofingId={}", |
|
|
|
data.getSite(), data.getProjectId(), data.getProjectPartId(), normalizedProofingNo, matchedNpiProofingId); |
|
|
|
return matchedNpiProofingId; |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
private boolean isNpiAlignedId(Integer idValue) { |
|
|
|
return idValue != null && idValue > 0 && idValue < NPI_ID_THRESHOLD; |
|
|
|
} |
|
|
|
|
|
|
|
private boolean isTrackingRowExists(Integer trackingId) { |
|
|
|
if (trackingId == null || trackingId <= 0) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
return sampleTrackingMapper.existsProofTrackingId(trackingId) != null; |
|
|
|
} |
|
|
|
|
|
|
|
private void ensureProjectTrackingRowExists(Integer projectId, String site, String operateUser) { |
|
|
|
if (projectId == null) { |
|
|
|
return; |
|
|
|
} |
|
|
|
Integer existedTrackingProjectId = sampleTrackingMapper.existsProjectInfoTrackingId(projectId); |
|
|
|
if (existedTrackingProjectId != null) { |
|
|
|
return; |
|
|
|
} |
|
|
|
int insertedRows = sampleProofTrackingMapper.insertProjectInfoTrackingFromNpi(projectId, operateUser); |
|
|
|
Integer recheckedTrackingProjectId = sampleTrackingMapper.existsProjectInfoTrackingId(projectId); |
|
|
|
if (recheckedTrackingProjectId == null) { |
|
|
|
throw new RuntimeException("项目主档未落地到 tracking 表,无法创建打样记录: projectId=" + projectId); |
|
|
|
} |
|
|
|
if (insertedRows > 0) { |
|
|
|
log.info("一键创建补齐 tracking 项目主档成功: site={}, projectId={}", site, projectId); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void ensureProjectPartTrackingRowExists(Integer projectId, Integer projectPartId, String site, String operateUser) { |
|
|
|
if (projectPartId == null) { |
|
|
|
return; |
|
|
|
} |
|
|
|
Integer existedTrackingProjectPartId = sampleTrackingMapper.existsProjectPartTrackingId(projectPartId); |
|
|
|
if (existedTrackingProjectPartId != null) { |
|
|
|
return; |
|
|
|
} |
|
|
|
int insertedRows = sampleProofTrackingMapper.insertProjectPartTrackingFromNpi(projectId, projectPartId, operateUser); |
|
|
|
Integer recheckedTrackingProjectPartId = sampleTrackingMapper.existsProjectPartTrackingId(projectPartId); |
|
|
|
if (recheckedTrackingProjectPartId == null) { |
|
|
|
throw new RuntimeException("项目物料主档未落地到 tracking 表,无法创建打样记录: projectPartId=" + projectPartId); |
|
|
|
} |
|
|
|
if (insertedRows > 0) { |
|
|
|
log.info("一键创建补齐 tracking 项目物料主档成功: site={}, projectId={}, projectPartId={}", |
|
|
|
site, projectId, projectPartId); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void validateOneKeyUpdateData(ProofTrackingData data) { |
|
|
|
// 业务要求:一键修改仅强制校验料号描述、PjM、Engineer,其它字段允许为空。 |
|
|
|
if (isBlank(data.getPartDesc())) { |
|
|
|
|