diff --git a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/EblScenarioListBuilder.java b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/EblScenarioListBuilder.java index 77e52015..0d6fa6a8 100644 --- a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/EblScenarioListBuilder.java +++ b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/EblScenarioListBuilder.java @@ -40,38 +40,55 @@ public static EblScenarioListBuilder buildTree( threadLocalCarrierPartyName.set(carrierPartyName); threadLocalShipperPartyName.set(shipperPartyName); return noAction().thenEither( - carrier_SupplyScenarioParameters(ScenarioType.REGULAR).thenAllPathsFrom(SI_START), - carrier_SupplyScenarioParameters(ScenarioType.REEFER).thenHappyPathFrom(SI_START), - carrier_SupplyScenarioParameters(ScenarioType.DG).thenHappyPathFrom(SI_START) + carrier_SupplyScenarioParameters(ScenarioType.REGULAR_SWB).thenAllPathsFrom(SI_START, TD_START, false), + carrier_SupplyScenarioParameters(ScenarioType.REGULAR_BOL).thenHappyPathFrom(SI_START, TD_START, false), + carrier_SupplyScenarioParameters(ScenarioType.REEFER).thenHappyPathFrom(SI_START, TD_START, false), + carrier_SupplyScenarioParameters(ScenarioType.DG).thenHappyPathFrom(SI_START, TD_START, false) ); } private EblScenarioListBuilder thenAllPathsFrom( - ShippingInstructionsStatus shippingInstructionsStatus) { - return thenAllPathsFrom(shippingInstructionsStatus, null); + ShippingInstructionsStatus shippingInstructionsStatus, TransportDocumentStatus transportDocumentStatus, boolean useTDRef) { + return thenAllPathsFrom(shippingInstructionsStatus, null, transportDocumentStatus, useTDRef); } private EblScenarioListBuilder thenAllPathsFrom( - ShippingInstructionsStatus shippingInstructionsStatus, ShippingInstructionsStatus memoryState) { + ShippingInstructionsStatus shippingInstructionsStatus, ShippingInstructionsStatus memoryState, TransportDocumentStatus transportDocumentStatus, boolean useTDRef) { return switch (shippingInstructionsStatus) { - case SI_START -> then( - uc1_shipper_submitShippingInstructions() - .then( - shipper_GetShippingInstructions(SI_RECEIVED, TD_START) - .thenAllPathsFrom(SI_RECEIVED))); + case SI_START -> { + if (useTDRef) { + throw new IllegalStateException("Cannot use transport document reference when submitting a TD"); + } + if (transportDocumentStatus != TD_START) { + throw new IllegalStateException("Cannot use transport document reference when submitting a TD"); + } + yield then( + uc1_shipper_submitShippingInstructions() + .then( + shipper_GetShippingInstructions(SI_RECEIVED, false) + .thenAllPathsFrom(SI_RECEIVED, transportDocumentStatus, false))); + } case SI_RECEIVED -> thenEither( uc2_carrier_requestUpdateToShippingInstruction() .then( - shipper_GetShippingInstructions(SI_PENDING_UPDATE, TD_START) - .thenAllPathsFrom(SI_PENDING_UPDATE)), - uc3_shipper_submitUpdatedShippingInstructions() - .then( - shipper_GetShippingInstructions(SI_RECEIVED, SI_UPDATE_RECEIVED, TD_START) - .thenAllPathsFrom(SI_UPDATE_RECEIVED, SI_RECEIVED)), - uc6_carrier_publishDraftTransportDocument() + shipper_GetShippingInstructions(SI_PENDING_UPDATE, useTDRef) + .thenAllPathsFrom(SI_PENDING_UPDATE, transportDocumentStatus, useTDRef)), + uc3_shipper_submitUpdatedShippingInstructions(useTDRef) .then( - shipper_GetShippingInstructions(SI_RECEIVED, SI_ANY, TD_DRAFT, true) - .then(shipper_GetTransportDocument(TD_DRAFT).thenAllPathsFrom(TD_DRAFT)))); + shipper_GetShippingInstructions(SI_RECEIVED, SI_UPDATE_RECEIVED, useTDRef) + .thenAllPathsFrom(SI_UPDATE_RECEIVED, SI_RECEIVED, transportDocumentStatus, useTDRef)), + switch (transportDocumentStatus) { + case TD_START -> uc6_carrier_publishDraftTransportDocument().then( + shipper_GetShippingInstructionsRecordTDRef() + .then(shipper_GetTransportDocument(TD_DRAFT).thenAllPathsFrom(TD_DRAFT))); + case TD_DRAFT -> uc6_carrier_publishDraftTransportDocument().then( + shipper_GetShippingInstructionsRecordTDRef() + .then(shipper_GetTransportDocument(TD_DRAFT).thenHappyPathFrom(TD_DRAFT))); + case TD_ISSUED -> uc9_carrier_awaitSurrenderRequestForAmendment().then( + shipper_GetTransportDocument(TD_PENDING_SURRENDER_FOR_AMENDMENT) + ).thenHappyPathFrom(TD_PENDING_SURRENDER_FOR_AMENDMENT); + default -> throw new IllegalStateException("Unexpected transportDocumentStatus: " + transportDocumentStatus.name()); + }); case SI_UPDATE_RECEIVED -> { if (memoryState == null) { throw new IllegalArgumentException( @@ -80,89 +97,105 @@ private EblScenarioListBuilder thenAllPathsFrom( yield thenEither( uc2_carrier_requestUpdateToShippingInstruction() .then( - shipper_GetShippingInstructions(SI_PENDING_UPDATE, TD_START) - .thenHappyPathFrom(SI_PENDING_UPDATE)), + shipper_GetShippingInstructions(SI_PENDING_UPDATE, useTDRef) + .thenHappyPathFrom(SI_PENDING_UPDATE, transportDocumentStatus, useTDRef)), uc4a_carrier_acceptUpdatedShippingInstructions() .then( - shipper_GetShippingInstructions(SI_RECEIVED, SI_UPDATE_CONFIRMED, TD_START) - .thenHappyPathFrom(SI_RECEIVED)), + shipper_GetShippingInstructions(SI_RECEIVED, SI_UPDATE_CONFIRMED, useTDRef) + .thenHappyPathFrom(SI_RECEIVED, transportDocumentStatus, useTDRef)), uc4d_carrier_declineUpdatedShippingInstructions() .then( - shipper_GetShippingInstructions(memoryState, SI_UPDATE_DECLINED, TD_START) - .thenHappyPathFrom(memoryState)), + shipper_GetShippingInstructions(memoryState, SI_UPDATE_DECLINED, useTDRef) + .thenHappyPathFrom(memoryState, transportDocumentStatus, useTDRef)), uc5_shipper_cancelUpdateToShippingInstructions() - .then( - shipper_GetShippingInstructions(memoryState, SI_UPDATE_CANCELLED, TD_START) - .thenHappyPathFrom(memoryState))); + .then( + shipper_GetShippingInstructions(memoryState, SI_UPDATE_CANCELLED, useTDRef) + .thenHappyPathFrom(memoryState, transportDocumentStatus, useTDRef))); } case SI_PENDING_UPDATE -> then( - uc3_shipper_submitUpdatedShippingInstructions() + uc3_shipper_submitUpdatedShippingInstructions(useTDRef) .then( - shipper_GetShippingInstructions(SI_PENDING_UPDATE, SI_UPDATE_RECEIVED, TD_START) - .thenEither( - noAction().thenHappyPathFrom(SI_PENDING_UPDATE), - // Special-case: UC2 -> UC3 -> UC5 -> ... - // - Doing thenAllPathsFrom(...) from UC2 would cause UC3 -> UC2 -> UC3 -> UC2 -> UC3 -> ... - // patterns (it eventually resolves, but it is unhelpful many cases) - // To ensure that UC2 -> UC3 -> UC5 -> ... works properly we manually the subtree here. - // Otherwise, we would never test the UC2 -> UC3 -> UC5 -> ... flow because neither UC2 and UC5 - // are considered happy paths. - uc5_shipper_cancelUpdateToShippingInstructions() - .then( - shipper_GetShippingInstructions(SI_PENDING_UPDATE, SI_UPDATE_CANCELLED, TD_START) - .thenEither( - noAction().thenHappyPathFrom(SI_PENDING_UPDATE), - uc3_shipper_submitUpdatedShippingInstructions().then( - shipper_GetShippingInstructions(SI_PENDING_UPDATE, SI_UPDATE_RECEIVED, TD_START) - .thenHappyPathFrom(SI_UPDATE_RECEIVED, SI_PENDING_UPDATE))))))); + shipper_GetShippingInstructions(SI_PENDING_UPDATE, SI_UPDATE_RECEIVED, useTDRef) + .thenEither( + noAction().thenHappyPathFrom(SI_PENDING_UPDATE, transportDocumentStatus, useTDRef), + // Special-case: UC2 -> UC3 -> UC5 -> ... + // - Doing thenAllPathsFrom(...) from UC2 would cause UC3 -> UC2 -> UC3 -> + // UC2 -> UC3 -> ... + // patterns (it eventually resolves, but it is unhelpful many cases) + // To ensure that UC2 -> UC3 -> UC5 -> ... works properly we manually do + // the subtree here. + // Otherwise, we would never test the UC2 -> UC3 -> UC5 -> ... flow + // because neither UC2 and UC3 + // are considered happy paths. + uc5_shipper_cancelUpdateToShippingInstructions() + .then( + shipper_GetShippingInstructions( + SI_PENDING_UPDATE, SI_UPDATE_CANCELLED, useTDRef) + .thenEither( + noAction().thenHappyPathFrom(SI_PENDING_UPDATE, transportDocumentStatus, useTDRef), + uc3_shipper_submitUpdatedShippingInstructions(useTDRef) + .then( + shipper_GetShippingInstructions( + SI_PENDING_UPDATE, SI_UPDATE_RECEIVED, useTDRef) + .thenHappyPathFrom( + SI_UPDATE_RECEIVED, + SI_PENDING_UPDATE, + transportDocumentStatus, + useTDRef))))))); case SI_UPDATE_CONFIRMED -> thenEither( - noAction().thenHappyPathFrom(SI_UPDATE_CONFIRMED), - // Just to validate that the "Carrier" does not get "stuck" - uc2_carrier_requestUpdateToShippingInstruction() - .then( - shipper_GetShippingInstructions(SI_PENDING_UPDATE, TD_START) - .thenHappyPathFrom(SI_PENDING_UPDATE)), - uc3_shipper_submitUpdatedShippingInstructions() - .then( - shipper_GetShippingInstructions(SI_PENDING_UPDATE, SI_UPDATE_RECEIVED, TD_START) - .thenHappyPathFrom(SI_UPDATE_RECEIVED, SI_PENDING_UPDATE))); - case SI_UPDATE_CANCELLED, SI_UPDATE_DECLINED -> throw new AssertionError("Please use the black state rather than " + shippingInstructionsStatus.name()); + noAction().thenHappyPathFrom(SI_UPDATE_CONFIRMED, transportDocumentStatus, useTDRef), + // Just to validate that the "Carrier" does not get "stuck" + uc2_carrier_requestUpdateToShippingInstruction() + .then( + shipper_GetShippingInstructions(SI_PENDING_UPDATE, useTDRef) + .thenHappyPathFrom(SI_PENDING_UPDATE, transportDocumentStatus, useTDRef)), + uc3_shipper_submitUpdatedShippingInstructions(useTDRef) + .then( + shipper_GetShippingInstructions(SI_PENDING_UPDATE, SI_UPDATE_RECEIVED, useTDRef) + .thenHappyPathFrom(SI_UPDATE_RECEIVED, SI_PENDING_UPDATE, transportDocumentStatus, useTDRef))); + case SI_UPDATE_CANCELLED, SI_UPDATE_DECLINED -> throw new AssertionError( + "Please use the black state rather than " + shippingInstructionsStatus.name()); case SI_ANY -> throw new AssertionError("Not a real/reachable state"); case SI_COMPLETED -> then(noAction()); }; } private EblScenarioListBuilder thenHappyPathFrom( - ShippingInstructionsStatus shippingInstructionsStatus) { - return thenHappyPathFrom(shippingInstructionsStatus, null); + ShippingInstructionsStatus shippingInstructionsStatus, TransportDocumentStatus transportDocumentStatus, boolean useTDRef) { + return thenHappyPathFrom(shippingInstructionsStatus, null, transportDocumentStatus, useTDRef); } private EblScenarioListBuilder thenHappyPathFrom( - ShippingInstructionsStatus shippingInstructionsStatus, ShippingInstructionsStatus memoryState) { + ShippingInstructionsStatus shippingInstructionsStatus, ShippingInstructionsStatus memoryState, TransportDocumentStatus transportDocumentStatus, boolean useTDRef) { return switch (shippingInstructionsStatus) { case SI_START -> then( uc1_shipper_submitShippingInstructions() .then( - shipper_GetShippingInstructions(SI_RECEIVED, TD_START) - .thenHappyPathFrom(SI_RECEIVED))); + shipper_GetShippingInstructions(SI_RECEIVED, useTDRef) + .thenHappyPathFrom(SI_RECEIVED, transportDocumentStatus, useTDRef))); case SI_UPDATE_CONFIRMED, SI_RECEIVED -> then( - uc6_carrier_publishDraftTransportDocument() - .then( - shipper_GetShippingInstructions(SI_RECEIVED, SI_ANY, TD_DRAFT, true) - .then(shipper_GetTransportDocument(TD_DRAFT).thenHappyPathFrom(TD_DRAFT)))); + switch (transportDocumentStatus) { + case TD_START, TD_DRAFT -> uc6_carrier_publishDraftTransportDocument().then( + shipper_GetShippingInstructionsRecordTDRef() + .then(shipper_GetTransportDocument(TD_DRAFT).thenHappyPathFrom(TD_DRAFT))); + case TD_ISSUED -> uc9_carrier_awaitSurrenderRequestForAmendment().then( + shipper_GetTransportDocument(TD_PENDING_SURRENDER_FOR_AMENDMENT) + .thenHappyPathFrom(TD_PENDING_SURRENDER_FOR_AMENDMENT)); + default -> throw new IllegalStateException("Unexpected transportDocumentStatus: " + transportDocumentStatus.name()); + }); case SI_PENDING_UPDATE -> then( - uc3_shipper_submitUpdatedShippingInstructions() + uc3_shipper_submitUpdatedShippingInstructions(false) .then( - shipper_GetShippingInstructions(SI_PENDING_UPDATE, SI_UPDATE_RECEIVED, TD_START) - .thenHappyPathFrom(SI_UPDATE_RECEIVED, SI_PENDING_UPDATE))); + shipper_GetShippingInstructions(SI_PENDING_UPDATE, SI_UPDATE_RECEIVED, useTDRef) + .thenHappyPathFrom(SI_UPDATE_RECEIVED, SI_PENDING_UPDATE, transportDocumentStatus, useTDRef))); case SI_UPDATE_RECEIVED -> then( uc4a_carrier_acceptUpdatedShippingInstructions() .then( - shipper_GetShippingInstructions(SI_RECEIVED, SI_UPDATE_CONFIRMED, TD_START) - .thenHappyPathFrom(SI_UPDATE_CONFIRMED))); + shipper_GetShippingInstructions(SI_RECEIVED, SI_UPDATE_CONFIRMED, useTDRef) + .thenHappyPathFrom(SI_UPDATE_CONFIRMED, transportDocumentStatus, useTDRef))); case SI_COMPLETED -> then(noAction()); case SI_UPDATE_CANCELLED, SI_UPDATE_DECLINED -> throw new AssertionError( - "Please use the black state rather than DECLINED"); + "Please use the black state rather than " + shippingInstructionsStatus.name()); case SI_ANY -> throw new AssertionError("Not a real/reachable state"); }; } @@ -170,16 +203,20 @@ private EblScenarioListBuilder thenHappyPathFrom( private EblScenarioListBuilder thenAllPathsFrom(TransportDocumentStatus transportDocumentStatus) { return switch (transportDocumentStatus) { case TD_DRAFT -> thenEither( + uc7_shipper_approveDraftTransportDocument() + .then(shipper_GetTransportDocument(TD_APPROVED) + .thenAllPathsFrom(TD_APPROVED)), uc8_carrier_issueTransportDocument() .then( shipper_GetTransportDocument(TD_ISSUED) // Using happy path here as requested in // https://github.com/dcsaorg/Conformance-Gateway/pull/29#discussion_r1421732797 .thenHappyPathFrom(TD_ISSUED)), - uc7_shipper_approveDraftTransportDocument() - .then(shipper_GetTransportDocument(TD_APPROVED) - .thenAllPathsFrom(TD_APPROVED)) - ); + uc3_shipper_submitUpdatedShippingInstructions(true) + .thenHappyPathFrom(SI_UPDATE_RECEIVED, TD_DRAFT, true), + uc3_shipper_submitUpdatedShippingInstructions(false) + .thenHappyPathFrom(SI_UPDATE_RECEIVED, TD_DRAFT, false) + ); case TD_APPROVED -> then( uc8_carrier_issueTransportDocument() .then( @@ -187,8 +224,10 @@ private EblScenarioListBuilder thenAllPathsFrom(TransportDocumentStatus transpor .thenAllPathsFrom(TD_ISSUED)) ); case TD_ISSUED -> thenEither( - // TODO: We should have uc3 + uc4a + uc9 for an SI based amendment in parallel with UC9 - // (without uc3 + uc4a, which is basically a booking based amendment) + uc3_shipper_submitUpdatedShippingInstructions(true) + .thenHappyPathFrom(SI_UPDATE_RECEIVED, TD_ISSUED, true), + uc3_shipper_submitUpdatedShippingInstructions(false) + .thenHappyPathFrom(SI_UPDATE_RECEIVED, TD_ISSUED, false), uc9_carrier_awaitSurrenderRequestForAmendment() .then(shipper_GetTransportDocument(TD_PENDING_SURRENDER_FOR_AMENDMENT) .thenAllPathsFrom(TD_PENDING_SURRENDER_FOR_AMENDMENT)), @@ -266,8 +305,9 @@ private EblScenarioListBuilder thenHappyPathFrom(TransportDocumentStatus transpo ) ); case TD_SURRENDERED_FOR_DELIVERY -> then( - uc14_carrier_confirmShippingInstructionsComplete().then( - shipper_GetShippingInstructions(SI_COMPLETED, TD_SURRENDERED_FOR_DELIVERY) + uc14_carrier_confirmShippingInstructionsComplete().thenEither( + shipper_GetShippingInstructions(SI_COMPLETED, false), + shipper_GetShippingInstructions(SI_COMPLETED, true) ) ); case TD_START, TD_ANY -> throw new AssertionError("Not a real/reachable state"); @@ -290,29 +330,30 @@ private static EblScenarioListBuilder carrier_SupplyScenarioParameters(ScenarioT } - private static EblScenarioListBuilder shipper_GetShippingInstructions( - ShippingInstructionsStatus expectedSiStatus, TransportDocumentStatus expectedTdStatus) { - return shipper_GetShippingInstructions(expectedSiStatus, null, expectedTdStatus); + private static EblScenarioListBuilder shipper_GetShippingInstructions(ShippingInstructionsStatus expectedSiStatus, + boolean useTDRef) { + return shipper_GetShippingInstructions(expectedSiStatus, null, useTDRef); } - private static EblScenarioListBuilder shipper_GetShippingInstructions( - ShippingInstructionsStatus expectedSiStatus, ShippingInstructionsStatus expectedUpdatedSiStatus, TransportDocumentStatus expectedTdStatus, boolean recordTDR) { - return shipper_GetShippingInstructions(expectedSiStatus, expectedUpdatedSiStatus, expectedTdStatus, false, recordTDR); + private static EblScenarioListBuilder shipper_GetShippingInstructionsRecordTDRef() { + return shipper_GetShippingInstructions(SI_RECEIVED, SI_ANY, false, true, false); } private static EblScenarioListBuilder shipper_GetShippingInstructions( ShippingInstructionsStatus expectedSiStatus, ShippingInstructionsStatus expectedUpdatedSiStatus, - TransportDocumentStatus expectedTdStatus) { - return shipper_GetShippingInstructions(expectedSiStatus, expectedUpdatedSiStatus, expectedTdStatus, false, false); + boolean useTDRef + ) { + return shipper_GetShippingInstructions(expectedSiStatus, expectedUpdatedSiStatus, false, false, useTDRef); } + private static EblScenarioListBuilder shipper_GetShippingInstructions( ShippingInstructionsStatus expectedSiStatus, ShippingInstructionsStatus expectedUpdatedSiStatus, - TransportDocumentStatus expectedTdStatus, boolean requestAmendedSI, - boolean recordTDR) { + boolean recordTDR, + boolean useTDRef) { EblComponentFactory componentFactory = threadLocalComponentFactory.get(); String carrierPartyName = threadLocalCarrierPartyName.get(); String shipperPartyName = threadLocalShipperPartyName.get(); @@ -326,7 +367,8 @@ private static EblScenarioListBuilder shipper_GetShippingInstructions( expectedUpdatedSiStatus, componentFactory.getMessageSchemaValidator(EBL_API, GET_EBL_SCHEMA_NAME), requestAmendedSI, - recordTDR)); + recordTDR, + useTDRef)); } private static EblScenarioListBuilder shipper_GetTransportDocument( @@ -359,7 +401,7 @@ private static EblScenarioListBuilder uc1_shipper_submitShippingInstructions() { componentFactory.getMessageSchemaValidator(EBL_NOTIFICATIONS_API, EBL_SI_NOTIFICATION_SCHEMA_NAME))); } - private static EblScenarioListBuilder uc3_shipper_submitUpdatedShippingInstructions() { + private static EblScenarioListBuilder uc3_shipper_submitUpdatedShippingInstructions(boolean useTDRef) { EblComponentFactory componentFactory = threadLocalComponentFactory.get(); String carrierPartyName = threadLocalCarrierPartyName.get(); String shipperPartyName = threadLocalShipperPartyName.get(); @@ -369,6 +411,7 @@ private static EblScenarioListBuilder uc3_shipper_submitUpdatedShippingInstructi carrierPartyName, shipperPartyName, (EblAction) previousAction, + useTDRef, componentFactory.getMessageSchemaValidator(EBL_API, PUT_EBL_SCHEMA_NAME), componentFactory.getMessageSchemaValidator(EBL_API, EBL_REF_STATUS_SCHEMA_NAME), componentFactory.getMessageSchemaValidator( diff --git a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/Carrier_SupplyScenarioParametersAction.java b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/Carrier_SupplyScenarioParametersAction.java index 3f560e2b..f9e05115 100644 --- a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/Carrier_SupplyScenarioParametersAction.java +++ b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/Carrier_SupplyScenarioParametersAction.java @@ -18,11 +18,7 @@ public Carrier_SupplyScenarioParametersAction(String carrierPartyName, @NonNull carrierPartyName, null, null, - switch (scenarioType) { - case REGULAR -> "SupplyCSP"; - case REEFER -> "SupplyCSP-AR"; - case DG -> "SupplyCSP-DG"; - }, + "SupplyCSP [%s]".formatted(scenarioType.name()), -1); this.scenarioType = scenarioType; this.getDspConsumer().accept(getDspSupplier().get().withScenarioType(scenarioType)); @@ -67,7 +63,7 @@ public String getHumanReadablePrompt() { @Override public JsonNode getJsonForHumanReadablePrompt() { var csp = switch (scenarioType) { - case REGULAR -> new CarrierScenarioParameters( + case REGULAR_SWB, REGULAR_BOL -> new CarrierScenarioParameters( "Booking Reference", "Commodity subreference for regular (non-DG, non-reefer) cargo", // Any valid regular equipment reference will do as an example. diff --git a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/EblAction.java b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/EblAction.java index 552717c6..4b42f931 100644 --- a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/EblAction.java +++ b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/EblAction.java @@ -31,7 +31,7 @@ public EblAction( this.dspReference = previousAction == null ? new OverwritingReference<>( - null, new DynamicScenarioParameters(ScenarioType.REGULAR, null, null, null, null, null)) + null, new DynamicScenarioParameters(ScenarioType.REGULAR_SWB, null, null, null, null, null)) : new OverwritingReference<>(previousAction.dspReference, null); } diff --git a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/Shipper_GetShippingInstructionsAction.java b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/Shipper_GetShippingInstructionsAction.java index ad88e9d2..c0f49b21 100644 --- a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/Shipper_GetShippingInstructionsAction.java +++ b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/Shipper_GetShippingInstructionsAction.java @@ -16,6 +16,7 @@ public class Shipper_GetShippingInstructionsAction extends EblAction { private final JsonSchemaValidator responseSchemaValidator; private final boolean requestAmendedStatus; private final boolean recordTDR; + private final boolean useTDRef; public Shipper_GetShippingInstructionsAction( String carrierPartyName, @@ -25,25 +26,41 @@ public Shipper_GetShippingInstructionsAction( ShippingInstructionsStatus expectedAmendedSiStatus, JsonSchemaValidator responseSchemaValidator, boolean requestAmendedStatus, - boolean recordTDR) { + boolean recordTDR, + boolean useTDRef) { super(shipperPartyName, carrierPartyName, previousAction, requestAmendedStatus ? "GET aSI" : "GET SI", 200); this.expectedSiStatus = expectedSiStatus; this.expectedAmendedSiStatus = expectedAmendedSiStatus; + this.useTDRef = useTDRef; this.responseSchemaValidator = responseSchemaValidator; this.requestAmendedStatus = requestAmendedStatus; this.recordTDR = recordTDR; + + if (useTDRef && recordTDR) { + throw new IllegalArgumentException("Cannot use recordTDR with useTDRef"); + } } @Override public ObjectNode asJsonNode() { + var dsp = getDspSupplier().get(); + var documentReference = this.useTDRef ? dsp.transportDocumentReference() : dsp.shippingInstructionsReference(); + if (documentReference == null) { + throw new IllegalStateException("Missing document reference for use-case 3"); + } return super.asJsonNode() - .put("sir", getDspSupplier().get().shippingInstructionsReference()); + .put("documentReference", documentReference); } @Override public String getHumanReadablePrompt() { + var dsp = getDspSupplier().get(); + var documentReference = this.useTDRef ? dsp.transportDocumentReference() : dsp.shippingInstructionsReference(); + if (documentReference == null) { + throw new IllegalStateException("Missing document reference for get SI"); + } return "GET the SI with reference '%s'" - .formatted(getDspSupplier().get().shippingInstructionsReference()); + .formatted(documentReference); } protected void doHandleExchange(ConformanceExchange exchange) { @@ -62,11 +79,13 @@ public ConformanceCheck createCheck(String expectedApiVersion) { return new ConformanceCheck(getActionTitle()) { @Override protected Stream createSubChecks() { + var dsp = getDspSupplier().get(); + var documentReference = useTDRef ? dsp.transportDocumentReference() : dsp.shippingInstructionsReference(); return Stream.of( new UrlPathCheck( EblRole::isShipper, getMatchedExchangeUuid(), - "/v3/shipping-instructions/" + getDspSupplier().get().shippingInstructionsReference()), + "/v3/shipping-instructions/" + documentReference), new ResponseStatusCheck( EblRole::isCarrier, getMatchedExchangeUuid(), expectedStatus), new ApiHeaderCheck( diff --git a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/Shipper_GetTransportDocumentAction.java b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/Shipper_GetTransportDocumentAction.java index 31f6a932..d9ce8603 100644 --- a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/Shipper_GetTransportDocumentAction.java +++ b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/Shipper_GetTransportDocumentAction.java @@ -65,7 +65,7 @@ protected Stream createSubChecks() { getMatchedExchangeUuid(), HttpMessageType.RESPONSE, responseSchemaValidator), - EBLChecks.tdContentChecks(getMatchedExchangeUuid(), expectedTdStatus, getDspSupplier())); + EBLChecks.tdContentChecks(getMatchedExchangeUuid(), expectedTdStatus, getCspSupplier(), getDspSupplier())); } }; } diff --git a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/UC1_Shipper_SubmitShippingInstructionsAction.java b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/UC1_Shipper_SubmitShippingInstructionsAction.java index f2f039e8..96d6afde 100644 --- a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/UC1_Shipper_SubmitShippingInstructionsAction.java +++ b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/UC1_Shipper_SubmitShippingInstructionsAction.java @@ -39,7 +39,7 @@ public String getHumanReadablePrompt() { public ObjectNode asJsonNode() { ObjectNode jsonNode = super.asJsonNode(); jsonNode.set("csp", getCspSupplier().get().toJson()); - return jsonNode; + return jsonNode.put("scenarioType", getDspSupplier().get().scenarioType().name()); } @Override @@ -78,7 +78,7 @@ protected Stream createSubChecks() { getMatchedExchangeUuid(), HttpMessageType.RESPONSE, responseSchemaValidator), - EBLChecks.siRequestContentChecks(getMatchedExchangeUuid(), getCspSupplier())); + EBLChecks.siRequestContentChecks(getMatchedExchangeUuid(), getCspSupplier(), getDspSupplier())); return Stream.concat( primaryExchangeChecks, Stream.concat( diff --git a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/UC3_Shipper_SubmitUpdatedShippingInstructionsAction.java b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/UC3_Shipper_SubmitUpdatedShippingInstructionsAction.java index 6ac45ef9..b6f8cfae 100644 --- a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/UC3_Shipper_SubmitUpdatedShippingInstructionsAction.java +++ b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/action/UC3_Shipper_SubmitUpdatedShippingInstructionsAction.java @@ -17,15 +17,18 @@ public class UC3_Shipper_SubmitUpdatedShippingInstructionsAction extends StateCh private final JsonSchemaValidator requestSchemaValidator; private final JsonSchemaValidator responseSchemaValidator; private final JsonSchemaValidator notificationSchemaValidator; + private final boolean useTDRef; public UC3_Shipper_SubmitUpdatedShippingInstructionsAction( String carrierPartyName, String shipperPartyName, EblAction previousAction, + boolean useTDRef, JsonSchemaValidator requestSchemaValidator, JsonSchemaValidator responseSchemaValidator, JsonSchemaValidator notificationSchemaValidator) { - super(shipperPartyName, carrierPartyName, previousAction, "UC3", 200); + super(shipperPartyName, carrierPartyName, previousAction, "UC3" + (useTDRef ? " [TDR]" : ""), 200); + this.useTDRef = useTDRef; this.requestSchemaValidator = requestSchemaValidator; this.responseSchemaValidator = responseSchemaValidator; this.notificationSchemaValidator = notificationSchemaValidator; @@ -38,8 +41,14 @@ public String getHumanReadablePrompt() { @Override public ObjectNode asJsonNode() { + var dsp = getDspSupplier().get(); + var documentReference = this.useTDRef ? dsp.transportDocumentReference() : dsp.shippingInstructionsReference(); + if (documentReference == null) { + throw new IllegalStateException("Missing document reference for use-case 3"); + } return super.asJsonNode() - .put("sir", getDspSupplier().get().shippingInstructionsReference()); + .put("sir", dsp.shippingInstructionsReference()) + .put("documentReference", documentReference); } @Override @@ -60,7 +69,7 @@ protected Stream createSubChecks() { Stream primaryExchangeChecks = Stream.of( new HttpMethodCheck(EblRole::isShipper, getMatchedExchangeUuid(), "PUT"), - new UrlPathCheck(EblRole::isShipper, getMatchedExchangeUuid(), "/v3/shipping-instructions/%s".formatted(dsp.shippingInstructionsReference())), + new UrlPathCheck(EblRole::isShipper, getMatchedExchangeUuid(), "/v3/shipping-instructions/%s".formatted(useTDRef ? dsp.transportDocumentReference() : dsp.shippingInstructionsReference())), new ResponseStatusCheck( EblRole::isCarrier, getMatchedExchangeUuid(), expectedStatus), new ApiHeaderCheck( @@ -83,7 +92,7 @@ protected Stream createSubChecks() { getMatchedExchangeUuid(), HttpMessageType.RESPONSE, responseSchemaValidator), - EBLChecks.siRequestContentChecks(getMatchedExchangeUuid(), getCspSupplier()) + EBLChecks.siRequestContentChecks(getMatchedExchangeUuid(), getCspSupplier(), getDspSupplier()) ); return Stream.concat( primaryExchangeChecks, diff --git a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/checks/EBLChecks.java b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/checks/EBLChecks.java index 749fe88f..7c4298fd 100644 --- a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/checks/EBLChecks.java +++ b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/checks/EBLChecks.java @@ -668,7 +668,7 @@ public static JsonContentCheck tdrInNotificationMustMatchDSP(Supplier dspSupplier.get().transportDocumentReference()); } - private static Supplier cspValue(Supplier cspSupplier, Function field) { + private static Supplier delayedValue(Supplier cspSupplier, Function field) { return () -> { var csp = cspSupplier.get(); if (csp == null) { @@ -678,11 +678,16 @@ private static Supplier cspValue(Supplier cspS }; } - private static void generateCSPRelatedChecks(List checks, Supplier cspSupplier, boolean isTD) { + private static void generateScenarioRelatedChecks(List checks, Supplier cspSupplier, Supplier dspSupplier, boolean isTD) { + checks.add(JsonAttribute.mustEqual( + "[Scenario] Verify that the correct 'transportDocumentTypeCode' is used", + "transportDocumentTypeCode", + delayedValue(dspSupplier, dsp -> dsp.scenarioType().transportDocumentTypeCode()) + )); checks.add(JsonAttribute.allIndividualMatchesMustBeValid( "[Scenario] Verify that the correct 'carrierBookingReference' is used", mav -> mav.submitAllMatching("consignmentItems.*.carrierBookingReference"), - JsonAttribute.matchedMustEqual(cspValue(cspSupplier, CarrierScenarioParameters::carrierBookingReference)) + JsonAttribute.matchedMustEqual(delayedValue(cspSupplier, CarrierScenarioParameters::carrierBookingReference)) )); if (!isTD) { checks.add( @@ -690,7 +695,7 @@ private static void generateCSPRelatedChecks(List checks, Supp "[Scenario] Verify that the correct 'commoditySubreference' is used", mav -> mav.submitAllMatching("consignmentItems.*.commoditySubreference"), JsonAttribute.matchedMustEqual( - cspValue(cspSupplier, CarrierScenarioParameters::commoditySubreference)))); + delayedValue(cspSupplier, CarrierScenarioParameters::commoditySubreference)))); } checks.add(JsonAttribute.allIndividualMatchesMustBeValid( "[Scenario] Verify that the correct 'equipmentReference' is used", @@ -700,41 +705,41 @@ private static void generateCSPRelatedChecks(List checks, Supp mav.submitAllMatching("utilizedTransportEquipments.*.equipmentReference"); mav.submitAllMatching("utilizedTransportEquipments.*.equipment.equipmentReference"); }, - JsonAttribute.matchedMustEqualIfPresent(cspValue(cspSupplier, CarrierScenarioParameters::equipmentReference)) + JsonAttribute.matchedMustEqualIfPresent(delayedValue(cspSupplier, CarrierScenarioParameters::equipmentReference)) )); checks.add(JsonAttribute.allIndividualMatchesMustBeValid( "[Scenario] Verify that the correct 'HSCodes' are used", mav -> mav.submitAllMatching("consignmentItems.*.HSCodes.*"), - JsonAttribute.matchedMustEqual(cspValue(cspSupplier, CarrierScenarioParameters::consignmentItemHSCode)) + JsonAttribute.matchedMustEqual(delayedValue(cspSupplier, CarrierScenarioParameters::consignmentItemHSCode)) )); checks.add(JsonAttribute.allIndividualMatchesMustBeValid( "[Scenario] Verify that the correct 'descriptionOfGoods' is used", mav -> mav.submitAllMatching("consignmentItems.*.descriptionOfGoods"), - JsonAttribute.matchedMustEqual(cspValue(cspSupplier, CarrierScenarioParameters::descriptionOfGoods)) + JsonAttribute.matchedMustEqual(delayedValue(cspSupplier, CarrierScenarioParameters::descriptionOfGoods)) )); checks.add(JsonAttribute.mustEqual( "[Scenario] Verify that the correct 'serviceContractReference' is used", "serviceContractReference", - cspValue(cspSupplier, CarrierScenarioParameters::serviceContractReference) + delayedValue(cspSupplier, CarrierScenarioParameters::serviceContractReference) )); checks.add(JsonAttribute.mustEqual( "[Scenario] Verify that the correct 'contractQuotationReference' is used", "contractQuotationReference", - cspValue(cspSupplier, CarrierScenarioParameters::contractQuotationReference) + delayedValue(cspSupplier, CarrierScenarioParameters::contractQuotationReference) )); checks.add(JsonAttribute.mustEqual( "[Scenario] Verify that the correct 'invoicePayableAt' location is used", SI_REQUEST_INVOICE_PAYABLE_AT_UN_LOCATION_CODE, - cspValue(cspSupplier, CarrierScenarioParameters::invoicePayableAtUNLocationCode) + delayedValue(cspSupplier, CarrierScenarioParameters::invoicePayableAtUNLocationCode) )); } - public static ActionCheck siRequestContentChecks(UUID matched, Supplier cspSupplier) { + public static ActionCheck siRequestContentChecks(UUID matched, Supplier cspSupplier, Supplier dspSupplier) { var checks = new ArrayList<>(STATIC_SI_CHECKS); - generateCSPRelatedChecks(checks, cspSupplier, false); + generateScenarioRelatedChecks(checks, cspSupplier, dspSupplier, false); return JsonAttribute.contentChecks( EblRole::isShipper, matched, @@ -762,7 +767,7 @@ public static ActionCheck siResponseContentChecks(UUID matched, Supplier dspSupplier) { + public static ActionCheck tdContentChecks(UUID matched, TransportDocumentStatus transportDocumentStatus, Supplier cspSupplier, Supplier dspSupplier) { List jsonContentChecks = new ArrayList<>(); jsonContentChecks.add(JsonAttribute.mustEqual( TD_TDR, @@ -899,6 +904,7 @@ public static ActionCheck tdContentChecks(UUID matched, TransportDocumentStatus return Set.of(); } )); + generateScenarioRelatedChecks(jsonContentChecks, cspSupplier, dspSupplier, true); return JsonAttribute.contentChecks( EblRole::isCarrier, matched, diff --git a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/checks/ScenarioType.java b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/checks/ScenarioType.java index e481f306..21a120e9 100644 --- a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/checks/ScenarioType.java +++ b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/checks/ScenarioType.java @@ -1,8 +1,17 @@ package org.dcsa.conformance.standards.ebl.checks; public enum ScenarioType { - REGULAR, + REGULAR_SWB, + REGULAR_BOL, REEFER, DG, ; + + public String transportDocumentTypeCode() { + return this == REGULAR_BOL ? "BOL" : "SWB"; + } + + public boolean isToOrder() { + return false; + } } diff --git a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/models/CarrierShippingInstructions.java b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/models/CarrierShippingInstructions.java index d3945596..66bf7782 100644 --- a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/models/CarrierShippingInstructions.java +++ b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/models/CarrierShippingInstructions.java @@ -500,7 +500,7 @@ private void fixupConsignmentItems(ObjectNode transportDocument, ScenarioType sc // The alternative is having a look-up table of all known packageCode's and their relevant // description. switch (scenarioType) { - case REGULAR -> + case REGULAR_SWB, REGULAR_BOL -> outerPackaging.put("packageCode", "4G") .put("description", "Fibreboard boxes"); case REEFER -> @@ -527,7 +527,7 @@ private void fixupUtilizedTransportEquipments(ObjectNode transportDocument, Scen // These code must be aligned with the equipment references. var containerISOEquipmentCode = switch (scenarioType) { case REEFER -> "45R1"; - case REGULAR -> "22G1"; + case REGULAR_SWB, REGULAR_BOL -> "22G1"; case DG -> "22GP"; }; var consignmentItemsNode = transportDocument.path("consignmentItems"); diff --git a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/party/EblCarrier.java b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/party/EblCarrier.java index c260735f..5f81dfd4 100644 --- a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/party/EblCarrier.java +++ b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/party/EblCarrier.java @@ -85,7 +85,7 @@ private void supplyScenarioParameters(JsonNode actionPrompt) { var scenarioType = ScenarioType.valueOf(actionPrompt.required("scenarioType").asText()); CarrierScenarioParameters carrierScenarioParameters = switch (scenarioType) { - case REGULAR -> new CarrierScenarioParameters( + case REGULAR_SWB, REGULAR_BOL -> new CarrierScenarioParameters( "CBR_123_REGULAR", "Some Commodity Subreference 123", // A "22G1" container - keep aligned with the fixupUtilizedTransportEquipments() diff --git a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/party/EblShipper.java b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/party/EblShipper.java index 5abdcf9c..adc7be7a 100644 --- a/ebl/src/main/java/org/dcsa/conformance/standards/ebl/party/EblShipper.java +++ b/ebl/src/main/java/org/dcsa/conformance/standards/ebl/party/EblShipper.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import java.util.*; import java.util.function.Consumer; @@ -17,6 +18,7 @@ import org.dcsa.conformance.core.traffic.ConformanceRequest; import org.dcsa.conformance.core.traffic.ConformanceResponse; import org.dcsa.conformance.standards.ebl.action.*; +import org.dcsa.conformance.standards.ebl.checks.ScenarioType; @Slf4j public class EblShipper extends ConformanceParty { @@ -70,8 +72,9 @@ private void sendShippingInstructionsRequest(JsonNode actionPrompt) { CarrierScenarioParameters carrierScenarioParameters = CarrierScenarioParameters.fromJson(actionPrompt.get("csp")); + var scenarioType = ScenarioType.valueOf(actionPrompt.required("scenarioType").asText()); - JsonNode jsonRequestBody = + var jsonRequestBody = (ObjectNode) JsonToolkit.templateFileToJsonNode( "/standards/ebl/messages/ebl-api-v30-request.json", Map.ofEntries( @@ -88,15 +91,31 @@ private void sendShippingInstructionsRequest(JsonNode actionPrompt) { Map.entry("CONSIGNMENT_ITEM_HS_CODE", carrierScenarioParameters.consignmentItemHSCode()), Map.entry("DESCRIPTION_OF_GOODS_PLACEHOLDER", carrierScenarioParameters.descriptionOfGoods()), Map.entry("SERVICE_CONTRACT_REFERENCE_PLACEHOLDER", carrierScenarioParameters.serviceContractReference()), - Map.entry("CONTRACT_QUOTATION_REFERENCE_PLACEHOLDER", carrierScenarioParameters.contractQuotationReference()) + Map.entry("CONTRACT_QUOTATION_REFERENCE_PLACEHOLDER", carrierScenarioParameters.contractQuotationReference()), + Map.entry("TRANSPORT_DOCUMENT_TYPE_CODE_PLACEHOLDER", scenarioType.transportDocumentTypeCode()) )); + // Cannot substitute this because it is a boolean + jsonRequestBody.put("isToOrder", scenarioType.isToOrder()); + if (!scenarioType.isToOrder()) { + // Cannot substitute this because it is an array element + var parties = (ArrayNode) jsonRequestBody.path("documentParties"); + var consignee = parties.addObject(); + consignee.put("partyFunction", "CN") + .put("isToBeNotified", false) + .putObject("party") + .put("partyName", "DCSA CTK Consignee") + .putArray("partyContactDetails") + .addObject() + .put("name", "DCSA another test person") + .put("email", "no-reply@dcsa-consignee.example.org"); + } + ConformanceResponse conformanceResponse = syncCounterpartPost("/v3/shipping-instructions", jsonRequestBody); JsonNode jsonBody = conformanceResponse.message().body().getJsonBody(); String shippingInstructionsReference = jsonBody.path("shippingInstructionsReference").asText(); - ObjectNode updatedShippingInstructions = - ((ObjectNode) jsonRequestBody) + ObjectNode updatedShippingInstructions = jsonRequestBody .put("shippingInstructionsReference", shippingInstructionsReference); persistentMap.save(shippingInstructionsReference, updatedShippingInstructions); @@ -109,8 +128,10 @@ private void sendUpdatedShippingInstructionsRequest(JsonNode actionPrompt) { log.info("Shipper.sendUpdatedShippingInstructionsRequest(%s)".formatted(actionPrompt.toPrettyString())); var sir = actionPrompt.required("sir").asText(); + var documentReference = actionPrompt.required("documentReference").asText(); var si = (ObjectNode) persistentMap.load(sir); + // FIXME: We should be changing the seal number var pcd = si.required("partyContactDetails").required(0); var newName = "DCSA test person2"; if (pcd.required("name").asText("").equals(newName)) { @@ -118,12 +139,12 @@ private void sendUpdatedShippingInstructionsRequest(JsonNode actionPrompt) { } ((ObjectNode)pcd).put("name", newName); - ConformanceResponse conformanceResponse = syncCounterpartPut("/v3/shipping-instructions/%s".formatted(sir), si); + ConformanceResponse conformanceResponse = syncCounterpartPut("/v3/shipping-instructions/%s".formatted(documentReference), si); JsonNode jsonBody = conformanceResponse.message().body().getJsonBody(); String shippingInstructionsStatus = jsonBody.path("shippingInstructionsStatus").asText(); ObjectNode updatedBooking = si.put("shippingInstructionsStatus", shippingInstructionsStatus); - persistentMap.save(sir, updatedBooking); + persistentMap.save(documentReference, updatedBooking); addOperatorLogEntry( "Sent a shipping instructions update with the parameters: %s" @@ -167,15 +188,15 @@ private void approveDraftTransportDocument(JsonNode actionPrompt) { private void getShippingInstructionsRequest(JsonNode actionPrompt) { log.info("Shipper.getShippingInstructionsRequest(%s)".formatted(actionPrompt.toPrettyString())); - String sir = actionPrompt.get("sir").asText(); + String documentReference = actionPrompt.get("documentReference").asText(); boolean requestAmendment = actionPrompt.path("amendedContent").asBoolean(false); Map> queryParams = requestAmendment ? Map.of("amendedContent", List.of("true")) : Collections.emptyMap(); - syncCounterpartGet("/v3/shipping-instructions/" + sir, queryParams); + syncCounterpartGet("/v3/shipping-instructions/" + documentReference, queryParams); - addOperatorLogEntry("Sent a GET request for shipping instructions with SIR: %s".formatted(sir)); + addOperatorLogEntry("Sent a GET request for shipping instructions with documentReference: %s".formatted(documentReference)); } private void getTransportDocument(JsonNode actionPrompt) { diff --git a/ebl/src/main/resources/standards/ebl/messages/ebl-api-v30-request.json b/ebl/src/main/resources/standards/ebl/messages/ebl-api-v30-request.json index b1fa20d0..f8af912b 100644 --- a/ebl/src/main/resources/standards/ebl/messages/ebl-api-v30-request.json +++ b/ebl/src/main/resources/standards/ebl/messages/ebl-api-v30-request.json @@ -1,7 +1,7 @@ { - "transportDocumentTypeCode": "BOL", + "transportDocumentTypeCode": "TRANSPORT_DOCUMENT_TYPE_CODE_PLACEHOLDER", "isElectronic": true, - "isToOrder": true, + "isToOrder": false, "sendToPlatform": "BOLE", "freightPaymentTermCode": "PRE", "isShippedOnBoardType": true,