fix(dropship): project sealed carton identities into overseas receiving

This commit is contained in:
2026-09-09 13:20:11 +08:00
parent 90973532f0
commit 748855793d
19 changed files with 558 additions and 33 deletions
@@ -285,7 +285,7 @@ public class LoadingCompletedOutboxService {
int markEnd = Math.min(detail.marks().size(), markStart + count);
List<String> marks = new ArrayList<>(detail.marks().subList(markStart, markEnd));
if (marks.size() != count) throw new BizException(ResultCode.CONFLICT, "一键代发箱唛数量与托盘箱数不一致");
sku.add(new FirstLegLoadingPlanCompletedV2.SkuPackageSnapshot(detail.skuCode(),
sku.add(new FirstLegLoadingPlanCompletedV2.SkuPackageSnapshot(detail.detailId().toString(), detail.skuCode(),
detail.productName(), count, totalQuantity, marks));
remainingPackages.put(detail.detailId(), remaining - count);
remainingMarks.put(detail.detailId(), markEnd);
@@ -325,7 +325,7 @@ public class LoadingCompletedOutboxService {
int quantity = detail.getProductQuantity() == null ? marks.size()
: (int) Math.round((double) detail.getProductQuantity() * marks.size()
/ Math.max(1, detail.getPackageCount()));
skus.add(new FirstLegLoadingPlanCompletedV2.SkuPackageSnapshot(detail.getSkuCode(),
skus.add(new FirstLegLoadingPlanCompletedV2.SkuPackageSnapshot(detail.getSourceInboundDetailId().toString(), detail.getSkuCode(),
detail.getProductNameZh(), marks.size(), quantity, marks));
actualPackages += marks.size();
}
@@ -273,6 +273,44 @@ class LoadingCompletedOutboxServiceTest {
.doesNotContain("pallet.pallet_code");
}
@org.junit.jupiter.params.ParameterizedTest
@org.junit.jupiter.params.provider.ValueSource(booleans = {true, false})
void freezesRepeatedSkuCartonsBySourceDetailForBothPalletSources(boolean actualBinding) throws Exception {
Row first = row(11, 100, 101); first.setFulfillmentType("ONE_CLICK_DROPSHIP");
first.setSkuCode("SAME-SKU"); first.setProductQuantity(10);
Row second = row(11, 100, 102); second.setFulfillmentType("ONE_CLICK_DROPSHIP");
second.setSkuCode("SAME-SKU"); second.setProductQuantity(20);
when(snapshots.rows(90L)).thenReturn(List.of(second, first));
if (actualBinding) {
when(snapshots.workPalletCount(90L)).thenReturn(1);
when(snapshots.actualPalletRows(90L)).thenReturn(List.of(
actualPallet(11,100,"DP-260909-0001",102,"SAME-SKU","BOX-102"),
actualPallet(11,100,"DP-260909-0001",101,"SAME-SKU","BOX-101")));
} else {
when(snapshots.palletRows(90L)).thenReturn(List.of(
pallet(11,100,1,"DP-260909-0001",2,102,"SAME-SKU",1,20,"BOX-102"),
pallet(11,100,1,"DP-260909-0001",2,101,"SAME-SKU",1,10,"BOX-101")));
}
service.publish(90L);
service.publish(90L);
ArgumentCaptor<InboundOutboxEntity> captor = ArgumentCaptor.forClass(InboundOutboxEntity.class);
verify(outbox, org.mockito.Mockito.times(2)).insert(captor.capture());
EventEnvelope event = mapper.readValue(captor.getAllValues().get(0).getPayloadJson(), EventEnvelope.class);
var frozen = event.payload().at("/orders/0/pallets/0/skuPackages");
assertThat(frozen).hasSize(2);
for (var sku : frozen) {
String detail = sku.path("sourceInboundDetailId").asText();
assertThat(detail).isIn("101", "102");
assertThat(sku.path("skuCode").asText()).isEqualTo("SAME-SKU");
assertThat(sku.path("cartonMarks")).hasSize(1);
assertThat(sku.path("cartonMarks").get(0).asText()).isEqualTo("BOX-" + detail);
assertThat(sku.path("productQuantity").asInt()).isEqualTo("101".equals(detail) ? 10 : 20);
}
assertThat(frozen.get(0).path("sourceInboundDetailId"))
.isNotEqualTo(frozen.get(1).path("sourceInboundDetailId"));
assertThat(captor.getAllValues().get(0).getPayloadHash()).isEqualTo(captor.getAllValues().get(1).getPayloadHash());
}
@Test void publishesDropshipPalletSkuAndCartonSnapshots() throws Exception {
Row first = row(11, 100, 101); first.setFulfillmentType("ONE_CLICK_DROPSHIP");
first.setPackageCount(2); first.setProductQuantity(20); first.setSkuCode("SKU-A");