fix(firstleg): sequence child inbound codes

This commit is contained in:
2026-08-10 20:18:53 +08:00
parent 4749bd3bc1
commit b1ca37699f
2 changed files with 24 additions and 11 deletions
@@ -165,16 +165,18 @@ public class PdaPickSettlementService {
long remainderChildId = childPackageCount > 0 ? IdWorker.getId() : 0L; long remainderChildId = childPackageCount > 0 ? IdWorker.getId() : 0L;
long batchId = IdWorker.getId(); long batchId = IdWorker.getId();
String idempotencyKey = "pda-task-" + taskId; String idempotencyKey = "pda-task-" + taskId;
String childCode = childInboundCode(parent.inboundCode(), remainderChildId == 0 ? loadedChildId : remainderChildId);
int parentVersion = root.version() == null ? 0 : root.version(); int parentVersion = root.version() == null ? 0 : root.version();
int sequence = splits.nextSplitSequence(parent.tenantId(), rootInboundId); int sequence = splits.nextSplitSequence(parent.tenantId(), rootInboundId);
String loadedChildCode = childInboundCode(root.inboundCode(), sequence);
String remainderChildCode = childPackageCount > 0
? childInboundCode(root.inboundCode(), sequence + 1) : null;
requireAffected(splits.cloneChildWithPurpose(parent.tenantId(), rootInboundId, rootInboundId, loadedChildId, requireAffected(splits.cloneChildWithPurpose(parent.tenantId(), rootInboundId, rootInboundId, loadedChildId,
orderSplit.loadedChild().orderId(), orderSplit.loadedChild().orderNo(), orderSplit.loadedChild().orderId(), orderSplit.loadedChild().orderNo(),
childInboundCode(parent.inboundCode(), loadedChildId), pickedPackageCount, sequence, "LOADED", operatorId, operatorName), "实装子入库单"); loadedChildCode, pickedPackageCount, sequence, "LOADED", operatorId, operatorName), "实装子入库单");
if (remainderChildId != 0L) { if (remainderChildId != 0L) {
requireAffected(splits.cloneChildWithPurpose(parent.tenantId(), rootInboundId, rootInboundId, remainderChildId, requireAffected(splits.cloneChildWithPurpose(parent.tenantId(), rootInboundId, rootInboundId, remainderChildId,
orderSplit.remainderChild().orderId(), orderSplit.remainderChild().orderNo(), orderSplit.remainderChild().orderId(), orderSplit.remainderChild().orderNo(),
childCode, childPackageCount, sequence + 1, "REMAINDER", operatorId, operatorName), "余量子入库单"); remainderChildCode, childPackageCount, sequence + 1, "REMAINDER", operatorId, operatorName), "余量子入库单");
} }
requireAffected(splits.insertBatchWithChildren(batchId, parent.tenantId(), rootInboundId, operationId, parentInboundId, requireAffected(splits.insertBatchWithChildren(batchId, parent.tenantId(), rootInboundId, operationId, parentInboundId,
idempotencyKey, parentVersion, parentAvailable, loadedChildId, remainderChildId == 0L ? null : remainderChildId, idempotencyKey, parentVersion, parentAvailable, loadedChildId, remainderChildId == 0L ? null : remainderChildId,
@@ -242,7 +244,9 @@ public class PdaPickSettlementService {
allocations.markTransferred(parent.tenantId(), parentInboundId, confirmedAllocations, allocations.markTransferred(parent.tenantId(), parentInboundId, confirmedAllocations,
releasedReservationIds); releasedReservationIds);
allocations.markReleased(parent.tenantId(), parentInboundId, releasedReservationIds); allocations.markReleased(parent.tenantId(), parentInboundId, releasedReservationIds);
settleWarehouseResources(parentInboundId, remainderChildId, childCode, taskId, operatorId, operatorName, settleWarehouseResources(parentInboundId, remainderChildId,
remainderChildCode == null ? loadedChildCode : remainderChildCode,
taskId, operatorId, operatorName,
warehouseId, parentAvailable, childPackageCount, releasedReservationIds, transferItems); warehouseId, parentAvailable, childPackageCount, releasedReservationIds, transferItems);
return true; return true;
} }
@@ -442,12 +446,15 @@ public class PdaPickSettlementService {
return expectedByLocation.equals(actualByLocation); return expectedByLocation.equals(actualByLocation);
} }
private static String childInboundCode(String parentCode, long childId) { static String childInboundCode(String rootInboundCode, int splitSequence) {
String prefix = parentCode == null ? "INBOUND" : parentCode.trim(); if (splitSequence <= 0) {
throw conflict("子入库单拆分序号不合法");
}
String prefix = rootInboundCode == null ? "INBOUND" : rootInboundCode.trim();
if (prefix.isEmpty()) { if (prefix.isEmpty()) {
prefix = "INBOUND"; prefix = "INBOUND";
} }
String suffix = "-S" + Long.toUnsignedString(childId).substring(0, 6); String suffix = "-" + splitSequence;
return prefix.substring(0, Math.min(prefix.length(), 40 - suffix.length())) + suffix; return prefix.substring(0, Math.min(prefix.length(), 40 - suffix.length())) + suffix;
} }
@@ -62,11 +62,11 @@ class PdaPickSettlementServiceTest {
service.settle(1L, 9L, "operator"); service.settle(1L, 9L, "operator");
verify(splits).cloneChildWithPurpose(eq(10001L), eq(31L), eq(31L), anyLong(), verify(splits).cloneChildWithPurpose(eq(10001L), eq(31L), eq(31L), anyLong(),
eq(1001L), eq("ORDER-LOADED"), anyString(), eq(8), eq(1001L), eq("ORDER-LOADED"), eq("IN-001-1"), eq(8),
anyInt(), eq("LOADED"), eq(9L), eq("operator")); eq(1), eq("LOADED"), eq(9L), eq("operator"));
verify(splits).cloneChildWithPurpose(eq(10001L), eq(31L), eq(31L), anyLong(), verify(splits).cloneChildWithPurpose(eq(10001L), eq(31L), eq(31L), anyLong(),
eq(1002L), eq("ORDER-REMAINDER"), anyString(), eq(12), eq(1002L), eq("ORDER-REMAINDER"), eq("IN-001-2"), eq(12),
anyInt(), eq("REMAINDER"), eq(9L), eq("operator")); eq(2), eq("REMAINDER"), eq(9L), eq("operator"));
verify(allocations).consume(10001L, 31L, 1L, 8); verify(allocations).consume(10001L, 31L, 1L, 8);
verify(warehouse).settle(eq("internal-token"), org.mockito.ArgumentMatchers.argThat(request -> verify(warehouse).settle(eq("internal-token"), org.mockito.ArgumentMatchers.argThat(request ->
request.warehouseId() == 701L && request.sourceBusinessId() == 31L request.warehouseId() == 701L && request.sourceBusinessId() == 31L
@@ -201,6 +201,12 @@ class PdaPickSettlementServiceTest {
assertThat(resolution.skippedPlanItemIds()).isEmpty(); assertThat(resolution.skippedPlanItemIds()).isEmpty();
} }
@Test
void childInboundCodesUseRootCodeAndGlobalSplitSequence() {
assertThat(PdaPickSettlementService.childInboundCode("RK-001", 1)).isEqualTo("RK-001-1");
assertThat(PdaPickSettlementService.childInboundCode("RK-001", 4)).isEqualTo("RK-001-4");
}
@Test @Test
void orderSplitFailureStopsLocalChildCreationAndCanBeRetriedWithSameKey() { void orderSplitFailureStopsLocalChildCreationAndCanBeRetriedWithSameKey() {
LoadingPickItemEntity item = item(11L, 21L, 31L, 41L, 20, 20, "PICKED"); LoadingPickItemEntity item = item(11L, 21L, 31L, 41L, 20, 20, "PICKED");