fix(dropship): preserve carton quantities and shared pallet outbound ownership
This commit is contained in:
+24
-1
@@ -141,6 +141,18 @@ class LoadingCompletedConsumerTest {
|
||||
}
|
||||
verify(dropshipOrders).receive(any());
|
||||
}
|
||||
@Test void preservesNonUniformCartonQuantitiesAcrossTheEventBoundary() {
|
||||
EventEnvelope original=overseasDropshipEvent(false);
|
||||
var node=(com.fasterxml.jackson.databind.node.ObjectNode)original.payload().deepCopy();
|
||||
var sku=(com.fasterxml.jackson.databind.node.ObjectNode)node.path("orders").get(0).path("pallets").get(0).path("skuPackages").get(0);
|
||||
var quantities=sku.putObject("cartonQuantities");
|
||||
quantities.put("RK1#5-1",6).put("RK1#5-2",7).put("RK1#5-3",8).put("RK1#5-4",9).put("RK1#5-5",20);
|
||||
service.consume(rehash(original,node));
|
||||
var captured=ArgumentCaptor.forClass(DropshipRequests.Receive.class);
|
||||
verify(dropshipOrders).receive(captured.capture());
|
||||
assertEquals(Map.of("RK1#5-1",6L,"RK1#5-2",7L,"RK1#5-3",8L,"RK1#5-4",9L,"RK1#5-5",20L),
|
||||
captured.getValue().pallets().get(0).skuPackages().get(0).cartonQuantities());
|
||||
}
|
||||
@Test void rejectsAmbiguousDropshipSkuSourceBeforeWritingReceivingLabels() {
|
||||
var failure=assertThrows(IllegalArgumentException.class,()->service.consume(overseasDropshipEvent(true)));
|
||||
assertTrue(failure.getMessage().contains("来源明细"));
|
||||
@@ -159,6 +171,7 @@ class LoadingCompletedConsumerTest {
|
||||
var secondSku=(com.fasterxml.jackson.databind.node.ObjectNode)secondPallet.path("skuPackages").get(0);
|
||||
var marks=secondSku.putArray("cartonMarks"); for(int n=6;n<=10;n++)marks.add("RK1#10-"+n);
|
||||
((com.fasterxml.jackson.databind.node.ArrayNode)order.path("pallets")).add(secondPallet);
|
||||
addManifest(secondPallet, 5);
|
||||
|
||||
service.consume(rehash(original,node));
|
||||
|
||||
@@ -230,5 +243,15 @@ class LoadingCompletedConsumerTest {
|
||||
private EventEnvelope event(){ var item1=new FirstLegLoadingPlanCompletedV1.Item("d-1","SKU-1","产品","Product",5,50,1,new BigDecimal("10"),new BigDecimal("9"),new BigDecimal("12"),new BigDecimal("1.2"),"wh-1","ONT8","FBA ONT8","FBA-1","SHIP-1","MARK-1"); var item2=new FirstLegLoadingPlanCompletedV1.Item("d-2","SKU-2","产品2","Product2",3,30,2,new BigDecimal("8"),new BigDecimal("7"),new BigDecimal("9"),new BigDecimal("0.8"),"wh-2","LAX9","FBA LAX9","FBA-2","SHIP-2","MARK-2"); var p=new FirstLegLoadingPlanCompletedV1("plan-1","LP1","book-1","MSCU6639870","CAB1","ow-1","洛杉矶海外仓",List.of(new FirstLegLoadingPlanCompletedV1.Order("in-1","root-1","ord-1","FL1","root-o1","RK1","wh-1","ONT8","FBA ONT8",5,50,1,new BigDecimal("10"),new BigDecimal("9"),new BigDecimal("1.2"),List.of(item1),"100","Customer 100","FIRST_LEG",List.of()),new FirstLegLoadingPlanCompletedV1.Order("in-2","root-2","ord-2","FL2","root-o2","RK2","wh-2","LAX9","FBA LAX9",3,30,2,new BigDecimal("8"),new BigDecimal("7"),new BigDecimal("0.8"),List.of(item2),"100","Customer 100","FIRST_LEG",List.of()))); JsonNode node=json.valueToTree(p); String hash=EventPayloadHash.sha256(EventPayloadCanonicalizer.canonicalize(node)); return new EventEnvelope("123e4567-e89b-12d3-a456-426614174000",EventTypes.FIRST_LEG_LOADING_PLAN_COMPLETED,1,Instant.now(),RegionCode.CN,RegionCode.OVERSEAS,"100","LOADING_PLAN","plan-1",2,1L,"123e4567-e89b-12d3-a456-426614174001","FIRSTLEG_LOADING_COMPLETED:plan-1:100:1",null,node,hash); }
|
||||
private JsonNode v2Payload(EventEnvelope source){ com.fasterxml.jackson.databind.node.ObjectNode node=source.payload().deepCopy(); node.set("sourceContainerBookingId",node.remove("containerBookingId")); return node; }
|
||||
private EventEnvelope eventForPayload(FirstLegLoadingPlanCompletedV1 payload, long version){ JsonNode node=json.valueToTree(payload); for(JsonNode order:node.path("orders")) for(JsonNode pallet:order.path("pallets")) addManifest(pallet,order.path("packageCount").asInt()); String hash=EventPayloadHash.sha256(EventPayloadCanonicalizer.canonicalize(node)); return new EventEnvelope("123e4567-e89b-12d3-a456-426614174099",EventTypes.FIRST_LEG_LOADING_PLAN_COMPLETED,1,Instant.now(),RegionCode.CN,RegionCode.OVERSEAS,"100","LOADING_PLAN",payload.loadingPlanId(),2,version,"123e4567-e89b-12d3-a456-426614174098","FIRSTLEG_LOADING_COMPLETED:"+payload.loadingPlanId()+":100:1",null,node,hash); }
|
||||
private void addManifest(JsonNode pallet,int packageCount){ var object=(com.fasterxml.jackson.databind.node.ObjectNode)pallet; object.put("manifestVersion",1).put("manifestPackageCount",packageCount).put("manifestFragmentCount",1).put("manifestHash","a".repeat(64)); }
|
||||
private void addManifest(JsonNode pallet,int packageCount){
|
||||
var object=(com.fasterxml.jackson.databind.node.ObjectNode)pallet;
|
||||
object.put("manifestVersion",1).put("manifestPackageCount",packageCount).put("manifestFragmentCount",1).put("manifestHash","a".repeat(64));
|
||||
// These fixtures explicitly represent uniform cartons; production must never infer this ratio.
|
||||
for(JsonNode sku:object.path("skuPackages")) {
|
||||
int count=sku.path("packageCount").asInt(), quantity=sku.path("productQuantity").asInt();
|
||||
assertTrue(count>0 && quantity%count==0);
|
||||
var quantities=((com.fasterxml.jackson.databind.node.ObjectNode)sku).putObject("cartonQuantities");
|
||||
for(JsonNode mark:sku.path("cartonMarks")) quantities.put(mark.asText(),quantity/count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user