fix: retain scanned carton traceability in measurement drafts

This commit is contained in:
2026-09-02 17:57:35 +08:00
parent 2a0f942234
commit 6296f032f0
6 changed files with 155 additions and 12 deletions
@@ -14,8 +14,10 @@ import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
@@ -71,6 +73,7 @@ public class MeasurementBatchService {
throw concurrentModification();
}
}
preserveScannedTraceability(command, measurement, calculatedItems);
calculatedItems.forEach(item -> {
item.setTenantId(command.tenantId());
item.setMeasurementId(measurement.getId());
@@ -79,6 +82,39 @@ public class MeasurementBatchService {
return measurement;
}
/**
* 人工补录会整批替换可编辑测量项,但不能抹掉同一项已冻结的扫码身份与设备取证。
* 只按入库货物明细和明细号精确匹配,避免把一个箱码猜测性地复制给其他测量项。
*/
private void preserveScannedTraceability(MeasurementBatchCommand command,
InboundMeasurementEntity measurement,
List<InboundMeasurementItemEntity> replacement) {
if (command.measurementId() == null || replacement.isEmpty()) {
return;
}
Map<String, InboundMeasurementItemEntity> scannedByItem = new HashMap<>();
for (InboundMeasurementItemEntity existing : repository.listItems(command.tenantId(), measurement.getId())) {
if (existing.getBoxCode() != null && !existing.getBoxCode().isBlank()) {
scannedByItem.put(itemKey(existing.getInboundDetailId(), existing.getItemNo()), existing);
}
}
for (InboundMeasurementItemEntity item : replacement) {
InboundMeasurementItemEntity scanned = scannedByItem.get(itemKey(item.getInboundDetailId(), item.getItemNo()));
if (scanned == null) {
continue;
}
item.setExternalDetailNo(scanned.getExternalDetailNo());
item.setBoxCode(scanned.getBoxCode());
item.setScannedShipmentId(scanned.getScannedShipmentId());
item.setMachineNo(scanned.getMachineNo());
item.setDeviceMeasuredAt(scanned.getDeviceMeasuredAt());
}
}
private String itemKey(Long inboundDetailId, String itemNo) {
return String.valueOf(inboundDetailId) + ':' + itemNo;
}
private void validateSource(MeasurementBatchCommand command) {
if (!SOURCE_MANUAL.equals(command.sourceType()) && !SOURCE_THIRD_PARTY.equals(command.sourceType())) {
throw new BizException(ResultCode.BAD_REQUEST, "测量数据来源不支持");