Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DT-773: Create scenario with active reefer #35

Merged
merged 1 commit into from
Dec 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading