Skip to content

Commit

Permalink
DT-632: UC4 - Carrier - Process updated shipping instructions
Browse files Browse the repository at this point in the history
Signed-off-by: Niels Thykier <[email protected]>
  • Loading branch information
nt-gt committed Dec 5, 2023
1 parent b57e2c5 commit bf8393f
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,26 +49,59 @@ private EblScenarioListBuilder thenAllPathsFrom(
case SI_RECEIVED -> thenEither(
uc2_carrier_requestUpdateToShippingInstruction()
.then(shipper_GetShippingInstructions(SI_PENDING_UPDATE, TD_START)
.thenHappyPathFrom(SI_PENDING_UPDATE)),
.thenAllPathsFrom(SI_PENDING_UPDATE)),
uc3_shipper_submitUpdatedShippingInstructions()
.then(
shipper_GetShippingInstructions(SI_RECEIVED, SI_UPDATE_RECEIVED, TD_START)
.then(
uc2_carrier_requestUpdateToShippingInstruction()
.then(shipper_GetShippingInstructions(SI_PENDING_UPDATE, TD_START)
.thenHappyPathFrom(SI_PENDING_UPDATE)))),
.thenAllPathsFrom(SI_UPDATE_RECEIVED)),
uc6_carrier_publishDraftTransportDocument()
.then(
shipper_GetShippingInstructions(SI_RECEIVED, TD_DRAFT, true)
.then(shipper_GetTransportDocument(TD_DRAFT)
.thenAllPathsFrom(TD_DRAFT))));
case SI_UPDATE_RECEIVED -> thenEither(
uc2_carrier_requestUpdateToShippingInstruction()
.then(shipper_GetShippingInstructions(SI_PENDING_UPDATE, TD_START)
.thenHappyPathFrom(SI_PENDING_UPDATE)),
uc4a_carrier_acceptUpdatedShippingInstructions()
.then(shipper_GetShippingInstructions(SI_RECEIVED, TD_START)
.thenHappyPathFrom(SI_RECEIVED)),
uc4d_carrier_declineUpdatedShippingInstructions()
.then(shipper_GetShippingInstructions(SI_RECEIVED, SI_DECLINED, TD_START)
.thenAllPathsFrom(SI_DECLINED)));
case SI_DECLINED -> thenEither(
uc6_carrier_publishDraftTransportDocument()
.then(shipper_GetShippingInstructions(SI_RECEIVED, TD_DRAFT, true)
.then(shipper_GetTransportDocument(TD_DRAFT)
.thenHappyPathFrom(TD_DRAFT))),
uc2_carrier_requestUpdateToShippingInstruction()
.then(shipper_GetShippingInstructions(SI_PENDING_UPDATE, TD_START)
.thenHappyPathFrom(SI_PENDING_UPDATE)),
uc3_shipper_submitUpdatedShippingInstructions()
.then(shipper_GetShippingInstructions(SI_UPDATE_RECEIVED, TD_START)
.thenHappyPathFrom(SI_UPDATE_RECEIVED)));
default -> then(noAction()); // TODO
};
}

private EblScenarioListBuilder thenHappyPathFrom(
ShippingInstructionsStatus shippingInstructionsStatus) {
return then(noAction()); // TODO
return switch (shippingInstructionsStatus) {
case SI_RECEIVED, SI_DECLINED -> then(uc6_carrier_publishDraftTransportDocument()
.then(
shipper_GetShippingInstructions(SI_RECEIVED, TD_DRAFT, true)
.then(shipper_GetTransportDocument(TD_DRAFT)
.thenHappyPathFrom(TD_DRAFT))));
case SI_PENDING_UPDATE -> then(uc3_shipper_submitUpdatedShippingInstructions()
.then(
shipper_GetShippingInstructions(SI_RECEIVED, SI_UPDATE_RECEIVED, TD_START)
.thenHappyPathFrom(SI_UPDATE_RECEIVED)));
case SI_UPDATE_RECEIVED -> then(uc4a_carrier_acceptUpdatedShippingInstructions()
.then(shipper_GetShippingInstructions(SI_RECEIVED, TD_START)
.thenHappyPathFrom(SI_RECEIVED))
);
default -> then(noAction()); // TODO
};
}

private EblScenarioListBuilder thenAllPathsFrom(TransportDocumentStatus transportDocumentStatus) {
Expand Down Expand Up @@ -201,6 +234,36 @@ private static EblScenarioListBuilder uc2_carrier_requestUpdateToShippingInstruc
EBL_NOTIFICATIONS_API, EBL_SI_NOTIFICATION_SCHEMA_NAME)));
}

private static EblScenarioListBuilder uc4a_carrier_acceptUpdatedShippingInstructions() {
EblComponentFactory componentFactory = threadLocalComponentFactory.get();
String carrierPartyName = threadLocalCarrierPartyName.get();
String shipperPartyName = threadLocalShipperPartyName.get();
return new EblScenarioListBuilder(
previousAction ->
new UC4_Carrier_ProcessUpdateToShippingInstructionsAction(
carrierPartyName,
shipperPartyName,
(EblAction) previousAction,
componentFactory.getMessageSchemaValidator(
EBL_NOTIFICATIONS_API, EBL_SI_NOTIFICATION_SCHEMA_NAME),
true));
}

private static EblScenarioListBuilder uc4d_carrier_declineUpdatedShippingInstructions() {
EblComponentFactory componentFactory = threadLocalComponentFactory.get();
String carrierPartyName = threadLocalCarrierPartyName.get();
String shipperPartyName = threadLocalShipperPartyName.get();
return new EblScenarioListBuilder(
previousAction ->
new UC4_Carrier_ProcessUpdateToShippingInstructionsAction(
carrierPartyName,
shipperPartyName,
(EblAction) previousAction,
componentFactory.getMessageSchemaValidator(
EBL_NOTIFICATIONS_API, EBL_SI_NOTIFICATION_SCHEMA_NAME),
false));
}

private static EblScenarioListBuilder uc6_carrier_publishDraftTransportDocument() {
EblComponentFactory componentFactory = threadLocalComponentFactory.get();
String carrierPartyName = threadLocalCarrierPartyName.get();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package org.dcsa.conformance.standards.ebl.action;

import com.fasterxml.jackson.databind.node.ObjectNode;
import java.util.stream.Stream;
import lombok.Getter;
import org.dcsa.conformance.core.check.*;

@Getter
public class UC4_Carrier_ProcessUpdateToShippingInstructionsAction extends StateChangingSIAction {
private final JsonSchemaValidator requestSchemaValidator;
private final boolean acceptChanges;

public UC4_Carrier_ProcessUpdateToShippingInstructionsAction(
String carrierPartyName,
String shipperPartyName,
EblAction previousAction,
JsonSchemaValidator requestSchemaValidator,
boolean acceptChanges) {
super(carrierPartyName, shipperPartyName, previousAction, acceptChanges ? "UC4a" : "UC4d", 204);
this.requestSchemaValidator = requestSchemaValidator;
this.acceptChanges = acceptChanges;
}

@Override
public String getHumanReadablePrompt() {
if (acceptChanges) {
return ("UC4: Accept updated shipping instructions with document reference %s"
.formatted(getDspSupplier().get().shippingInstructionsReference()));
}
return ("UC4: Decline updated shipping instructions with document reference %s"
.formatted(getDspSupplier().get().shippingInstructionsReference()));
}

@Override
public ObjectNode asJsonNode() {
return super.asJsonNode()
.put("documentReference", getDspSupplier().get().shippingInstructionsReference())
.put("acceptChanges", acceptChanges);
}

@Override
public ConformanceCheck createCheck(String expectedApiVersion) {
return new ConformanceCheck(getActionTitle()) {
@Override
protected Stream<? extends ConformanceCheck> createSubChecks() {
return getSINotificationChecks(
getMatchedExchangeUuid(),
expectedApiVersion,
requestSchemaValidator
);
}
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,8 @@ public class CarrierShippingInstructions {

private static final Set<ShippingInstructionsStatus> PENDING_UPDATE_PREREQUISITE_STATES = Set.of(
SI_RECEIVED,
SI_UPDATE_RECEIVED
);

private static final Set<ShippingInstructionsStatus> DRAFT_TRANSPORT_DOCUMENT_PREREQUISITE_STATES = Set.of(
SI_RECEIVED,
SI_UPDATE_RECEIVED
SI_UPDATE_RECEIVED,
SI_DECLINED
);

private static final String SI_STATUS = "shippingInstructionsStatus";
Expand Down Expand Up @@ -174,9 +170,20 @@ public void acceptUpdatedShippingInstructions(String documentReference) {
changeSIState(SI_STATUS, SI_RECEIVED);
}

public void declineUpdatedShippingInstructions(String documentReference, String reason) {
checkState(documentReference, getShippingInstructionsState(), s -> s == SI_UPDATE_RECEIVED);
var updated = getUpdatedShippingInstructions().orElseThrow();
setShippingInstructions(updated);
clearUpdatedShippingInstructions();
setReason(reason);
mutateShippingInstructionsAndUpdate(siData -> siData.remove("requestedChanges"));
changeSIState(UPDATED_SI_STATUS, SI_DECLINED);
}

public void publishDraftTransportDocument(String documentReference) {
checkState(documentReference, getShippingInstructionsState(), s -> s == SI_RECEIVED);
assert getUpdatedShippingInstructions().isEmpty();
// SI_DECLINED only applies to the updated SI. UC1 -> UC3 -> UC4 (decline) -> UC6 is applicable and
// in this case, the SI would be in RECEIVED with updated state SI_DECLINED.
checkState(documentReference, getShippingInstructionsState(), s -> s == SI_RECEIVED || s == SI_DECLINED);
this.generateTDFromSI();
var tdData = getTransportDocument().orElseThrow();
var tdr = tdData.required(TRANSPORT_DOCUMENT_REFERENCE).asText();
Expand Down Expand Up @@ -272,7 +279,7 @@ public void putShippingInstructions(String documentReference, ObjectNode newShip
checkState(
documentReference,
currentState,
s -> s != SI_DECLINED && s != SI_COMPLETED
s -> s != SI_COMPLETED
);
changeSIState(UPDATED_SI_STATUS, SI_UPDATE_RECEIVED);
copyMetadataFields(getShippingInstructions(), newShippingInstructionData);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@
import org.dcsa.conformance.core.traffic.ConformanceMessageBody;
import org.dcsa.conformance.core.traffic.ConformanceRequest;
import org.dcsa.conformance.core.traffic.ConformanceResponse;
import org.dcsa.conformance.standards.ebl.action.Carrier_SupplyScenarioParametersAction;
import org.dcsa.conformance.standards.ebl.action.UC2_Carrier_RequestUpdateToShippingInstructionsAction;
import org.dcsa.conformance.standards.ebl.action.UC6_Carrier_PublishDraftTransportDocumentAction;
import org.dcsa.conformance.standards.ebl.action.UC8_Carrier_IssueTransportDocumentAction;
import org.dcsa.conformance.standards.ebl.action.*;
import org.dcsa.conformance.standards.ebl.models.CarrierShippingInstructions;

@Slf4j
Expand Down Expand Up @@ -74,6 +71,7 @@ protected Map<Class<? extends ConformanceAction>, Consumer<JsonNode>> getActionP
return Map.ofEntries(
Map.entry(Carrier_SupplyScenarioParametersAction.class, this::supplyScenarioParameters),
Map.entry(UC2_Carrier_RequestUpdateToShippingInstructionsAction.class, this::requestUpdateToShippingInstructions),
Map.entry(UC4_Carrier_ProcessUpdateToShippingInstructionsAction.class, this::processUpdatedShippingInstructions),
Map.entry(UC6_Carrier_PublishDraftTransportDocumentAction.class, this::publishDraftTransportDocument),
Map.entry(UC8_Carrier_IssueTransportDocumentAction.class, this::issueTransportDocument)
);
Expand All @@ -93,7 +91,7 @@ private void supplyScenarioParameters(JsonNode actionPrompt) {
asyncOrchestratorPostPartyInput(
OBJECT_MAPPER
.createObjectNode()
.put("actionId", actionPrompt.get("actionId").asText())
.put("actionId", actionPrompt.required("actionId").asText())
.set("input", carrierScenarioParameters.toJson()));
addOperatorLogEntry(
"Provided CarrierScenarioParameters: %s".formatted(carrierScenarioParameters));
Expand All @@ -102,7 +100,7 @@ private void supplyScenarioParameters(JsonNode actionPrompt) {
private void requestUpdateToShippingInstructions(JsonNode actionPrompt) {
log.info("Carrier.requestUpdateToShippingInstructions(%s)".formatted(actionPrompt.toPrettyString()));

var documentReference = actionPrompt.get("documentReference").asText();
var documentReference = actionPrompt.required("documentReference").asText();
var sir = tdrToSir.getOrDefault(documentReference, documentReference);

var si = CarrierShippingInstructions.fromPersistentStore(persistentMap, sir);
Expand All @@ -116,6 +114,25 @@ private void requestUpdateToShippingInstructions(JsonNode actionPrompt) {
}


private void processUpdatedShippingInstructions(JsonNode actionPrompt) {
log.info("Carrier.processUpdatedShippingInstructions(%s)".formatted(actionPrompt.toPrettyString()));

var documentReference = actionPrompt.required("documentReference").asText();
var accept = actionPrompt.required("acceptChanges").asBoolean(true);
var sir = tdrToSir.getOrDefault(documentReference, documentReference);

var si = CarrierShippingInstructions.fromPersistentStore(persistentMap, sir);
if (accept) {
si.acceptUpdatedShippingInstructions(documentReference);
} else {
si.declineUpdatedShippingInstructions(documentReference, "Declined as requested by the Conformance orchestrator");
}
si.save(persistentMap);
generateAndEmitNotificationFromShippingInstructions(actionPrompt, si, true);

addOperatorLogEntry("Processed update to the shipping instructions with document reference '%s'".formatted(documentReference));
}

private void publishDraftTransportDocument(JsonNode actionPrompt) {
log.info("Carrier.publishDraftTransportDocument(%s)".formatted(actionPrompt.toPrettyString()));

Expand Down

0 comments on commit bf8393f

Please sign in to comment.