Skip to content

Commit

Permalink
DT-773: Create scenario with active reefer
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 13, 2023
1 parent 0cd46f4 commit 70fc87e
Show file tree
Hide file tree
Showing 9 changed files with 153 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.dcsa.conformance.core.scenario.ConformanceAction;
import org.dcsa.conformance.core.scenario.ScenarioListBuilder;
import org.dcsa.conformance.standards.ebl.action.*;
import org.dcsa.conformance.standards.ebl.checks.ScenarioType;
import org.dcsa.conformance.standards.ebl.party.ShippingInstructionsStatus;
import org.dcsa.conformance.standards.ebl.party.TransportDocumentStatus;

Expand Down Expand Up @@ -38,7 +39,10 @@ public static EblScenarioListBuilder buildTree(
threadLocalComponentFactory.set(componentFactory);
threadLocalCarrierPartyName.set(carrierPartyName);
threadLocalShipperPartyName.set(shipperPartyName);
return carrier_SupplyScenarioParameters().thenAllPathsFrom(SI_START);
return noAction().thenEither(
carrier_SupplyScenarioParameters(ScenarioType.REGULAR).thenAllPathsFrom(SI_START),
carrier_SupplyScenarioParameters(ScenarioType.REEFER).thenHappyPathFrom(SI_START)
);
}

private EblScenarioListBuilder thenAllPathsFrom(
Expand Down Expand Up @@ -119,6 +123,11 @@ yield thenEither(
private EblScenarioListBuilder thenHappyPathFrom(
ShippingInstructionsStatus shippingInstructionsStatus) {
return switch (shippingInstructionsStatus) {
case SI_START -> then(
uc1_shipper_submitShippingInstructions()
.then(
shipper_GetShippingInstructions(SI_RECEIVED, TD_START)
.thenHappyPathFrom(SI_RECEIVED)));
case SI_RECEIVED -> then(uc6_carrier_publishDraftTransportDocument()
.then(
shipper_GetShippingInstructions(SI_RECEIVED, TD_DRAFT, true)
Expand All @@ -134,7 +143,7 @@ private EblScenarioListBuilder thenHappyPathFrom(
);
case SI_COMPLETED -> then(noAction());
case SI_CANCELLED, SI_DECLINED -> throw new AssertionError("Please use the black state rather than DECLINED");
case SI_START, SI_ANY -> throw new AssertionError("Not a real/reachable state");
case SI_ANY -> throw new AssertionError("Not a real/reachable state");
};
}

Expand Down Expand Up @@ -255,10 +264,10 @@ private static EblScenarioListBuilder noAction() {
return new EblScenarioListBuilder(null);
}

private static EblScenarioListBuilder carrier_SupplyScenarioParameters() {
private static EblScenarioListBuilder carrier_SupplyScenarioParameters(ScenarioType scenarioType) {
String carrierPartyName = threadLocalCarrierPartyName.get();
return new EblScenarioListBuilder(
previousAction -> new Carrier_SupplyScenarioParametersAction(carrierPartyName));
previousAction -> new Carrier_SupplyScenarioParametersAction(carrierPartyName, scenarioType));
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,29 @@
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.util.function.Consumer;
import java.util.function.Supplier;

import lombok.NonNull;
import org.dcsa.conformance.standards.ebl.checks.ScenarioType;
import org.dcsa.conformance.standards.ebl.party.CarrierScenarioParameters;
import org.dcsa.conformance.standards.ebl.party.DynamicScenarioParameters;

public class Carrier_SupplyScenarioParametersAction extends EblAction {
private CarrierScenarioParameters carrierScenarioParameters = null;

public Carrier_SupplyScenarioParametersAction(String carrierPartyName) {
super(carrierPartyName, null, null, "SupplyCSP", -1);
private ScenarioType scenarioType;

public Carrier_SupplyScenarioParametersAction(String carrierPartyName, @NonNull ScenarioType scenarioType) {
super(
carrierPartyName,
null,
null,
switch (scenarioType) {
case REGULAR -> "SupplyCSP";
case REEFER -> "SupplyCSP-AR";
},
-1);
this.scenarioType = scenarioType;
this.getDspConsumer().accept(getDspSupplier().get().withScenarioType(scenarioType));
}

@Override
Expand All @@ -19,13 +35,19 @@ public void reset() {
carrierScenarioParameters = null;
}

@Override
public ObjectNode asJsonNode() {
return super.asJsonNode()
.put("scenarioType", scenarioType.name());
}

@Override
public ObjectNode exportJsonState() {
ObjectNode jsonState = super.exportJsonState();
if (carrierScenarioParameters != null) {
jsonState.set("carrierScenarioParameters", carrierScenarioParameters.toJson());
}
return jsonState;
return jsonState.put("scenarioType", scenarioType.name());
}

@Override
Expand All @@ -35,6 +57,7 @@ public void importJsonState(JsonNode jsonState) {
if (cspNode != null) {
carrierScenarioParameters = CarrierScenarioParameters.fromJson(cspNode);
}
this.scenarioType = ScenarioType.valueOf(jsonState.required("scenarioType").asText());
}

@Override
Expand All @@ -44,15 +67,27 @@ public String getHumanReadablePrompt() {

@Override
public JsonNode getJsonForHumanReadablePrompt() {
return new CarrierScenarioParameters(
"Booking ref X",
"Commodity Subref for X",
"APZU4812090",
"DKCPH",
"Consignment Item HS Code",
"Shoes"

).toJson();
var csp = switch (scenarioType) {
case REGULAR -> new CarrierScenarioParameters(
"Booking Reference",
"Commodity subreference for regular (non-DG, non-reefer) cargo",
// Any valid regular equipment reference will do as an example.
"NARU3472484",
"DKCPH",
"851712",
"300 boxes of blue shoes size 47"
);
case REEFER -> new CarrierScenarioParameters(
"Booking Reference",
"Commodity subreference for cargo requiring an *active* reefer",
// Any valid reefer equipment reference will do as an example.
"BBCU5200220",
"DKCPH",
"04052090",
"Dairy products"
);
};
return csp.toJson();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.dcsa.conformance.core.traffic.ConformanceExchange;
import org.dcsa.conformance.core.traffic.HttpMessageType;
import org.dcsa.conformance.standards.ebl.checks.EBLChecks;
import org.dcsa.conformance.standards.ebl.checks.ScenarioType;
import org.dcsa.conformance.standards.ebl.party.*;

import java.util.UUID;
Expand All @@ -31,7 +32,7 @@ public EblAction(
this.dspReference =
previousAction == null
? new OverwritingReference<>(
null, new DynamicScenarioParameters(null, null, null, null, null))
null, new DynamicScenarioParameters(ScenarioType.REGULAR, null, null, null, null, null))
: new OverwritingReference<>(previousAction.dspReference, null);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ public String getHumanReadablePrompt() {

@Override
public ObjectNode asJsonNode() {
var dsp = getDspSupplier().get();
return super.asJsonNode()
.put("documentReference", getDspSupplier().get().transportDocumentReference());
.put("documentReference", dsp.transportDocumentReference())
.put("scenarioType", dsp.scenarioType().name());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ public String getHumanReadablePrompt() {

@Override
public ObjectNode asJsonNode() {
var dsp = getDspSupplier().get();
return super.asJsonNode()
.put("documentReference", getDspSupplier().get().shippingInstructionsReference());
.put("documentReference", dsp.shippingInstructionsReference())
.put("scenarioType", dsp.scenarioType().name());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.dcsa.conformance.standards.ebl.checks;

public enum ScenarioType {
REGULAR,
REEFER,
;
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.util.*;
import java.util.function.*;
import org.dcsa.conformance.core.state.JsonNodeMap;
import org.dcsa.conformance.standards.ebl.checks.ScenarioType;
import org.dcsa.conformance.standards.ebl.party.ShippingInstructionsStatus;
import org.dcsa.conformance.standards.ebl.party.TransportDocumentStatus;

Expand Down Expand Up @@ -327,9 +328,9 @@ public void voidTransportDocument(String documentReference) {
td.put(TRANSPORT_DOCUMENT_STATUS, TD_VOIDED.wireName());
}

public void issueAmendedTransportDocument(String documentReference) {
public void issueAmendedTransportDocument(String documentReference, ScenarioType scenarioType) {
checkState(documentReference, getTransportDocumentState(), s -> s == TD_VOIDED);
this.generateDraftTD();
this.generateDraftTD(scenarioType);
updateTDForIssuance();
var tdData = getTransportDocument().orElseThrow();
var tdr = tdData.required(TRANSPORT_DOCUMENT_REFERENCE).asText();
Expand All @@ -354,13 +355,13 @@ public void rejectSurrenderForDelivery(String documentReference) {
td.put(TRANSPORT_DOCUMENT_STATUS, TD_ISSUED.wireName());
}

public void publishDraftTransportDocument(String documentReference) {
public void publishDraftTransportDocument(String documentReference, ScenarioType scenarioType) {
// We allow draft when:
// 1) The original ("black") state is RECEIVED, *and*
// 2) There is no update received (that is "grey" is not UPDATE_RECEIVED)
checkState(documentReference, getOriginalShippingInstructionState(), s -> s == SI_RECEIVED);
checkState(documentReference, getOriginalShippingInstructionState(), s -> s != SI_UPDATE_RECEIVED);
this.generateDraftTD();
this.generateDraftTD(scenarioType);
var tdData = getTransportDocument().orElseThrow();
var tdr = tdData.required(TRANSPORT_DOCUMENT_REFERENCE).asText();
mutateShippingInstructionsAndUpdate(si -> si.put(TRANSPORT_DOCUMENT_REFERENCE, tdr));
Expand Down Expand Up @@ -432,25 +433,37 @@ private void fixupConsignmentItems(ObjectNode transportDocument) {
}
}

private void fixupUtilizedTransportEquipments(ObjectNode transportDocument) {
private void fixupUtilizedTransportEquipments(ObjectNode transportDocument, ScenarioType scenarioType) {
var containerISOEquipmentCode = switch (scenarioType) {
case REEFER -> "22RB";
case REGULAR -> "22G1";
};
for (JsonNode node : transportDocument.path("utilizedTransportEquipments")) {
if (!node.isObject()) {
continue;
}
ObjectNode ute = (ObjectNode)node;
var ref = ute.path("equipmentReference");
ute.putObject("equipment").set("equipmentReference", ref);
ute.putObject("equipment")
.put("ISOEquipmentCode", containerISOEquipmentCode)
.set("equipmentReference", ref);
ute.remove("equipmentReference");
if (scenarioType == ScenarioType.REEFER) {
ute.put("isNonOperatingReefer", false)
.putObject("activeReeferSettings")
.put("temperatureSetpoint", -18)
.put("temperatureUnit", "CEL");
}
}
}

private void generateDraftTD() {
private void generateDraftTD(ScenarioType scenarioType) {
var td = OBJECT_MAPPER.createObjectNode();
var siData = getShippingInstructions();
var existingTd = getTransportDocument().orElse(null);
copyFieldsWherePresent(siData, td, COPY_SI_INTO_TD_FIELDS);
preserveOrGenerateCarrierFields(existingTd, td);
fixupUtilizedTransportEquipments(td);
fixupUtilizedTransportEquipments(td, scenarioType);
fixupConsignmentItems(td);
state.set(TD_DATA_FIELD, td);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,55 +3,53 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.NonNull;
import lombok.With;
import org.dcsa.conformance.standards.ebl.checks.ScenarioType;

import java.util.function.Function;

@With
public record DynamicScenarioParameters(
@NonNull
ScenarioType scenarioType,
String shippingInstructionsReference,
String transportDocumentReference,
ShippingInstructionsStatus shippingInstructionsStatus,
ShippingInstructionsStatus updatedShippingInstructionsStatus,
TransportDocumentStatus transportDocumentStatus) {
public ObjectNode toJson() {
ObjectNode dspNode = new ObjectMapper().createObjectNode();
if (shippingInstructionsReference != null) {
dspNode.put("shippingInstructionsReference", shippingInstructionsReference);
}
if (transportDocumentReference != null) {
dspNode.put("transportDocumentReference", transportDocumentReference);
}
if (shippingInstructionsStatus != null) {
dspNode.put("shippingInstructionsStatus", shippingInstructionsStatus.wireName());
}
if (updatedShippingInstructionsStatus != null) {
dspNode.put(
"updatedShippingInstructionsStatus", updatedShippingInstructionsStatus.wireName());
return new ObjectMapper().createObjectNode()
.put("scenarioType", scenarioType.name())
.put("shippingInstructionsReference", shippingInstructionsReference)
.put("transportDocumentReference", transportDocumentReference)
.put("shippingInstructionsStatus", serializeEnum(shippingInstructionsStatus, ShippingInstructionsStatus::wireName))
.put("updatedShippingInstructionsStatus", serializeEnum(updatedShippingInstructionsStatus, ShippingInstructionsStatus::wireName))
.put("transportDocumentStatus", serializeEnum(transportDocumentStatus, TransportDocumentStatus::wireName));
}

private static <E extends Enum<E>> String serializeEnum(E v, Function<E, String> mapper) {
if (v == null) {
return null;
}
if (transportDocumentStatus != null) {
dspNode.put("transportDocumentStatus", transportDocumentStatus.wireName());
return mapper.apply(v);
}

private static <E> E readEnum(String value, Function<String, E> mapper) {
if (value == null) {
return null;
}
return dspNode;
return mapper.apply(value);
}

public static DynamicScenarioParameters fromJson(JsonNode jsonNode) {
ObjectNode dspNode = (ObjectNode) jsonNode;
return new DynamicScenarioParameters(
dspNode.has("shippingInstructionsReference")
? dspNode.get("shippingInstructionsReference").asText()
: null,
dspNode.has("transportDocumentReference")
? dspNode.get("transportDocumentReference").asText()
: null,
dspNode.has("shippingInstructionsStatus")
? ShippingInstructionsStatus.fromWireName(
dspNode.get("shippingInstructionsStatus").asText())
: null,
dspNode.has("updatedShippingInstructionsStatus")
? ShippingInstructionsStatus.fromWireName(
dspNode.get("updatedShippingInstructionsStatus").asText())
: null,
dspNode.has("transportDocumentStatus")
? TransportDocumentStatus.fromWireName(dspNode.get("transportDocumentStatus").asText())
: null);
readEnum(jsonNode.required("scenarioType").asText(), ScenarioType::valueOf),
jsonNode.path("shippingInstructionsReference").asText(null),
jsonNode.path("transportDocumentReference").asText(null),
readEnum(jsonNode.required("shippingInstructionsStatus").asText(null), ShippingInstructionsStatus::fromWireName),
readEnum(jsonNode.required("updatedShippingInstructionsStatus").asText(null), ShippingInstructionsStatus::fromWireName),
readEnum(jsonNode.required("transportDocumentStatus").asText(null), TransportDocumentStatus::fromWireName)
);
}
}
Loading

0 comments on commit 70fc87e

Please sign in to comment.