From e797cfc52fb92bf56053e09f7c72ab73f3149165 Mon Sep 17 00:00:00 2001 From: Niels Thykier Date: Tue, 31 Oct 2023 13:29:17 +0100 Subject: [PATCH] Refactor: Rewrite and simplify the data model for booking The carrier SMEs have decided that there should be one and only one endpoint for bookings. This means the distinguish between a `BookingRequest` and `ConfirmedBooking` should no longer be entity but only status level changes. To prepare for that, I have rewritten the data model with this focus in mind. In this rewrite, `BookingRequest` and `ConfirmedBooking` are replaced by `Booking` and `BookingData`. The `BookingData` contains the combined set of attributes from `BookingRequest` and `ConfirmedBooking` with a very few "meta data" attributes (such as `carrierBookingRequestReference`, `carrierBookingReference`, and the `bookingStatus`). Everything else is in the `BookingData` entity. Because this is a massive internal rewrite, I made it a goal to keep the postman test passing running without any changes to the postman collection. This should give us confidence that this is purely an internal "implementation-detail"-level rewrite. No externally visible contracts have chanced. Other notes: * Henrik is still working on the updated Swagger specs for the new design. It is currently a private draft at [DRAFT-SWAGGER] * I made *no* changes to TOss. Again to avoid changing the postman tests. I expect we will able to regnerate those once Henrik is done with the swagger rewrite. - There are also no *externally* visisble changes to controllers for the same reason. The only change is a rename of a method in a service used by a controller). * Most of the SQL changes is removing now redundant SQL test data. Most of it became redundant with the removal of the summaries endpoint, but was not removed at the time. I removed it in this commit because the data was not used anyway and in some cases violated "1-1" constraints (we had multiple ConfirmedBookings linking to the BookingRequest, which is no longer possible in the new data model design). * I had to keep some "dead" attributes around (such as the "create" and "update" timestamps) because they are required by a JSON schema in the postman collection. The reference implementation does not maintain these field as strictly as before as they are scheduled for removal (DT-389). Just enough to satisify the JSON schema requirement to avoid having to touch the postman collection. I have spinkled TODO around with a refrence to DT-389 where I thought it was relevant. [DRAFT-SWAGGER]: https://app.swaggerhub.com/apis/dcsaorg/DCSA_BKG/2.0.0-Beta-1-Henrik Signed-off-by: Niels Thykier --- .../controller/BookingRequestController.java | 2 +- .../ManageConfirmedBookingController.java | 3 +- .../entity/AdvanceManifestFiling.java | 5 +- .../domain/persistence/entity/Booking.java | 277 ++++ .../persistence/entity/BookingData.java | 299 ++++ .../persistence/entity/BookingRequest.java | 443 ------ .../entity/BookingRequestedChange.java | 2 +- .../domain/persistence/entity/Charge.java | 4 +- .../persistence/entity/ConfirmedBooking.java | 133 +- .../entity/ConfirmedEquipment.java | 4 +- .../persistence/entity/ConsignmentItem.java | 11 +- .../persistence/entity/DocumentParty.java | 4 +- .../domain/persistence/entity/Reference.java | 4 +- .../entity/RequestedEquipmentGroup.java | 4 +- .../entity/ShipmentCutOffTime.java | 4 +- .../persistence/entity/ShipmentLocation.java | 10 +- .../persistence/entity/ShipmentTransport.java | 4 +- .../entity/ShippingInstruction.java | 11 +- .../persistence/entity/TransportDocument.java | 2 +- .../repository/BookingRepository.java | 18 + .../repository/BookingRequestRepository.java | 21 - .../ConfirmedBookingRepository.java | 20 - ...dation.java => BookingDataValidation.java} | 2 +- .../validations/BookingRequestValidator.java | 9 +- .../validations/ConsignmentItemValidator.java | 8 +- .../ShippingInstructionValidator.java | 39 +- .../db/migration/V3_0__dcsa_im_v3.sql | 135 +- ...V5_0__reference_implementation_support.sql | 20 - .../resources/db/migration/V6_0__metadata.sql | 6 - .../db/testdata.d/V8_1__test_data_ebl.sql | 1275 +++-------------- .../db/testdata.d/V8_4__test_data_bkg.sql | 185 +-- .../BookingRequestStateMachineTest.java | 58 - .../booking/BookingStateMachineTest.java | 53 + .../service/BookingRequestService.java | 98 +- .../service/ConfirmedBookingService.java | 14 +- .../service/DocumentPartyService.java | 19 +- .../service/ReferenceService.java | 15 +- .../service/ShipmentLocationService.java | 15 +- .../service/ShipmentTransportService.java | 6 +- .../service/ShippingInstructionService.java | 13 +- .../service/TransportDocumentService.java | 24 +- .../mapping/AdvanceManifestFilingMapper.java | 4 +- ...uestMapper.java => BookingDataMapper.java} | 28 +- .../service/mapping/BookingMapper.java | 84 ++ .../mapping/ConfirmedBookingMapper.java | 30 - .../mapping/ConfirmedEquipmentMapper.java | 2 +- .../mapping/ConsignmentItemMapper.java | 3 +- .../service/mapping/DocumentPartyMapper.java | 6 +- .../service/mapping/ReferenceMapper.java | 13 +- .../RequestedEquipmentGroupMapper.java | 2 +- .../mapping/ShipmentCutOffTimeMapper.java | 2 +- .../mapping/ShipmentLocationMapper.java | 15 +- .../mapping/ShipmentTransportMapper.java | 6 +- .../mapping/TransportDocumentMapper.java | 44 +- .../unofficial/ManageShipmentService.java | 111 +- .../UnofficialBookingRequestService.java | 45 +- .../UnofficialTransportDocumentService.java | 9 +- .../datafactories/BookingDataFactory.java | 284 ++-- .../ConfirmedBookingDataFactory.java | 61 - .../ShipmentLocationDataFactory.java | 15 +- .../ShippingInstructionDataFactory.java | 123 +- .../service/BookingRequestServiceTest.java | 72 +- .../service/DocumentPartyServiceTest.java | 13 +- .../service/ReferenceServiceTest.java | 27 +- 64 files changed, 1467 insertions(+), 2811 deletions(-) create mode 100644 edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/Booking.java create mode 100644 edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/BookingData.java delete mode 100644 edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/BookingRequest.java create mode 100644 edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/repository/BookingRepository.java delete mode 100644 edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/repository/BookingRequestRepository.java delete mode 100644 edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/repository/ConfirmedBookingRepository.java rename edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/validations/{BookingRequestValidation.java => BookingDataValidation.java} (94%) delete mode 100644 edocumentation-domain/src/test/java/org/dcsa/edocumentation/domain/booking/BookingRequestStateMachineTest.java create mode 100644 edocumentation-domain/src/test/java/org/dcsa/edocumentation/domain/booking/BookingStateMachineTest.java rename edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/{BookingRequestMapper.java => BookingDataMapper.java} (55%) create mode 100644 edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/BookingMapper.java delete mode 100644 edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/ConfirmedBookingMapper.java delete mode 100644 edocumentation-service/src/test/java/org/dcsa/edocumentation/datafactories/ConfirmedBookingDataFactory.java diff --git a/edocumentation-application/src/main/java/org/dcsa/edocumentation/controller/BookingRequestController.java b/edocumentation-application/src/main/java/org/dcsa/edocumentation/controller/BookingRequestController.java index 9d8e4a3c..a6e4b82a 100644 --- a/edocumentation-application/src/main/java/org/dcsa/edocumentation/controller/BookingRequestController.java +++ b/edocumentation-application/src/main/java/org/dcsa/edocumentation/controller/BookingRequestController.java @@ -93,7 +93,7 @@ public BookingRequestRefStatusTO cancelBookingRequest( if (!bookingCancelRequestTO.bookingStatus().equals(BookingStatus.CANCELLED)) { throw ConcreteRequestErrorMessageException.invalidInput("bookingStatus must be CANCELLED"); } - return bookingRequestService.cancelBookingRequest(carrierBookingRequestReference, bookingCancelRequestTO.reason()) + return bookingRequestService.cancelBooking(carrierBookingRequestReference, bookingCancelRequestTO.reason()) .orElseThrow( () -> ConcreteRequestErrorMessageException.notFound( diff --git a/edocumentation-application/src/main/java/org/dcsa/edocumentation/controller/unofficial/ManageConfirmedBookingController.java b/edocumentation-application/src/main/java/org/dcsa/edocumentation/controller/unofficial/ManageConfirmedBookingController.java index 5e5e93ac..4510d6db 100644 --- a/edocumentation-application/src/main/java/org/dcsa/edocumentation/controller/unofficial/ManageConfirmedBookingController.java +++ b/edocumentation-application/src/main/java/org/dcsa/edocumentation/controller/unofficial/ManageConfirmedBookingController.java @@ -1,5 +1,6 @@ package org.dcsa.edocumentation.controller.unofficial; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.dcsa.edocumentation.service.unofficial.ManageShipmentService; import org.dcsa.edocumentation.transferobjects.unofficial.ConfirmedBookingRefStatusTO; @@ -11,8 +12,6 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; -import jakarta.validation.Valid; - @Validated @RestController @RequiredArgsConstructor diff --git a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/AdvanceManifestFiling.java b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/AdvanceManifestFiling.java index 19425664..d894a8c1 100644 --- a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/AdvanceManifestFiling.java +++ b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/AdvanceManifestFiling.java @@ -16,10 +16,11 @@ public class AdvanceManifestFiling { @GeneratedValue @Id private UUID manifest_id; + @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) - @JoinColumn(name = "confirmed_booking_id") + @JoinColumn(name = "booking_data_id") @Setter(AccessLevel.PACKAGE) - private ConfirmedBooking confirmedBooking; + private BookingData bookingData; @Column(name = "manifest_type_code") private String manifestTypeCode; diff --git a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/Booking.java b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/Booking.java new file mode 100644 index 00000000..38336834 --- /dev/null +++ b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/Booking.java @@ -0,0 +1,277 @@ +package org.dcsa.edocumentation.domain.persistence.entity; + +import static org.dcsa.edocumentation.infra.enums.BookingStatus.*; + +import jakarta.persistence.*; +import jakarta.validation.Validator; +import jakarta.validation.constraints.NotNull; + +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import lombok.*; +import lombok.extern.slf4j.Slf4j; +import org.dcsa.edocumentation.domain.dfa.AbstractStateMachine; +import org.dcsa.edocumentation.domain.dfa.CannotLeaveTerminalStateException; +import org.dcsa.edocumentation.domain.dfa.DFADefinition; +import org.dcsa.edocumentation.domain.dfa.TargetStateIsNotSuccessorException; +import org.dcsa.edocumentation.domain.persistence.entity.unofficial.ValidationResult; +import org.dcsa.edocumentation.domain.validations.*; +import org.dcsa.edocumentation.infra.enums.BookingStatus; +import org.dcsa.edocumentation.infra.validation.StringEnumValidation; +import org.dcsa.skernel.errors.exceptions.ConcreteRequestErrorMessageException; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; + +@NamedEntityGraph( + name = "graph.booking", + attributeNodes = { + @NamedAttributeNode(value = "bookingData", subgraph = "graph.booking-data"), + }) +@Slf4j +@Data +@EqualsAndHashCode(callSuper = true) +@Builder(toBuilder = true) +@NoArgsConstructor +@AllArgsConstructor +@Setter(AccessLevel.PRIVATE) +@Entity +@Table(name = "booking") +public class Booking extends AbstractStateMachine { + + private static final Set CAN_BE_VALIDATED = Set.of(RECEIVED, + PENDING_UPDATES_CONFIRMATION, + PENDING_AMENDMENTS_APPROVAL); + + private static final DFADefinition BOOKING_DFA_DEFINITION = DFADefinition.builder(RECEIVED) + .nonTerminalState(RECEIVED) + .successorNodes(CONFIRMED, PENDING_UPDATE, REJECTED, // Carrier + CANCELLED, PENDING_UPDATES_CONFIRMATION) // Shipper + .nonTerminalState(PENDING_UPDATE) + .successorNodes(PENDING_UPDATE, REJECTED, // Carrier + PENDING_UPDATES_CONFIRMATION, CANCELLED) // Shipper + .nonTerminalState(PENDING_UPDATES_CONFIRMATION) + .successorNodes(CONFIRMED, PENDING_UPDATE, REJECTED, // Carrier + CANCELLED) // Shipper + .nonTerminalState(CONFIRMED) + .successorNodes(PENDING_UPDATE, COMPLETED, DECLINED, // Carrier + PENDING_AMENDMENTS_APPROVAL, CANCELLED) // Shipper + .nonTerminalState(PENDING_AMENDMENTS_APPROVAL) + .successorNodes(PENDING_UPDATE, CONFIRMED, DECLINED, // Carrier + CANCELLED) // Shipper + .terminalStates(COMPLETED, REJECTED, DECLINED, // Carrier + CANCELLED) // Shipper + .build(); + + @Id + @Column(name = "id", nullable = false) + @GeneratedValue + private UUID id; + + @Column(name = "carrier_booking_request_reference", length = 100) + private String carrierBookingRequestReference; + + @Column(name = "carrier_booking_reference", length = 35) + private String carrierBookingReference; + + @Column(name = "booking_status") + @StringEnumValidation(value = BookingStatus.class) + private String bookingStatus; + + @ToString.Exclude + @EqualsAndHashCode.Exclude + @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true, optional = false) + @JoinColumn(name = "booking_data_id") + @Setter(AccessLevel.PACKAGE) + private BookingData bookingData; + + @ToString.Exclude + @EqualsAndHashCode.Exclude + @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) + @JoinColumn(name = "last_confirmed_booking_data_id") + @Setter(AccessLevel.PACKAGE) + private BookingData lastConfirmedBookingData; + + @ToString.Exclude + @EqualsAndHashCode.Exclude + @OneToMany(cascade = CascadeType.ALL) + @JoinColumn(name = "booking_id", referencedColumnName = "id", nullable = false) + @OrderColumn(name = "element_order") + private List requestedChanges; + + // TODO: Remove later (in DT-389) + @CreatedDate + @Column(name = "created_date_time") + @Builder.Default + protected OffsetDateTime bookingRequestCreatedDateTime = OffsetDateTime.now(); + + // TODO: Remove later (in DT-389) + @LastModifiedDate + @Column(name = "updated_date_time") + @Builder.Default + protected OffsetDateTime bookingRequestUpdatedDateTime = OffsetDateTime.now(); + + public void assignCarrierBookingReference(@NotNull String carrierBookingReference) { + if (this.carrierBookingReference != null + && !this.carrierBookingReference.equals(carrierBookingReference)) { + + } + this.carrierBookingReference = carrierBookingReference; + } + + public ValidationResult asyncValidation(Validator validator) { + List validationErrors = new ArrayList<>(); + + if (!CAN_BE_VALIDATED.contains(bookingStatus)) { + throw new IllegalStateException("bookingStatus must be one of " + CAN_BE_VALIDATED); + } + if (this.requestedChanges == null) { + this.requestedChanges = new ArrayList<>(); + } + clearRequestedChanges(); + + for (var violation : validator.validate(this.bookingData, AsyncShipperProvidedDataValidation.class)) { + this.requestedChanges.add(BookingRequestedChange.fromConstraintViolation(violation)); + validationErrors.add(violation.getPropertyPath().toString() + ": " + violation.getMessage()); + } + + // TODO: according to the latest Booking State Transition Diagram (STD), + // PENDING_UPDATES_CONFIRMATION should be replaced with CONFIRMED, but this change should be done together + // with other STD-related changes so that new BOOKING_DFA_DEFINITION does not get broken + var proposedStatus = validationErrors.isEmpty() ? PENDING_UPDATES_CONFIRMATION : PENDING_UPDATE; + + return new ValidationResult<>(proposedStatus, validationErrors); + } + + private void clearRequestedChanges() { + if (this.requestedChanges != null && !this.requestedChanges.isEmpty()) { + this.requestedChanges.clear(); + } + } + + + /** + * Transition the booking into its {@link BookingStatus#RECEIVED} state. + */ + public void receive() { + processTransition(RECEIVED, null, false); + } + + /** + * Transition the booking into its {@link BookingStatus#CANCELLED} state. + */ + public void cancel(String reason) { + processTransition(CANCELLED, reason, false); + } + + /** + * Transition the booking into its {@link BookingStatus#REJECTED} state. + */ + public void reject(String reason) { + processTransition(REJECTED, reason, false); + } + + /** + * Transition the booking into its {@link BookingStatus#REJECTED} state. + */ + public void decline(String reason) { + processTransition(DECLINED, reason, false); + } + + /** + * Transition the booking into its {@link BookingStatus#PENDING_UPDATE} state. + */ + public void pendingUpdate(String reason) { + processTransition(PENDING_UPDATE, reason, false); + } + + /** + * Transition the booking into its {@link BookingStatus#PENDING_UPDATES_CONFIRMATION} state + * as a consequence of a shipper provided change + */ + public void pendingUpdatesConfirmation(@NotNull BookingData newBookingData) { + this.pendingUpdatesConfirmation(); + this.bookingData = newBookingData; + } + + /** + * Transition the booking into its {@link BookingStatus#PENDING_UPDATES_CONFIRMATION} state + * as a consequence of a carrier side (partial) validation. + */ + public void pendingUpdatesConfirmation() { + processTransition(PENDING_UPDATES_CONFIRMATION, null, true); + } + + /** + * Transition the booking into its {@link BookingStatus#PENDING_AMENDMENTS_APPROVAL} state. + */ + public void pendingAmendmentsApproval(String reason) { + processTransition(PENDING_AMENDMENTS_APPROVAL, reason, true); + } + + /** + * Transition the booking into its {@link BookingStatus#CONFIRMED} state. + */ + public void confirm() { + // TODO: Validate that all carrier provided attributes for confirming the booking has been given + processTransition(CONFIRMED, null, true); + this.lastConfirmedBookingData = this.bookingData; + } + + /** + * Transition the booking into its {@link BookingStatus#COMPLETED} state. + */ + public void complete() { + processTransition(COMPLETED, null, true); + } + + @Override + protected DFADefinition getDfaDefinition() { + return BOOKING_DFA_DEFINITION; + } + + @Override + protected String getResumeFromState() { + return this.bookingStatus; + } + + protected void processTransition(String bookingStatus, String reason, boolean clearRequestedChanges) { + transitionTo(bookingStatus); + this.bookingStatus = bookingStatus; + if (carrierBookingRequestReference == null) { + carrierBookingRequestReference = UUID.randomUUID().toString(); + } + if (clearRequestedChanges) { + this.clearRequestedChanges(); + } + } + + @Override + protected RuntimeException errorForAttemptToLeaveTerminalState(String currentState, + String successorState, + CannotLeaveTerminalStateException e) { + log.error("Booking with id=" + (id != null ? id.toString() : "null") +" is in terminal state " + currentState + + ", can not transition to state " + successorState); + return ConcreteRequestErrorMessageException.conflict( + "Cannot perform the requested action on the booking because the booking status is '" + + currentState + "'", + e + ); + } + + @Override + protected RuntimeException errorForTargetStateNotListedAsSuccessor(String currentState, + String successorState, + TargetStateIsNotSuccessorException e) { + log.error("Booking with id=" + (id != null ? id.toString() : "null") +" is in state " + currentState + + ", can not transition to unexpected state " + successorState); + return ConcreteRequestErrorMessageException.conflict( + "It is not possible to perform the requested action on the booking with the booking status '" + + currentState + "'", + e + ); + } + +} diff --git a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/BookingData.java b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/BookingData.java new file mode 100644 index 00000000..37c2709f --- /dev/null +++ b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/BookingData.java @@ -0,0 +1,299 @@ +package org.dcsa.edocumentation.domain.persistence.entity; + +import jakarta.persistence.*; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Future; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import java.time.LocalDate; +import java.time.OffsetDateTime; +import java.util.*; +import lombok.*; +import lombok.extern.slf4j.Slf4j; +import org.dcsa.edocumentation.domain.persistence.entity.enums.*; +import org.dcsa.edocumentation.domain.validations.*; + +@NamedEntityGraph( + name = "graph.booking-data", + attributeNodes = { + @NamedAttributeNode("vessel"), + @NamedAttributeNode("placeOfIssue"), + @NamedAttributeNode("invoicePayableAt"), + @NamedAttributeNode("references"), + @NamedAttributeNode(value = "documentParties", subgraph = "graph.documentParties"), + @NamedAttributeNode("shipmentLocations"), + @NamedAttributeNode("shipmentCutOffTimes"), + @NamedAttributeNode("carrierClauses"), + @NamedAttributeNode("confirmedEquipments"), + @NamedAttributeNode("charges"), + @NamedAttributeNode("carrier"), + }, + subgraphs = { + @NamedSubgraph( + name = "graph.documentParties", + attributeNodes = { + @NamedAttributeNode("displayedAddress"), + @NamedAttributeNode(value = "party", subgraph = "graph.party") + }), + @NamedSubgraph( + name = "graph.party", + attributeNodes = {@NamedAttributeNode("partyContactDetails")}), + @NamedSubgraph( + name = "subgraph.shipmentLocations", + attributeNodes = {@NamedAttributeNode("location")}), + @NamedSubgraph( + name = "subgraph.shipmentTransports", + attributeNodes = { + @NamedAttributeNode("loadLocation"), + @NamedAttributeNode("dischargeLocation"), + }), + }) +@Slf4j +@Data +@Builder(toBuilder = true) +@NoArgsConstructor +@AllArgsConstructor +@Setter(AccessLevel.PRIVATE) +@Entity +@Table(name = "booking_data") +@BookingDataValidation(groups = AsyncShipperProvidedDataValidation.class) +public class BookingData { + + @Id + @Column(name = "id", nullable = false) + @GeneratedValue + private UUID id; + + @Column(name = "receipt_type_at_origin") + @Enumerated(EnumType.STRING) + private ReceiptDeliveryType receiptTypeAtOrigin; + + @Column(name = "delivery_type_at_destination") + @Enumerated(EnumType.STRING) + private ReceiptDeliveryType deliveryTypeAtDestination; + + @Column(name = "cargo_movement_type_at_origin") + @Enumerated(EnumType.STRING) + private CargoMovementType cargoMovementTypeAtOrigin; + + @Column(name = "cargo_movement_type_at_destination") + @Enumerated(EnumType.STRING) + private CargoMovementType cargoMovementTypeAtDestination; + + @Column(name = "service_contract_reference", length = 30) + private String serviceContractReference; + + @Column(name = "payment_term_code") + @Enumerated(EnumType.STRING) + private PaymentTerm paymentTermCode; + + @Column(name = "is_partial_load_allowed") + private Boolean isPartialLoadAllowed; + + @Column(name = "is_export_declaration_required") + private Boolean isExportDeclarationRequired; + + @Column(name = "export_declaration_reference", length = 35) + private String exportDeclarationReference; + + @Column(name = "is_import_license_required") + private Boolean isImportLicenseRequired; + + @Column(name = "import_license_reference", length = 35) + private String importLicenseReference; + + @Column(name = "is_ams_aci_filing_required") + private Boolean isAMSACIFilingRequired; + + @Column(name = "is_destination_filing_required") + private Boolean isDestinationFilingRequired; + + @Column(name = "contract_quotation_reference", length = 35) + private String contractQuotationReference; + + @Column(name = "incoterms") + @PseudoEnum(value = "incotermscodes.csv", groups = AsyncShipperProvidedDataValidation.class) + private String incoTerms; + + @ToString.Exclude + @EqualsAndHashCode.Exclude + @ManyToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "invoice_payable_at_id") + @LocationValidation( + allowedSubtypes = {LocationSubType.ADDR, LocationSubType.UNLO}, + groups = AsyncShipperProvidedDataValidation.class + ) + private Location invoicePayableAt; + + @Future(groups = AsyncShipperProvidedDataValidation.class, message ="must be in the future" ) + @Column(name = "expected_departure_date") + private LocalDate expectedDepartureDate; + + @Future(groups = AsyncShipperProvidedDataValidation.class, message ="must be in the future" ) + @Column(name = "expected_arrival_at_place_of_delivery_start_date") + private LocalDate expectedArrivalAtPlaceOfDeliveryStartDate; + + @Future(groups = AsyncShipperProvidedDataValidation.class, message ="must be in the future" ) + @Column(name = "expected_arrival_at_place_of_delivery_end_date") + private LocalDate expectedArrivalAtPlaceOfDeliveryEndDate; + + @Column(name = "transport_document_type_code") + @Enumerated(EnumType.STRING) + private TransportDocumentTypeCode transportDocumentTypeCode; + + @Column(name = "transport_document_reference", length = 20) + private String transportDocumentReference; + + @Column(name = "booking_channel_reference", length = 20) + private String bookingChannelReference; + + @Column(name = "communication_channel_code") + @PseudoEnum(value = "communicationchannelqualifier.csv", groups = AsyncShipperProvidedDataValidation.class) + private String communicationChannelCode; + + @Column(name = "is_equipment_substitution_allowed") + private Boolean isEquipmentSubstitutionAllowed; + + @PseudoEnum(value = "currencycodes.csv", groups = AsyncShipperProvidedDataValidation.class) + @Column(name = "declared_value_currency_code", length = 3) + private String declaredValueCurrency; + + @Column(name = "declared_value") + private Float declaredValue; + + @ToString.Exclude + @EqualsAndHashCode.Exclude + @ManyToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "vessel_id") + private Vessel vessel; + + @ToString.Exclude + @EqualsAndHashCode.Exclude + @ManyToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "place_of_issue_id") + @LocationValidation( + allowedSubtypes = {LocationSubType.ADDR, LocationSubType.UNLO}, + groups = AsyncShipperProvidedDataValidation.class + ) + private Location placeOfIssue; + + @ToString.Exclude + @EqualsAndHashCode.Exclude + @ManyToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "carrier_id") + private Carrier carrier; + + @Column(name = "terms_and_conditions", length = 35) + private String termsAndConditions; + + @ToString.Exclude + @EqualsAndHashCode.Exclude + @OneToMany(mappedBy = "bookingData", cascade = CascadeType.ALL, orphanRemoval = true) + private Set<@Valid Reference> references; + + @ToString.Exclude + @EqualsAndHashCode.Exclude + @OneToMany(mappedBy = "bookingData", cascade = CascadeType.ALL, orphanRemoval = true) + @OrderColumn(name = "list_order") + private List<@Valid RequestedEquipmentGroup> requestedEquipments; + + @ToString.Exclude + @EqualsAndHashCode.Exclude + @OneToMany(mappedBy = "bookingData", cascade = CascadeType.ALL, orphanRemoval = true) + private Set<@Valid DocumentParty> documentParties; + + @ToString.Exclude + @EqualsAndHashCode.Exclude + @OneToMany(mappedBy = "bookingData", cascade = CascadeType.ALL, orphanRemoval = true) + @Size(min = 2, message = "Must have at least two shipment locations", groups = AsyncShipperProvidedDataValidation.class) + @NotNull(groups = AsyncShipperProvidedDataValidation.class) // -- for some reason this triggers, when shipmentLocations != null!? + private Set<@Valid ShipmentLocation> shipmentLocations; + + @ToString.Exclude + @EqualsAndHashCode.Exclude + @OneToMany(mappedBy = "bookingData", cascade = CascadeType.ALL, orphanRemoval = true) + @OrderColumn(name = "list_order") + private List<@Valid ShipmentCutOffTime> shipmentCutOffTimes; + + @ToString.Exclude + @EqualsAndHashCode.Exclude + @ManyToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "voyage_id") + private Voyage voyage; + + @ToString.Exclude + @EqualsAndHashCode.Exclude + @OneToMany + @JoinTable( + name = "shipment_carrier_clauses", + joinColumns = {@JoinColumn(name = "booking_data_id", referencedColumnName = "id")}, + inverseJoinColumns = {@JoinColumn(name = "carrier_clause_id", referencedColumnName = "id")}) + private Set carrierClauses = new LinkedHashSet<>(); + + @ToString.Exclude + @EqualsAndHashCode.Exclude + @OneToMany(mappedBy = "bookingData") + private Set shipmentTransports = new LinkedHashSet<>(); + + @ToString.Exclude + @EqualsAndHashCode.Exclude + @OneToMany(mappedBy = "bookingData", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) + @OrderColumn(name = "list_order") + private List confirmedEquipments = new ArrayList<>(); + + @ToString.Exclude + @EqualsAndHashCode.Exclude + @OneToMany(mappedBy = "bookingDataID") + private Set charges = new LinkedHashSet<>(); + + @ToString.Exclude + @EqualsAndHashCode.Exclude + @OrderColumn(name = "list_order") + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @JoinColumn(name = "booking_data_id") + private List advanceManifestFilings = new ArrayList<>(); + + public void assignRequestedEquipment(@NotNull List requestedEquipments) { + this.requestedEquipments = Objects.requireNonNullElseGet(this.requestedEquipments, ArrayList::new); + this.requestedEquipments.clear(); + this.requestedEquipments.addAll(requestedEquipments); + for (var re : requestedEquipments) { + re.setBookingData(this); + } + } + + public void assignConfirmedEquipments(@NotNull List confirmedEquipments) { + this.confirmedEquipments = Objects.requireNonNullElseGet(this.confirmedEquipments, ArrayList::new); + this.confirmedEquipments.clear(); + this.confirmedEquipments.addAll(confirmedEquipments); + for (var e : confirmedEquipments) { + e.setBookingData(this); // For cascade to work properly + } + } + + public void assignShipmentCutOffTimes(@NotNull List shipmentCutOffTimes) { + this.shipmentCutOffTimes = Objects.requireNonNullElseGet(this.shipmentCutOffTimes, ArrayList::new); + this.shipmentCutOffTimes.clear(); + this.shipmentCutOffTimes.addAll(shipmentCutOffTimes); + for (var t : shipmentCutOffTimes) { + t.setBookingData(this); // For cascade to work properly + } + } + + public void assignAdvanceManifestFiling(@NotNull List advanceManifestFilings) { + this.advanceManifestFilings = Objects.requireNonNullElseGet(this.advanceManifestFilings, ArrayList::new); + this.advanceManifestFilings.clear(); + this.advanceManifestFilings.addAll(advanceManifestFilings); + for (var e : advanceManifestFilings) { + e.setBookingData(this); // For cascade to work properly + } + } + + public void assignTermsAndConditions(@NotNull String termsAndConditions) { + this.termsAndConditions = termsAndConditions; + } + + public void assignCarrier(@NotNull Carrier carrier) { + this.carrier = carrier; + } +} diff --git a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/BookingRequest.java b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/BookingRequest.java deleted file mode 100644 index eedac6b2..00000000 --- a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/BookingRequest.java +++ /dev/null @@ -1,443 +0,0 @@ -package org.dcsa.edocumentation.domain.persistence.entity; - -import jakarta.persistence.*; -import jakarta.validation.Valid; -import jakarta.validation.Validator; -import jakarta.validation.constraints.Future; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import java.time.LocalDate; -import java.time.OffsetDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.UUID; -import lombok.*; -import lombok.extern.slf4j.Slf4j; -import org.dcsa.edocumentation.domain.dfa.AbstractStateMachine; -import org.dcsa.edocumentation.domain.dfa.CannotLeaveTerminalStateException; -import org.dcsa.edocumentation.domain.dfa.DFADefinition; -import org.dcsa.edocumentation.domain.dfa.TargetStateIsNotSuccessorException; -import org.dcsa.edocumentation.domain.persistence.entity.enums.*; -import org.dcsa.edocumentation.domain.persistence.entity.unofficial.ValidationResult; -import org.dcsa.edocumentation.domain.validations.*; -import org.dcsa.edocumentation.infra.enums.BookingStatus; -import static org.dcsa.edocumentation.infra.enums.BookingStatus.*; -import org.dcsa.edocumentation.infra.validation.StringEnumValidation; -import org.dcsa.skernel.errors.exceptions.ConcreteRequestErrorMessageException; -import org.springframework.data.domain.Persistable; - -@NamedEntityGraph( - name = "graph.booking-request-summary", - attributeNodes = {@NamedAttributeNode("vessel")}) -@NamedEntityGraph( - name = "graph.booking-request", - attributeNodes = { - @NamedAttributeNode("vessel"), - @NamedAttributeNode("placeOfIssue"), - @NamedAttributeNode("invoicePayableAt"), - @NamedAttributeNode("references"), - @NamedAttributeNode(value = "documentParties", subgraph = "graph.documentParties"), - @NamedAttributeNode("shipmentLocations") - }, - subgraphs = { - @NamedSubgraph( - name = "graph.documentParties", - attributeNodes = { - @NamedAttributeNode("displayedAddress"), - @NamedAttributeNode(value = "party", subgraph = "graph.party") - }), - @NamedSubgraph( - name = "graph.party", - attributeNodes = {@NamedAttributeNode("partyContactDetails")}), - }) -@Slf4j -@Data -@Builder(toBuilder = true) -@NoArgsConstructor -@AllArgsConstructor -@Setter(AccessLevel.PRIVATE) -@Entity -@Table(name = "booking_request") -@BookingRequestValidation(groups = AsyncShipperProvidedDataValidation.class) -public class BookingRequest extends AbstractStateMachine implements Persistable { - - private static final Set CAN_BE_VALIDATED = Set.of(RECEIVED, - PENDING_UPDATES_CONFIRMATION, - PENDING_AMENDMENTS_APPROVAL); - - private static final DFADefinition BOOKING_DFA_DEFINITION = DFADefinition.builder(RECEIVED) - .nonTerminalState(RECEIVED) - .successorNodes(CONFIRMED, PENDING_UPDATE, REJECTED, // Carrier - CANCELLED, PENDING_UPDATES_CONFIRMATION) // Shipper - .nonTerminalState(PENDING_UPDATE) - .successorNodes(PENDING_UPDATE, REJECTED, // Carrier - PENDING_UPDATES_CONFIRMATION, CANCELLED) // Shipper - .nonTerminalState(PENDING_UPDATES_CONFIRMATION) - .successorNodes(CONFIRMED, PENDING_UPDATE, REJECTED, // Carrier - CANCELLED) // Shipper - .nonTerminalState(CONFIRMED) - .successorNodes(PENDING_UPDATE, COMPLETED, DECLINED, // Carrier - PENDING_AMENDMENTS_APPROVAL, CANCELLED) // Shipper - .nonTerminalState(PENDING_AMENDMENTS_APPROVAL) - .successorNodes(PENDING_UPDATE, CONFIRMED, DECLINED, // Carrier - CANCELLED) // Shipper - .terminalStates(COMPLETED, REJECTED, DECLINED, // Carrier - CANCELLED) // Shipper - .build(); - - @Id - @Column(name = "id", nullable = false) - private UUID id; - - @Column(name = "carrier_booking_request_reference", length = 100) - private String carrierBookingRequestReference; - - @Column(name = "booking_status") - @StringEnumValidation(value= BookingStatus.class) - private String bookingStatus; - - @ToString.Exclude - @EqualsAndHashCode.Exclude - @OneToMany(cascade = CascadeType.ALL) - @JoinColumn(name = "booking_request_id", referencedColumnName = "id", nullable = false) - @OrderColumn(name = "element_order") - private List requestedChanges; - - @Column(name = "receipt_type_at_origin") - @Enumerated(EnumType.STRING) - private ReceiptDeliveryType receiptTypeAtOrigin; - - @Column(name = "delivery_type_at_destination") - @Enumerated(EnumType.STRING) - private ReceiptDeliveryType deliveryTypeAtDestination; - - @Column(name = "cargo_movement_type_at_origin") - @Enumerated(EnumType.STRING) - private CargoMovementType cargoMovementTypeAtOrigin; - - @Column(name = "cargo_movement_type_at_destination") - @Enumerated(EnumType.STRING) - private CargoMovementType cargoMovementTypeAtDestination; - - @Column(name = "booking_request_datetime") - private OffsetDateTime bookingRequestCreatedDateTime; - - @Column(name = "service_contract_reference", length = 30) - private String serviceContractReference; - - @Column(name = "payment_term_code") - @Enumerated(EnumType.STRING) - private PaymentTerm paymentTermCode; - - @Column(name = "is_partial_load_allowed") - private Boolean isPartialLoadAllowed; - - @Column(name = "is_export_declaration_required") - private Boolean isExportDeclarationRequired; - - @Column(name = "export_declaration_reference", length = 35) - private String exportDeclarationReference; - - @Column(name = "is_import_license_required") - private Boolean isImportLicenseRequired; - - @Column(name = "import_license_reference", length = 35) - private String importLicenseReference; - - @Column(name = "is_ams_aci_filing_required") - private Boolean isAMSACIFilingRequired; - - @Column(name = "is_destination_filing_required") - private Boolean isDestinationFilingRequired; - - @Column(name = "contract_quotation_reference", length = 35) - private String contractQuotationReference; - - @Column(name = "incoterms") - @PseudoEnum(value = "incotermscodes.csv", groups = AsyncShipperProvidedDataValidation.class) - private String incoTerms; - - @ToString.Exclude - @EqualsAndHashCode.Exclude - @ManyToOne(cascade = CascadeType.ALL) - @JoinColumn(name = "invoice_payable_at_id") - @LocationValidation( - allowedSubtypes = {LocationSubType.ADDR, LocationSubType.UNLO}, - groups = AsyncShipperProvidedDataValidation.class - ) - private Location invoicePayableAt; - - @Future(groups = AsyncShipperProvidedDataValidation.class, message ="must be in the future" ) - @Column(name = "expected_departure_date") - private LocalDate expectedDepartureDate; - - @Future(groups = AsyncShipperProvidedDataValidation.class, message ="must be in the future" ) - @Column(name = "expected_arrival_at_place_of_delivery_start_date") - private LocalDate expectedArrivalAtPlaceOfDeliveryStartDate; - - @Future(groups = AsyncShipperProvidedDataValidation.class, message ="must be in the future" ) - @Column(name = "expected_arrival_at_place_of_delivery_end_date") - private LocalDate expectedArrivalAtPlaceOfDeliveryEndDate; - - @Column(name = "transport_document_type_code") - @Enumerated(EnumType.STRING) - private TransportDocumentTypeCode transportDocumentTypeCode; - - @Column(name = "transport_document_reference", length = 20) - private String transportDocumentReference; - - @Column(name = "booking_channel_reference", length = 20) - private String bookingChannelReference; - - @Column(name = "communication_channel_code") - @PseudoEnum(value = "communicationchannelqualifier.csv", groups = AsyncShipperProvidedDataValidation.class) - private String communicationChannelCode; - - @Column(name = "is_equipment_substitution_allowed") - private Boolean isEquipmentSubstitutionAllowed; - - @PseudoEnum(value = "currencycodes.csv", groups = AsyncShipperProvidedDataValidation.class) - @Column(name = "declared_value_currency_code", length = 3) - private String declaredValueCurrency; - - @Column(name = "declared_value") - private Float declaredValue; - - @ToString.Exclude - @EqualsAndHashCode.Exclude - @ManyToOne(cascade = CascadeType.ALL) - @JoinColumn(name = "vessel_id") - private Vessel vessel; - - @ToString.Exclude - @EqualsAndHashCode.Exclude - @ManyToOne(cascade = CascadeType.ALL) - @JoinColumn(name = "place_of_issue_id") - @LocationValidation( - allowedSubtypes = {LocationSubType.ADDR, LocationSubType.UNLO}, - groups = AsyncShipperProvidedDataValidation.class - ) - private Location placeOfIssue; - - @ToString.Exclude - @EqualsAndHashCode.Exclude - @OneToMany(mappedBy = "bookingRequest") - private Set<@Valid Reference> references; - - @ToString.Exclude - @EqualsAndHashCode.Exclude - @OneToMany(mappedBy = "bookingRequest", cascade = CascadeType.ALL) - @OrderColumn(name = "list_order") - private List<@Valid RequestedEquipmentGroup> requestedEquipments; - - @ToString.Exclude - @EqualsAndHashCode.Exclude - @OneToMany(mappedBy = "bookingRequest") - private Set<@Valid DocumentParty> documentParties; - - @ToString.Exclude - @EqualsAndHashCode.Exclude - @OneToMany(mappedBy = "bookingRequest") - @Size(min = 2, message = "Must have at least two shipment locations", groups = AsyncShipperProvidedDataValidation.class) - @NotNull(groups = AsyncShipperProvidedDataValidation.class) - private Set<@Valid ShipmentLocation> shipmentLocations; - - @ToString.Exclude - @EqualsAndHashCode.Exclude - @ManyToOne(cascade = CascadeType.ALL) - @JoinColumn(name = "voyage_id") - private Voyage voyage; - - @Column(name = "valid_until") - private OffsetDateTime validUntil; - - // updatedDateTime is metadata to avoid having to query shipment_event for updated dateTime. - // This is not part of the official IM model. They are added in the sql only. - @Column(name = "updated_date_time") - protected OffsetDateTime bookingRequestUpdatedDateTime; - - @Transient - private boolean isNew; - - public boolean isNew() { - return id == null || isNew; - } - - - /** - * Subject to change. Reefer will probably change it. - */ - public ValidationResult asyncValidation(Validator validator) { - List validationErrors = new ArrayList<>(); - - if (!CAN_BE_VALIDATED.contains(bookingStatus)) { - throw new IllegalStateException("bookingStatus must be one of " + CAN_BE_VALIDATED); - } - if (this.requestedChanges == null) { - this.requestedChanges = new ArrayList<>(); - } - clearRequestedChanges(); - - for (var violation : validator.validate(this, AsyncShipperProvidedDataValidation.class)) { - this.requestedChanges.add(BookingRequestedChange.fromConstraintViolation(violation)); - validationErrors.add(violation.getPropertyPath().toString() + ": " + violation.getMessage()); - } - - // TODO: according to the latest Booking State Transition Diagram (STD), - // PENDING_UPDATES_CONFIRMATION should be replaced with CONFIRMED, but this change should be done together - // with other STD-related changes so that new BOOKING_DFA_DEFINITION does not get broken - var proposedStatus = validationErrors.isEmpty() ? PENDING_UPDATES_CONFIRMATION : PENDING_UPDATE; - - return new ValidationResult<>(proposedStatus, validationErrors); - } - - private void clearRequestedChanges() { - if (this.requestedChanges != null && !this.requestedChanges.isEmpty()) { - this.requestedChanges.clear(); - } - } - - - /** - * Transition the booking into its {@link BookingStatus#RECEIVED} state. - */ - public void receive() { - processTransition(RECEIVED, null, false); - } - - /** - * Transition the booking into its {@link BookingStatus#CANCELLED} state. - */ - public void cancel(String reason, OffsetDateTime updateTime) { - processTransition(CANCELLED, reason, updateTime, false); - } - - /** - * Transition the booking into its {@link BookingStatus#REJECTED} state. - */ - public void reject(String reason) { - processTransition(REJECTED, reason, false); - } - - /** - * Transition the booking into its {@link BookingStatus#REJECTED} state. - */ - public void decline(String reason) { - processTransition(DECLINED, reason, false); - } - - /** - * Transition the booking into its {@link BookingStatus#PENDING_UPDATE} state. - */ - public void pendingUpdate(String reason, OffsetDateTime updateTime) { - processTransition(PENDING_UPDATE, reason, updateTime, false); - } - - /** - * Transition the booking into its {@link BookingStatus#PENDING_UPDATES_CONFIRMATION} state. - */ - public void pendingUpdatesConfirmation(String reason, OffsetDateTime updateTime) { - processTransition(PENDING_UPDATES_CONFIRMATION, reason, updateTime, true); - } - - /** - * Transition the booking into its {@link BookingStatus#PENDING_AMENDMENTS_APPROVAL} state. - */ - public void pendingAmendmentsApproval(String reason, OffsetDateTime updateTime) { - processTransition(PENDING_AMENDMENTS_APPROVAL, reason, updateTime, true); - } - - /** - * Transition the booking into its {@link BookingStatus#CONFIRMED} state. - */ - public void confirm(OffsetDateTime confirmationTime) { - processTransition(CONFIRMED, null, confirmationTime, true); - } - - /** - * Transition the booking into its {@link BookingStatus#COMPLETED} state. - */ - public void complete() { - processTransition(COMPLETED, null, true); - } - - public void lockVersion(OffsetDateTime lockTime) { - if (isNew()) { - throw new IllegalStateException("Cannot lock a \"new\" version of the booking entity!"); - } - this.validUntil = lockTime; - } - - @Override - protected DFADefinition getDfaDefinition() { - return BOOKING_DFA_DEFINITION; - } - - @Override - protected String getResumeFromState() { - return this.bookingStatus; - } - - protected void processTransition(String bookingStatus, String reason, boolean clearRequestedChanges) { - processTransition(bookingStatus, reason, OffsetDateTime.now(), clearRequestedChanges); - } - - protected void processTransition(String bookingStatus, String reason, OffsetDateTime updateTime, boolean clearRequestedChanges) { - if (this.validUntil != null) { - throw new IllegalStateException("Cannot change state on a frozen version!"); - } - transitionTo(bookingStatus); - this.bookingStatus = bookingStatus; - this.bookingRequestUpdatedDateTime = updateTime; - if (this.bookingRequestCreatedDateTime == null) { - this.bookingRequestCreatedDateTime = updateTime; - } - if (id == null) { - id = UUID.randomUUID(); - isNew = true; - } - if (carrierBookingRequestReference == null) { - carrierBookingRequestReference = UUID.randomUUID().toString(); - } - if (clearRequestedChanges) { - this.clearRequestedChanges(); - } - } - - @Override - protected RuntimeException errorForAttemptToLeaveTerminalState(String currentState, - String successorState, - CannotLeaveTerminalStateException e) { - log.error("Booking with id=" + (id != null ? id.toString() : "null") +" is in terminal state " + currentState + - ", can not transition to state " + successorState); - return ConcreteRequestErrorMessageException.conflict( - "Cannot perform the requested action on the booking because the booking status is '" - + currentState + "'", - e - ); - } - - @Override - - protected RuntimeException errorForTargetStateNotListedAsSuccessor(String currentState, - String successorState, - TargetStateIsNotSuccessorException e) { - log.error("Booking with id=" + (id != null ? id.toString() : "null") +" is in state " + currentState + - ", can not transition to unexpected state " + successorState); - return ConcreteRequestErrorMessageException.conflict( - "It is not possible to perform the requested action on the booking with the booking status '" - + currentState + "'", - e - ); - } - - public void assignRequestedEquipment(List requestedEquipments) { - this.requestedEquipments = requestedEquipments; - if (requestedEquipments != null) { - for (var re : requestedEquipments) { - re.setBookingRequest(this); - } - } - } -} diff --git a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/BookingRequestedChange.java b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/BookingRequestedChange.java index ad9b7955..eae7f25d 100644 --- a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/BookingRequestedChange.java +++ b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/BookingRequestedChange.java @@ -25,7 +25,7 @@ public class BookingRequestedChange { @Column(name = "message", length = 500) private String message; - public static BookingRequestedChange fromConstraintViolation(ConstraintViolation violation) { + public static BookingRequestedChange fromConstraintViolation(ConstraintViolation violation) { return BookingRequestedChange.builder() .path(violation.getPropertyPath().toString()) .message(violation.getMessage()) diff --git a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/Charge.java b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/Charge.java index 64ac4510..c183bdef 100644 --- a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/Charge.java +++ b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/Charge.java @@ -21,8 +21,8 @@ public class Charge { @Column(name = "transport_document_id") private UUID transportDocumentID; - @Column(name = "confirmed_booking_id") - private UUID confirmedBookingID; + @Column(name = "booking_data_id") + private UUID bookingDataID; @Column(name = "charge_name") private String chargeName; diff --git a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/ConfirmedBooking.java b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/ConfirmedBooking.java index 60f46a3e..5285d605 100644 --- a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/ConfirmedBooking.java +++ b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/ConfirmedBooking.java @@ -1,44 +1,15 @@ package org.dcsa.edocumentation.domain.persistence.entity; import jakarta.persistence.*; -import jakarta.validation.Valid; -import java.time.OffsetDateTime; + import java.util.*; import lombok.*; -@NamedEntityGraph( - name = "graph.confirmed-booking-summary", - attributeNodes = {@NamedAttributeNode("booking")}) -@NamedEntityGraph( - name = "graph.confirmed-booking", - attributeNodes = { - @NamedAttributeNode("booking"), - @NamedAttributeNode("carrier"), - @NamedAttributeNode(value = "shipmentLocations", subgraph = "subgraph.shipmentLocations"), - @NamedAttributeNode(value = "shipmentTransports", subgraph = "subgraph.shipmentTransports"), - @NamedAttributeNode("shipmentCutOffTimes"), - @NamedAttributeNode("carrierClauses"), - @NamedAttributeNode("confirmedEquipments"), - @NamedAttributeNode("charges") - }, - subgraphs = { - @NamedSubgraph( - name = "subgraph.shipmentLocations", - attributeNodes = {@NamedAttributeNode("location")}), - @NamedSubgraph( - name = "subgraph.shipmentTransports", - attributeNodes = { - @NamedAttributeNode("loadLocation"), - @NamedAttributeNode("dischargeLocation"), - }), - }) @Data @Builder(toBuilder = true) @NoArgsConstructor @AllArgsConstructor @Setter(AccessLevel.PRIVATE) -@Entity -@Table(name = "confirmed_booking") public class ConfirmedBooking { @Id @@ -46,107 +17,5 @@ public class ConfirmedBooking { @Column(name = "id", nullable = false) private UUID id; - @ToString.Exclude - @EqualsAndHashCode.Exclude - @ManyToOne(cascade = CascadeType.ALL) - @JoinColumn(name = "booking_request_id") - private BookingRequest booking; - - @ToString.Exclude - @EqualsAndHashCode.Exclude - @OneToMany(mappedBy = "confirmedBooking") - private Set<@Valid ConsignmentItem> consignmentItems; - - @ToString.Exclude - @EqualsAndHashCode.Exclude - @ManyToOne(cascade = CascadeType.ALL) - @JoinColumn(name = "carrier_id") - private Carrier carrier; - - @Column(name = "carrier_booking_reference", length = 35) - private String carrierBookingReference; - - @Column(name = "terms_and_conditions", length = 35) - private String termsAndConditions; - - @Column(name = "confirmation_datetime") - private OffsetDateTime shipmentCreatedDateTime; - - @Column(name = "updated_date_time") - private OffsetDateTime shipmentUpdatedDateTime; - - @ToString.Exclude - @EqualsAndHashCode.Exclude - @OneToMany(mappedBy = "confirmedBooking") - private Set shipmentTransports = new LinkedHashSet<>(); - - @ToString.Exclude - @EqualsAndHashCode.Exclude - @OneToMany(mappedBy = "confirmedBooking") - private Set<@Valid ShipmentLocation> shipmentLocations = new LinkedHashSet<>(); - - @ToString.Exclude - @EqualsAndHashCode.Exclude - @OneToMany(mappedBy = "confirmedBooking", cascade = CascadeType.ALL) - @OrderColumn(name = "list_order") - private List<@Valid ShipmentCutOffTime> shipmentCutOffTimes; - - @ToString.Exclude - @EqualsAndHashCode.Exclude - @OneToMany(mappedBy = "confirmedBooking", fetch = FetchType.LAZY, cascade = CascadeType.ALL) - @OrderColumn(name = "list_order") - private List confirmedEquipments = new ArrayList<>(); - - @ToString.Exclude - @EqualsAndHashCode.Exclude - @OneToMany - @JoinTable( - name = "shipment_carrier_clauses", - joinColumns = {@JoinColumn(name = "confirmed_booking_id", referencedColumnName = "id")}, - inverseJoinColumns = {@JoinColumn(name = "carrier_clause_id", referencedColumnName = "id")}) - private Set carrierClauses = new LinkedHashSet<>(); - - - @ToString.Exclude - @EqualsAndHashCode.Exclude - @OneToMany(mappedBy = "confirmedBookingID") - private Set charges = new LinkedHashSet<>(); - - @ToString.Exclude - @EqualsAndHashCode.Exclude - @OrderColumn(name = "list_order") - @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) - @JoinColumn(name = "confirmed_booking_id") - private List advanceManifestFilings = new ArrayList<>(); - - public void assignConfirmedEquipments(List confirmedEquipments) { - this.confirmedEquipments = Objects.requireNonNullElseGet(this.confirmedEquipments, ArrayList::new); - this.confirmedEquipments.clear(); - this.confirmedEquipments.addAll(confirmedEquipments); - for (var e : confirmedEquipments) { - e.setConfirmedBooking(this); // For cascade to work properly - } - } - - public void assignShipmentCutOffTimes(List shipmentCutOffTimes) { - this.shipmentCutOffTimes = Objects.requireNonNullElseGet(this.shipmentCutOffTimes, ArrayList::new); - this.shipmentCutOffTimes.clear(); - this.shipmentCutOffTimes.addAll(shipmentCutOffTimes); - for (var t : shipmentCutOffTimes) { - t.setConfirmedBooking(this); // For cascade to work properly - } - } - - public void assignAdvanceManifestFiling(List advanceManifestFilings) { - if (this.advanceManifestFilings == null) { - this.advanceManifestFilings = new ArrayList<>(); - } else { - this.advanceManifestFilings.clear(); - } - this.advanceManifestFilings.addAll(advanceManifestFilings); - for (var e : advanceManifestFilings) { - e.setConfirmedBooking(this); // For cascade to work properly - } - } } diff --git a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/ConfirmedEquipment.java b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/ConfirmedEquipment.java index 20cd5fdf..d4e5c8d8 100644 --- a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/ConfirmedEquipment.java +++ b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/ConfirmedEquipment.java @@ -29,10 +29,10 @@ public class ConfirmedEquipment { @ToString.Exclude @EqualsAndHashCode.Exclude @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) - @JoinColumn(name = "confirmed_booking_id") + @JoinColumn(name = "booking_data") // Used by confirmed-booking to make the JPA relations work @Setter(AccessLevel.PACKAGE) - private ConfirmedBooking confirmedBooking; + private BookingData bookingData; @Column(name = "iso_equipment_code", nullable = false) @Size(max = 4) diff --git a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/ConsignmentItem.java b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/ConsignmentItem.java index 8e5eb585..cc54fa6e 100644 --- a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/ConsignmentItem.java +++ b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/ConsignmentItem.java @@ -18,7 +18,6 @@ import lombok.ToString; import org.dcsa.edocumentation.domain.validations.AsyncShipperProvidedDataValidation; import org.dcsa.edocumentation.domain.validations.ConsignmentItemValidation; -import org.springframework.web.bind.annotation.Mapping; @Builder(toBuilder = true) @NoArgsConstructor @@ -60,8 +59,8 @@ public class ConsignmentItem { @ToString.Exclude @EqualsAndHashCode.Exclude @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "confirmed_booking_id", nullable = false) - private ConfirmedBooking confirmedBooking; + @JoinColumn(name = "booking_id", nullable = false) + private Booking booking; @ToString.Exclude @EqualsAndHashCode.Exclude @@ -88,11 +87,11 @@ public class ConsignmentItem { @JoinColumn(name = "consignment_item_id") private List<@Valid CustomsReference> customsReferences; - public void resolvedConfirmedBooking(@NotNull ConfirmedBooking confirmedBooking) { - if (!this.getCarrierBookingReference().equals(confirmedBooking.getCarrierBookingReference())) { + public void resolvedConfirmedBooking(@NotNull Booking booking) { + if (!this.getCarrierBookingReference().equals(booking.getCarrierBookingReference())) { throw new IllegalArgumentException("Confirmed Booking had the wrong carrier booking reference"); } - this.confirmedBooking = confirmedBooking; + this.booking = booking; } public void resolvedCommodity(@NotNull Commodity commodity) { diff --git a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/DocumentParty.java b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/DocumentParty.java index 26583a3f..977ee709 100644 --- a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/DocumentParty.java +++ b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/DocumentParty.java @@ -39,8 +39,8 @@ public class DocumentParty { @ToString.Exclude @EqualsAndHashCode.Exclude @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) - @JoinColumn(name = "booking_request_id") - private BookingRequest bookingRequest; + @JoinColumn(name = "booking_data_id") + private BookingData bookingData; @JoinColumn(name = "shipping_instruction_id") @Column(name = "shipping_instruction_id") diff --git a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/Reference.java b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/Reference.java index 013c1674..eef098e5 100644 --- a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/Reference.java +++ b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/Reference.java @@ -35,8 +35,8 @@ public class Reference { @ToString.Exclude @EqualsAndHashCode.Exclude @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) - @JoinColumn(name = "booking_request_id") - private BookingRequest bookingRequest; + @JoinColumn(name = "booking_data_id") + private BookingData bookingData; @JoinColumn(name = "shipping_instruction_id") @Column(name = "shipping_instruction_id") diff --git a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/RequestedEquipmentGroup.java b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/RequestedEquipmentGroup.java index 31439288..fbfb8832 100644 --- a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/RequestedEquipmentGroup.java +++ b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/RequestedEquipmentGroup.java @@ -30,9 +30,9 @@ public class RequestedEquipmentGroup { @ToString.Exclude @EqualsAndHashCode.Exclude @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) - @JoinColumn(name = "booking_request_id") + @JoinColumn(name = "booking_data_id") @Setter(AccessLevel.PACKAGE) - private BookingRequest bookingRequest; + private BookingData bookingData; @Column(name = "iso_equipment_code", nullable = false) @Size(max = 4) diff --git a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/ShipmentCutOffTime.java b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/ShipmentCutOffTime.java index 794909b6..ad8d86af 100644 --- a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/ShipmentCutOffTime.java +++ b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/ShipmentCutOffTime.java @@ -21,10 +21,10 @@ public class ShipmentCutOffTime { @ToString.Exclude @EqualsAndHashCode.Exclude @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) - @JoinColumn(name = "confirmed_booking_id") + @JoinColumn(name = "booking_data_id") // Used by confirmed-booking to make the JPA relations work @Setter(AccessLevel.PACKAGE) - private ConfirmedBooking confirmedBooking; + private BookingData bookingData; @Column(name = "cut_off_time_code") private String cutOffDateTimeCode; diff --git a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/ShipmentLocation.java b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/ShipmentLocation.java index 069088bd..fc547515 100644 --- a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/ShipmentLocation.java +++ b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/ShipmentLocation.java @@ -40,12 +40,6 @@ public class ShipmentLocation { @ToString.Exclude @EqualsAndHashCode.Exclude @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) - @JoinColumn(name = "booking_request_id") - private BookingRequest bookingRequest; - - @ToString.Exclude - @EqualsAndHashCode.Exclude - @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) - @JoinColumn(name = "confirmed_booking_id") - private ConfirmedBooking confirmedBooking; + @JoinColumn(name = "booking_data_id") + private BookingData bookingData; } diff --git a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/ShipmentTransport.java b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/ShipmentTransport.java index 45cb6efc..ad1f15d9 100644 --- a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/ShipmentTransport.java +++ b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/ShipmentTransport.java @@ -26,8 +26,8 @@ public class ShipmentTransport { @Id private UUID id; @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) - @JoinColumn(name = "confirmed_booking_id", nullable = false) - private ConfirmedBooking confirmedBooking; + @JoinColumn(name = "booking_data_id", nullable = false) + private BookingData bookingData; @Column(name = "transport_plan_stage_sequence_number") private Integer transportPlanStageSequenceNumber; diff --git a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/ShippingInstruction.java b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/ShippingInstruction.java index a576930e..db403ea7 100644 --- a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/ShippingInstruction.java +++ b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/ShippingInstruction.java @@ -1,13 +1,12 @@ package org.dcsa.edocumentation.domain.persistence.entity; import jakarta.persistence.*; -import java.time.OffsetDateTime; -import java.util.*; - import jakarta.validation.Valid; import jakarta.validation.Validator; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Null; +import java.time.OffsetDateTime; +import java.util.*; import lombok.*; import org.dcsa.edocumentation.domain.dfa.*; import org.dcsa.edocumentation.domain.persistence.entity.enums.*; @@ -37,7 +36,7 @@ @NamedSubgraph( name = "graph.shippingInstructionSummary.consignmentItem", attributeNodes = { - @NamedAttributeNode("confirmedBooking") + @NamedAttributeNode("booking") }) } ) @@ -239,9 +238,9 @@ public class ShippingInstruction extends AbstractStateMachine // certain characteristics like the transport plan, are share among all shipments in the shipping // instruction, so it is beneficial to be able to retrieve one - public ConfirmedBooking retrieveOneShipment() { + public Booking retrieveOneBooking() { return this.consignmentItems.stream() - .map(ConsignmentItem::getConfirmedBooking) + .map(ConsignmentItem::getBooking) .findAny() .orElseThrow( () -> diff --git a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/TransportDocument.java b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/TransportDocument.java index 1c9c2515..dd072676 100644 --- a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/TransportDocument.java +++ b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/entity/TransportDocument.java @@ -47,7 +47,7 @@ @NamedSubgraph( name = "graph.transportDocumentSummary.consignmentItem", attributeNodes = { - @NamedAttributeNode("confirmedBooking") + @NamedAttributeNode("booking") }), @NamedSubgraph( name = "graph.transportDocumentSummary.issuingParty", diff --git a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/repository/BookingRepository.java b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/repository/BookingRepository.java new file mode 100644 index 00000000..e3c7d6ea --- /dev/null +++ b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/repository/BookingRepository.java @@ -0,0 +1,18 @@ +package org.dcsa.edocumentation.domain.persistence.repository; + +import java.util.Optional; +import java.util.UUID; +import org.dcsa.edocumentation.domain.persistence.entity.Booking; +import org.springframework.data.jpa.repository.EntityGraph; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface BookingRepository extends JpaRepository { + + @EntityGraph("graph.booking") + Optional findByCarrierBookingRequestReference(String carrierBookingRequestReference); + + @EntityGraph("graph.booking") + Optional findByCarrierBookingReference(String carrierBookingReference); +} diff --git a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/repository/BookingRequestRepository.java b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/repository/BookingRequestRepository.java deleted file mode 100644 index 3e927dea..00000000 --- a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/repository/BookingRequestRepository.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.dcsa.edocumentation.domain.persistence.repository; - -import lombok.NonNull; -import org.dcsa.edocumentation.domain.persistence.entity.BookingRequest; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.jpa.repository.EntityGraph; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.stereotype.Repository; - -import java.util.Optional; -import java.util.UUID; - -@Repository -public interface BookingRequestRepository extends JpaRepository { - - @EntityGraph("graph.booking-request") - @Query("FROM BookingRequest WHERE carrierBookingRequestReference = :carrierBookingRequestReference AND validUntil IS NULL") - Optional findBookingByCarrierBookingRequestReference(String carrierBookingRequestReference); -} diff --git a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/repository/ConfirmedBookingRepository.java b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/repository/ConfirmedBookingRepository.java deleted file mode 100644 index a7379863..00000000 --- a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/persistence/repository/ConfirmedBookingRepository.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.dcsa.edocumentation.domain.persistence.repository; - -import org.dcsa.edocumentation.domain.persistence.entity.ConfirmedBooking; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.jpa.repository.EntityGraph; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -import java.util.Optional; -import java.util.UUID; - -@Repository -public interface ConfirmedBookingRepository extends JpaRepository { - @EntityGraph("graph.confirmed-booking-summary") - Page findAll(Pageable pageable); - Optional findByCarrierBookingReference(String carrierBookingReference); - @EntityGraph("graph.confirmed-booking") - Optional findConfirmedBookingByCarrierBookingReference(String carrierBookingReference); -} diff --git a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/validations/BookingRequestValidation.java b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/validations/BookingDataValidation.java similarity index 94% rename from edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/validations/BookingRequestValidation.java rename to edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/validations/BookingDataValidation.java index dd08c248..c88219f3 100644 --- a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/validations/BookingRequestValidation.java +++ b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/validations/BookingDataValidation.java @@ -14,7 +14,7 @@ @Retention(RUNTIME) @Documented @Constraint(validatedBy = BookingRequestValidator.class) -public @interface BookingRequestValidation { +public @interface BookingDataValidation { String message() default "This attribute is not used (but required by the Validation API)"; Class[] groups() default {}; diff --git a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/validations/BookingRequestValidator.java b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/validations/BookingRequestValidator.java index f9bc630c..335a890e 100644 --- a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/validations/BookingRequestValidator.java +++ b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/validations/BookingRequestValidator.java @@ -3,15 +3,14 @@ import jakarta.validation.ConstraintValidator; import jakarta.validation.ConstraintValidatorContext; - import java.util.Objects; import java.util.Set; import java.util.function.Predicate; -import org.dcsa.edocumentation.domain.persistence.entity.BookingRequest; +import org.dcsa.edocumentation.domain.persistence.entity.BookingData; import org.dcsa.edocumentation.domain.persistence.entity.ShipmentLocation; import org.dcsa.edocumentation.domain.persistence.entity.enums.LocationType; -public class BookingRequestValidator implements ConstraintValidator { +public class BookingRequestValidator implements ConstraintValidator { private static final Predicate IS_SOURCE_LOCATION_TYPE = Set.of(LocationType.PRE.name(), LocationType.POL.name())::contains; private static final Predicate IS_DESTINATION_LOCATION_TYPE = Set.of(LocationType.POD.name(), LocationType.PDE.name())::contains; @@ -24,7 +23,7 @@ public class BookingRequestValidator implements ConstraintValidator state) { + private void validateShipmentLocations(ValidationState state) { var shipmentLocations = state.getValue().getShipmentLocations(); if (shipmentLocations == null || shipmentLocations.isEmpty()) { // This case is handled by a simple Jakarta annotation. diff --git a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/validations/ConsignmentItemValidator.java b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/validations/ConsignmentItemValidator.java index ff3af2ee..9ec96562 100644 --- a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/validations/ConsignmentItemValidator.java +++ b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/validations/ConsignmentItemValidator.java @@ -24,8 +24,8 @@ public boolean isValid(ConsignmentItem value, ConstraintValidatorContext context private void validateBookingAndCommodity(ValidationState state) { var consignmentItem = state.getValue(); - var confirmedBooking = consignmentItem.getConfirmedBooking(); - if (confirmedBooking == null) { + var booking = consignmentItem.getBooking(); + if (booking == null) { state.getContext().buildConstraintViolationWithTemplate( "Could not resolve booking with reference " + consignmentItem.getCarrierBookingReference() @@ -36,8 +36,8 @@ private void validateBookingAndCommodity(ValidationState state) state.invalidate(); return; } - if (!confirmedBooking.getBooking().getBookingStatus().equals(BookingStatus.CONFIRMED)) { - state.getContext().buildConstraintViolationWithTemplate("The booking " + confirmedBooking.getCarrierBookingReference() + " is not in state CONFIRMED") + if (!booking.getBookingStatus().equals(BookingStatus.CONFIRMED)) { + state.getContext().buildConstraintViolationWithTemplate("The booking " + booking.getCarrierBookingReference() + " is not in state CONFIRMED") // Match the TO path .addPropertyNode("carrierBookingReference") .addConstraintViolation(); diff --git a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/validations/ShippingInstructionValidator.java b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/validations/ShippingInstructionValidator.java index 00a975b4..48532a85 100644 --- a/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/validations/ShippingInstructionValidator.java +++ b/edocumentation-domain/src/main/java/org/dcsa/edocumentation/domain/validations/ShippingInstructionValidator.java @@ -3,7 +3,6 @@ import jakarta.validation.ConstraintValidator; import jakarta.validation.ConstraintValidatorContext; - import java.util.*; import java.util.function.BiPredicate; import java.util.stream.Stream; @@ -62,17 +61,20 @@ private void validateShipmentAlignment(ValidationState stat */ for (var item : state.getValue().getConsignmentItems()) { - var confirmedBooking = item.getConfirmedBooking(); - if (confirmedBooking == null) { + var booking = item.getBooking(); + if (booking == null) { + continue; + } + var bookingData = booking.getLastConfirmedBookingData(); + if (bookingData == null) { continue; } - var booking = confirmedBooking.getBooking(); - receiptTypeAtOriginChecker.check(booking.getReceiptTypeAtOrigin()); - deliveryTypeAtDestinationChecker.check(booking.getDeliveryTypeAtDestination()); - cargoMovementTypeAtOriginChecker.check(booking.getCargoMovementTypeAtOrigin()); - cargoMovementTypeAtDestinationChecker.check(booking.getCargoMovementTypeAtDestination()); - termAndConditionsChecker.check(confirmedBooking.getTermsAndConditions()); - serviceContractReferenceChecker.check(booking.getServiceContractReference()); + receiptTypeAtOriginChecker.check(bookingData.getReceiptTypeAtOrigin()); + deliveryTypeAtDestinationChecker.check(bookingData.getDeliveryTypeAtDestination()); + cargoMovementTypeAtOriginChecker.check(bookingData.getCargoMovementTypeAtOrigin()); + cargoMovementTypeAtDestinationChecker.check(bookingData.getCargoMovementTypeAtDestination()); + termAndConditionsChecker.check(bookingData.getTermsAndConditions()); + serviceContractReferenceChecker.check(bookingData.getServiceContractReference()); } emitConsignmentItemsConstraintIfNotOk(receiptTypeAtOriginChecker, state, "All referenced bookings must have the same receiptTypeAtOrigin"); @@ -157,33 +159,38 @@ private void validateManifestFilings(ValidationState state) List consignmentItems = si.getConsignmentItems(); var firstBooking = si.getConsignmentItems().stream() - .map(ConsignmentItem::getConfirmedBooking) + .map(ConsignmentItem::getBooking) .filter(Objects::nonNull) .findFirst() .orElse(null); if (firstBooking == null) { - // ConsignmentItemValidator flags shipment being null, so we are silent here. + // ConsignmentItemValidator flags Booking being null, so we are silent here. + return; + } + var bookingData = firstBooking.getLastConfirmedBookingData(); + if (bookingData == null) { + // ConsignmentItemValidator flags booking having the wrong status, so we are silent here. return; } - List advanceManifestFilingBase = firstBooking.getAdvanceManifestFilings(); + List advanceManifestFilingBase = bookingData.getAdvanceManifestFilings(); Map> misMatchedConsignmentManifestFilings = new HashMap<>(); for (ConsignmentItem ci : consignmentItems) { - var confirmedBooking = ci.getConfirmedBooking(); + var confirmedBooking = ci.getBooking(); if (confirmedBooking == null) { // ConsignmentItemValidator flags shipment being null, so we are silent here. continue; } - List advanceManifestFilings = confirmedBooking.getAdvanceManifestFilings(); + List advanceManifestFilings = bookingData.getAdvanceManifestFilings(); List misMatchedManifestFilings = advanceManifestFilingBase.stream() .filter(two -> advanceManifestFilings.stream() .noneMatch(one -> one.getManifestTypeCode().equals(two.getManifestTypeCode()) && one.getCountryCode().equals(two.getCountryCode()))) .toList(); if (!misMatchedManifestFilings.isEmpty()) { - misMatchedConsignmentManifestFilings.put(ci.getConfirmedBooking().getCarrierBookingReference(),misMatchedManifestFilings); + misMatchedConsignmentManifestFilings.put(ci.getBooking().getCarrierBookingReference(),misMatchedManifestFilings); } } diff --git a/edocumentation-domain/src/main/resources/db/migration/V3_0__dcsa_im_v3.sql b/edocumentation-domain/src/main/resources/db/migration/V3_0__dcsa_im_v3.sql index ad38926d..5384530f 100644 --- a/edocumentation-domain/src/main/resources/db/migration/V3_0__dcsa_im_v3.sql +++ b/edocumentation-domain/src/main/resources/db/migration/V3_0__dcsa_im_v3.sql @@ -156,53 +156,50 @@ CREATE TABLE voyage ( service_id uuid NULL REFERENCES service (id) INITIALLY DEFERRED ); - -CREATE TABLE booking_request ( - id uuid DEFAULT uuid_generate_v4() PRIMARY KEY, - carrier_booking_request_reference varchar(100) NOT NULL DEFAULT uuid_generate_v4()::text, - booking_status varchar(50), - receipt_type_at_origin varchar(3) NOT NULL REFERENCES receipt_delivery_type(receipt_delivery_type_code), - delivery_type_at_destination varchar(3) NOT NULL REFERENCES receipt_delivery_type(receipt_delivery_type_code), - cargo_movement_type_at_origin varchar(3) NOT NULL REFERENCES cargo_movement_type(cargo_movement_type_code), - cargo_movement_type_at_destination varchar(3) NOT NULL REFERENCES cargo_movement_type(cargo_movement_type_code), - booking_request_datetime timestamp with time zone NOT NULL, - service_contract_reference varchar(30) NULL, - payment_term_code varchar(3) NULL, - is_partial_load_allowed boolean NOT NULL, - is_export_declaration_required boolean NOT NULL, - export_declaration_reference varchar(35) NULL, - is_import_license_required boolean NOT NULL, - import_license_reference varchar(35) NULL, - is_ams_aci_filing_required boolean NULL, - is_destination_filing_required boolean NULL, - contract_quotation_reference varchar(35) NULL, - incoterms varchar(3) NULL, - invoice_payable_at_id uuid NULL REFERENCES location(id), - expected_departure_date date NULL, - expected_arrival_at_place_of_delivery_start_date date NULL CHECK ((expected_arrival_at_place_of_delivery_start_date IS NULL) OR (expected_arrival_at_place_of_delivery_end_date IS NULL) OR expected_arrival_at_place_of_delivery_start_date <= expected_arrival_at_place_of_delivery_end_date), - expected_arrival_at_place_of_delivery_end_date date NULL, - transport_document_type_code varchar(3) NULL REFERENCES transport_document_type(transport_document_type_code), - transport_document_reference varchar(20) NULL, - booking_channel_reference varchar(20) NULL, - communication_channel_code varchar(2) NOT NULL, - is_equipment_substitution_allowed boolean NOT NULL, - vessel_id uuid NULL REFERENCES vessel(id), - declared_value_currency_code varchar(3) NULL, - declared_value real NULL, - place_of_issue_id uuid NULL REFERENCES location(id), - voyage_id UUID NULL REFERENCES voyage(id) -); - -CREATE INDEX ON booking_request (id); - - -CREATE TABLE confirmed_booking ( - id uuid DEFAULT uuid_generate_v4() PRIMARY KEY, - booking_request_id uuid NOT NULL REFERENCES booking_request(id), - carrier_id uuid NOT NULL REFERENCES carrier(id), - carrier_booking_reference varchar(35) NOT NULL UNIQUE, - terms_and_conditions text NULL, - confirmation_datetime timestamp with time zone NOT NULL +CREATE TABLE booking_data ( + id uuid DEFAULT uuid_generate_v4() PRIMARY KEY, + receipt_type_at_origin varchar(3) NOT NULL REFERENCES receipt_delivery_type(receipt_delivery_type_code), + delivery_type_at_destination varchar(3) NOT NULL REFERENCES receipt_delivery_type(receipt_delivery_type_code), + cargo_movement_type_at_origin varchar(3) NOT NULL REFERENCES cargo_movement_type(cargo_movement_type_code), + cargo_movement_type_at_destination varchar(3) NOT NULL REFERENCES cargo_movement_type(cargo_movement_type_code), + service_contract_reference varchar(30) NULL, + payment_term_code varchar(3) NULL, + is_partial_load_allowed boolean NOT NULL, + is_export_declaration_required boolean NOT NULL, + export_declaration_reference varchar(35) NULL, + is_import_license_required boolean NOT NULL, + import_license_reference varchar(35) NULL, + is_ams_aci_filing_required boolean NULL, + is_destination_filing_required boolean NULL, + contract_quotation_reference varchar(35) NULL, + incoterms varchar(3) NULL, + invoice_payable_at_id uuid NULL REFERENCES location(id), + expected_departure_date date NULL, + expected_arrival_at_place_of_delivery_start_date date NULL CHECK ((expected_arrival_at_place_of_delivery_start_date IS NULL) OR (expected_arrival_at_place_of_delivery_end_date IS NULL) OR expected_arrival_at_place_of_delivery_start_date <= expected_arrival_at_place_of_delivery_end_date), + expected_arrival_at_place_of_delivery_end_date date NULL, + transport_document_type_code varchar(3) NULL REFERENCES transport_document_type(transport_document_type_code), + transport_document_reference varchar(20) NULL, + booking_channel_reference varchar(20) NULL, + communication_channel_code varchar(2) NOT NULL, + is_equipment_substitution_allowed boolean NOT NULL, + vessel_id uuid NULL REFERENCES vessel(id), + declared_value_currency_code varchar(3) NULL, + declared_value real NULL, + place_of_issue_id uuid NULL REFERENCES location(id), + terms_and_conditions text NULL, + carrier_id uuid NULL REFERENCES carrier(id), + voyage_id UUID NULL REFERENCES voyage(id) +); + +CREATE TABLE booking ( + id uuid DEFAULT uuid_generate_v4() PRIMARY KEY, + carrier_booking_request_reference varchar(100) NOT NULL UNIQUE DEFAULT uuid_generate_v4()::text, + carrier_booking_reference varchar(35) NULL UNIQUE, + booking_status varchar(50), + booking_data_id uuid NOT NULL REFERENCES booking_data(id), + last_confirmed_booking_data_id uuid NULL REFERENCES booking_data(id), + created_date_time timestamp with time zone NOT NULL default now(), + updated_date_time timestamp with time zone NOT NULL default now() ); @@ -227,8 +224,7 @@ CREATE TABLE active_reefer_settings ( CREATE TABLE requested_equipment_group ( id uuid DEFAULT uuid_generate_v4() PRIMARY KEY, - booking_request_id uuid NULL REFERENCES booking_request (id), - confirmed_booking_id uuid NULL REFERENCES confirmed_booking (id), + booking_data_id uuid NULL REFERENCES booking_data (id), iso_equipment_code varchar(4) NOT NULL, units int NOT NULL, tare_weight real NULL, @@ -238,7 +234,7 @@ CREATE TABLE requested_equipment_group ( list_order int NOT NULL DEFAULT 0 ); -CREATE INDEX ON requested_equipment_group (booking_request_id); +CREATE INDEX ON requested_equipment_group (booking_data_id); CREATE TABLE requested_equipment_group_equipment_references ( id uuid DEFAULT uuid_generate_v4() PRIMARY KEY, @@ -249,7 +245,7 @@ CREATE TABLE requested_equipment_group_equipment_references ( CREATE TABLE confirmed_equipment ( id uuid DEFAULT uuid_generate_v4() PRIMARY KEY, - confirmed_booking_id uuid NULL REFERENCES confirmed_booking (id), + booking_data uuid NULL REFERENCES booking_data (id), iso_equipment_code varchar(4) NOT NULL, units int NOT NULL CHECK (units > 0), list_order int NOT NULL DEFAULT 0 @@ -287,11 +283,11 @@ CREATE INDEX ON commodity (requested_equipment_group_id); CREATE TABLE shipment_cutoff_time ( id uuid DEFAULT uuid_generate_v4() PRIMARY KEY, - confirmed_booking_id uuid NOT NULL REFERENCES confirmed_booking(id), + booking_data_id uuid NOT NULL REFERENCES booking_data(id), cut_off_time_code varchar(3) NOT NULL, cut_off_time timestamp with time zone NOT NULL, list_order int NOT NULL default 0, - UNIQUE (confirmed_booking_id, cut_off_time_code) + UNIQUE (booking_data_id, cut_off_time_code) ); @@ -351,7 +347,7 @@ CREATE TABLE bkg_requested_change ( id uuid PRIMARY KEY DEFAULT uuid_generate_v4(), path varchar(500) NULL, message varchar(500) NOT NULL, - booking_request_id uuid REFERENCES booking_request (id), + booking_id uuid REFERENCES booking (id), element_order int NOT NULL default 0 ); @@ -372,7 +368,7 @@ CREATE TABLE carrier_clauses ( CREATE TABLE shipment_carrier_clauses ( carrier_clause_id uuid NOT NULL REFERENCES carrier_clauses (id), - confirmed_booking_id uuid NULL REFERENCES confirmed_booking (id), + booking_data_id uuid NULL REFERENCES booking_data (id), transport_document_id uuid NULL REFERENCES transport_document (id) ); @@ -380,24 +376,22 @@ CREATE TABLE document_party ( id uuid DEFAULT uuid_generate_v4() PRIMARY KEY, party_id uuid NOT NULL REFERENCES party (id), shipping_instruction_id uuid NULL REFERENCES shipping_instruction (id), - confirmed_booking_id uuid NULL REFERENCES confirmed_booking (id), party_function varchar(3) NOT NULL, is_to_be_notified boolean NOT NULL, - booking_request_id uuid NULL REFERENCES booking_request(id), + booking_data_id uuid NULL REFERENCES booking_data (id), displayed_address_id uuid NULL REFERENCES displayed_address(id) ); -- Supporting FK constraints CREATE INDEX ON document_party (party_id); -CREATE INDEX ON document_party (confirmed_booking_id); CREATE INDEX ON document_party (shipping_instruction_id); -CREATE INDEX ON document_party (booking_request_id); +CREATE INDEX ON document_party (booking_data_id); CREATE TABLE charge ( id varchar(100) PRIMARY KEY, transport_document_id uuid NOT NULL REFERENCES transport_document(id), - confirmed_booking_id uuid NULL REFERENCES confirmed_booking (id), + booking_data_id uuid NULL REFERENCES booking_data (id), charge_name varchar(50) NOT NULL, currency_amount real NOT NULL, currency_code varchar(3) NOT NULL, @@ -447,7 +441,7 @@ CREATE TABLE consignment_item ( carrier_booking_reference varchar(35) NOT NULL, commodity_subreference varchar(100) NOT NULL, shipping_instruction_id uuid NOT NULL REFERENCES shipping_instruction (id), - confirmed_booking_id uuid NULL REFERENCES confirmed_booking (id), + booking_id uuid NULL REFERENCES booking (id), commodity_id uuid NULL REFERENCES commodity (id), si_entry_order int NOT NULL default 0 ); @@ -465,7 +459,7 @@ CREATE INDEX ON hs_code_item (consignment_item_id); -- Supporting FK constraints CREATE INDEX ON consignment_item (shipping_instruction_id); -CREATE INDEX ON consignment_item (confirmed_booking_id); +CREATE INDEX ON consignment_item (booking_id); CREATE INDEX ON consignment_item (commodity_id); @@ -498,13 +492,12 @@ CREATE INDEX ON shipping_mark (cargo_item); CREATE TABLE reference ( reference_type_code varchar(3) NOT NULL, reference_value varchar(100) NOT NULL, - confirmed_booking_id uuid NULL REFERENCES confirmed_booking (id), shipping_instruction_id uuid NULL REFERENCES shipping_instruction (id), - booking_request_id uuid NULL REFERENCES booking_request(id), + booking_data_id uuid NULL REFERENCES booking_data(id), consignment_item_id uuid NULL REFERENCES consignment_item(id) ); -CREATE INDEX ON reference (booking_request_id); +CREATE INDEX ON reference (booking_data_id); CREATE INDEX ON reference (consignment_item_id); @@ -535,8 +528,7 @@ CREATE INDEX ON seal (seal_type_code); CREATE TABLE shipment_location ( - confirmed_booking_id uuid NULL REFERENCES confirmed_booking (id), - booking_request_id uuid NULL REFERENCES booking_request(id), + booking_data_id uuid NULL REFERENCES booking_data (id), location_id uuid NOT NULL REFERENCES location (id), shipment_location_type_code varchar(3) NOT NULL, event_date_time timestamp with time zone NULL --optional datetime indicating when the event at the location takes place @@ -546,8 +538,7 @@ CREATE TABLE shipment_location ( -- Note the omission of INDEX for "location_id" is deliberate; we rely on the implicit INDEX from the -- UNIQUE constraint for that. CREATE INDEX ON shipment_location (shipment_location_type_code); -CREATE INDEX ON shipment_location (confirmed_booking_id); -CREATE INDEX ON shipment_location (booking_request_id); +CREATE INDEX ON shipment_location (booking_data_id); CREATE TABLE port_call_status_type ( @@ -565,7 +556,7 @@ CREATE TABLE transport_plan_stage_type ( -- NOT a 1:1 with the DCSA IM version of the similarly named entity CREATE TABLE shipment_transport ( - confirmed_booking_id uuid NULL REFERENCES confirmed_booking(id), + booking_data_id uuid NULL REFERENCES booking_data(id), transport_plan_stage_sequence_number integer NOT NULL, transport_plan_stage_code varchar(3) NOT NULL REFERENCES transport_plan_stage_type(transport_plan_stage_code), dcsa_transport_type varchar(50) NULL, @@ -582,13 +573,15 @@ CREATE TABLE shipment_transport ( universal_export_voyage_reference varchar(5) NULL, universal_service_reference varchar(8) NULL ); + CREATE TABLE advance_manifest_filing ( manifest_id uuid DEFAULT uuid_generate_v4() PRIMARY KEY, - confirmed_booking_id uuid NOT NULL REFERENCES confirmed_booking(id), + booking_data_id uuid NOT NULL REFERENCES booking_data (id), manifest_type_code varchar(50) NOT NULL, country_code varchar(2) NOT NULL, list_order int NOT NULL default 0 ); + CREATE TABLE advance_manifest_filing_ebl ( manifest_id uuid DEFAULT uuid_generate_v4() PRIMARY KEY, shipping_instruction_id uuid REFERENCES shipping_instruction (id), diff --git a/edocumentation-domain/src/main/resources/db/migration/V5_0__reference_implementation_support.sql b/edocumentation-domain/src/main/resources/db/migration/V5_0__reference_implementation_support.sql index ce6b2527..675c56dc 100644 --- a/edocumentation-domain/src/main/resources/db/migration/V5_0__reference_implementation_support.sql +++ b/edocumentation-domain/src/main/resources/db/migration/V5_0__reference_implementation_support.sql @@ -5,20 +5,6 @@ CREATE EXTENSION IF NOT EXISTS pgcrypto; -- DDT-1356 -CREATE TABLE assigned_equipment ( - id uuid PRIMARY KEY, - confirmed_booking_id uuid NOT NULL REFERENCES confirmed_booking(id), - requested_equipment_group_id uuid NOT NULL REFERENCES requested_equipment_group(id) -); - -CREATE TABLE assigned_equipment_references ( - assigned_equipment_id uuid REFERENCES assigned_equipment (id), - equipment_reference varchar(15) NOT NULL REFERENCES equipment (equipment_reference), - - -- A equipment can only be used once per requested_equipment_group - UNIQUE (assigned_equipment_id, equipment_reference) -); - CREATE TABLE ebl_solution_provider_type ( ebl_solution_provider_name varchar(50) NOT NULL, ebl_solution_provider_code varchar(5) PRIMARY KEY, @@ -27,12 +13,6 @@ CREATE TABLE ebl_solution_provider_type ( ); --- DDT-948 -ALTER TABLE booking_request ADD valid_until timestamp with time zone NULL; -CREATE UNIQUE INDEX unq_valid_until_booking_idx ON booking_request(carrier_booking_request_reference) WHERE valid_until IS NULL; - -ALTER TABLE confirmed_booking ADD valid_until timestamp with time zone NULL; -CREATE UNIQUE INDEX unq_valid_until_shipment_idx ON confirmed_booking(carrier_booking_reference) WHERE valid_until IS NULL; - ALTER TABLE shipping_instruction ADD valid_until timestamp with time zone NULL; CREATE UNIQUE INDEX unq_valid_until_si_idx ON shipping_instruction(shipping_instruction_reference) WHERE valid_until IS NULL; diff --git a/edocumentation-domain/src/main/resources/db/migration/V6_0__metadata.sql b/edocumentation-domain/src/main/resources/db/migration/V6_0__metadata.sql index 2b2355c0..10cc83a1 100644 --- a/edocumentation-domain/src/main/resources/db/migration/V6_0__metadata.sql +++ b/edocumentation-domain/src/main/resources/db/migration/V6_0__metadata.sql @@ -28,9 +28,6 @@ ALTER TABLE party_identifying_code -- Metadata for Booking table to avoid having to query shipmentEvent for -- updated date_time necessary for BookingResponseTO -ALTER TABLE booking_request - ADD COLUMN IF NOT EXISTS updated_date_time timestamp with time zone NOT NULL; - ALTER TABLE shipping_instruction ADD COLUMN IF NOT EXISTS created_date_time timestamp with time zone NOT NULL; @@ -43,6 +40,3 @@ ALTER TABLE transport_document ALTER TABLE transport_document ADD COLUMN IF NOT EXISTS updated_date_time timestamp with time zone NOT NULL; -ALTER TABLE confirmed_booking - ADD COLUMN IF NOT EXISTS updated_date_time timestamp with time zone NOT NULL; - diff --git a/edocumentation-domain/src/main/resources/db/testdata.d/V8_1__test_data_ebl.sql b/edocumentation-domain/src/main/resources/db/testdata.d/V8_1__test_data_ebl.sql index 2aec5f31..9ff8fde2 100644 --- a/edocumentation-domain/src/main/resources/db/testdata.d/V8_1__test_data_ebl.sql +++ b/edocumentation-domain/src/main/resources/db/testdata.d/V8_1__test_data_ebl.sql @@ -85,15 +85,12 @@ INSERT INTO location ( 'DKCPH' ); -INSERT INTO booking_request ( +INSERT INTO booking_data ( id, - carrier_booking_request_reference, - booking_status, receipt_type_at_origin, delivery_type_at_destination, cargo_movement_type_at_origin, cargo_movement_type_at_destination, - booking_request_datetime, service_contract_reference, payment_term_code, is_partial_load_allowed, @@ -113,17 +110,14 @@ INSERT INTO booking_request ( declared_value_currency_code, declared_value, place_of_issue_id, - updated_date_time, + terms_and_conditions, invoice_payable_at_id ) VALUES ( 'b521dbdb-a12b-48f5-b489-8594349731bf'::uuid, - 'CARRIER_BOOKING_REQUEST_REFERENCE_01', - 'RECEIVED', 'CY', 'CFS', 'FCL', 'BB', - DATE '2020-03-07', 'SERVICE_CONTRACT_REFERENCE_01', 'PRE', TRUE, @@ -143,18 +137,30 @@ INSERT INTO booking_request ( 'WTK', 12.12, NULL, - DATE '2021-12-09', + 'TERMS AND CONDITIONS!', 'c703277f-84ca-4816-9ccf-fad8e202d3b6' ); -INSERT INTO booking_request ( - carrier_booking_request_reference, - booking_status, +INSERT INTO booking ( + carrier_booking_request_reference, + carrier_booking_reference, + booking_status, + booking_data_id, + last_confirmed_booking_data_id +) VALUES ( + 'CARRIER_BOOKING_REQUEST_REFERENCE_01', + 'BR1239719871', + 'CONFIRMED', + 'b521dbdb-a12b-48f5-b489-8594349731bf'::uuid, + 'b521dbdb-a12b-48f5-b489-8594349731bf'::uuid +); + +INSERT INTO booking_data ( + id, receipt_type_at_origin, delivery_type_at_destination, cargo_movement_type_at_origin, cargo_movement_type_at_destination, - booking_request_datetime, service_contract_reference, payment_term_code, is_partial_load_allowed, @@ -174,16 +180,14 @@ INSERT INTO booking_request ( vessel_id, declared_value_currency_code, declared_value, - place_of_issue_id, - updated_date_time + terms_and_conditions, + place_of_issue_id ) VALUES ( - 'CARRIER_BOOKING_REQUEST_REFERENCE_02', - 'RECEIVED', + 'a521dbdb-a12b-48f5-b489-8594349731bf'::uuid, 'CY', 'CFS', 'FCL', 'BB', - DATE '2020-03-07', 'SERVICE_CONTRACT_REFERENCE_02', 'PRE', TRUE, @@ -203,110 +207,120 @@ INSERT INTO booking_request ( (SELECT vessel.id FROM vessel WHERE vessel_imo_number = '9321483'), 'WTK', 12.12, - '01670315-a51f-4a11-b947-ce8e245128eb', - DATE '2021-12-16' -); - - -INSERT INTO confirmed_booking ( - carrier_id, - booking_request_id, - carrier_booking_reference, - terms_and_conditions, - confirmation_datetime, - updated_date_time -) VALUES ( - (SELECT id FROM carrier WHERE smdg_code = 'MSK'), - (SELECT id FROM booking_request WHERE carrier_booking_request_reference = 'CARRIER_BOOKING_REQUEST_REFERENCE_01'), - 'BR1239719871', 'TERMS AND CONDITIONS!', - DATE '2020-03-07T12:12:12', - DATE '2020-04-07T12:12:12' + '01670315-a51f-4a11-b947-ce8e245128eb' ); -INSERT INTO confirmed_booking ( - carrier_id, - booking_request_id, - carrier_booking_reference, - terms_and_conditions, - confirmation_datetime, - updated_date_time -) VALUES ( - (SELECT id FROM carrier WHERE smdg_code = 'MSK'), - (SELECT id FROM booking_request WHERE carrier_booking_request_reference = 'CARRIER_BOOKING_REQUEST_REFERENCE_02'), - 'CR1239719872', - 'TERMS AND CONDITIONS!', - DATE '2020-03-07T12:12:12', - DATE '2020-04-07T12:12:12' + +INSERT INTO booking ( + carrier_booking_request_reference, + carrier_booking_reference, + booking_status, + booking_data_id, + last_confirmed_booking_data_id +) values ( + 'CARRIER_BOOKING_REQUEST_REFERENCE_02', + 'CR1239719872', + 'CONFIRMED', + 'a521dbdb-a12b-48f5-b489-8594349731bf'::uuid, + 'a521dbdb-a12b-48f5-b489-8594349731bf'::uuid ); /** * Data used in integration tests - Do not modify - make your own data */ -INSERT INTO confirmed_booking ( - carrier_id, - booking_request_id, - carrier_booking_reference, - terms_and_conditions, - confirmation_datetime, - updated_date_time -) VALUES ( - (SELECT id FROM carrier WHERE smdg_code = 'MSK'), - (SELECT id FROM booking_request WHERE carrier_booking_request_reference = 'CARRIER_BOOKING_REQUEST_REFERENCE_01'), - 'bca68f1d3b804ff88aaa1e43055432f7', - 'TERMS AND CONDITIONS!', - DATE '2020-03-07T12:12:12', - DATE '2020-04-07T12:12:12' -),( - (SELECT id FROM carrier WHERE smdg_code = 'MSK'), - (SELECT id FROM booking_request WHERE carrier_booking_request_reference = 'CARRIER_BOOKING_REQUEST_REFERENCE_01'), - '832deb4bd4ea4b728430b857c59bd057', - 'TERMS AND CONDITIONS!', - DATE '2020-03-07T12:12:12', - DATE '2020-04-07T12:12:12' -),( - (SELECT id FROM carrier WHERE smdg_code = 'MSK'), - (SELECT id FROM booking_request WHERE carrier_booking_request_reference = 'CARRIER_BOOKING_REQUEST_REFERENCE_01'), - '994f0c2b590347ab86ad34cd1ffba505', - 'TERMS AND CONDITIONS!', - DATE '2020-03-07T12:12:12', - DATE '2020-04-07T12:12:12' -),( - (SELECT id FROM carrier WHERE smdg_code = 'MSK'), - (SELECT id FROM booking_request WHERE carrier_booking_request_reference = 'CARRIER_BOOKING_REQUEST_REFERENCE_01'), - '02c965382f5a41feb9f19b24b5fe2906', - 'TERMS AND CONDITIONS!', - DATE '2020-03-07T12:12:12', - DATE '2020-04-07T12:12:12' -),( - (SELECT id FROM carrier WHERE smdg_code = 'MSK'), - (SELECT id FROM booking_request WHERE carrier_booking_request_reference = 'CARRIER_BOOKING_REQUEST_REFERENCE_01'), - 'AR1239719871', - 'TERMS AND CONDITIONS!', - DATE '2020-03-07T12:12:12', - DATE '2020-04-07T12:12:12' + + +INSERT INTO booking_data ( + id, + receipt_type_at_origin, + delivery_type_at_destination, + cargo_movement_type_at_origin, + cargo_movement_type_at_destination, + service_contract_reference, + payment_term_code, + is_partial_load_allowed, + is_export_declaration_required, + export_declaration_reference, + is_import_license_required, + import_license_reference, + is_destination_filing_required, + incoterms, + expected_departure_date, + transport_document_type_code, + transport_document_reference, + booking_channel_reference, + communication_channel_code, + is_equipment_substitution_allowed, + vessel_id, + declared_value_currency_code, + declared_value, + place_of_issue_id, + terms_and_conditions, + invoice_payable_at_id +) VALUES ( + 'f521dbdb-a12b-48f5-b489-8594349731bf'::uuid, + 'CY', + 'CFS', + 'FCL', + 'BB', + 'SERVICE_CONTRACT_REFERENCE_01', + 'PRE', + TRUE, + TRUE, + 'EXPORT_DECLARATION_REFERENCE_01', + FALSE, + 'IMPORT_LICENSE_REFERENCE_01', + TRUE, + 'FCA', + DATE '2020-03-07', + 'SWB', + 'TRANSPORT_DOC_REF_01', + 'BOOKING_CHA_REF_01', + 'EI', + FALSE, + (SELECT vessel.id FROM vessel WHERE vessel_imo_number = '9321483'), + 'WTK', + 12.12, + NULL, + 'TERMS AND CONDITIONS!', + 'c703277f-84ca-4816-9ccf-fad8e202d3b6' +); + +INSERT INTO booking ( + carrier_booking_request_reference, + carrier_booking_reference, + booking_status, + booking_data_id, + last_confirmed_booking_data_id +) VALUES ( + 'CARRIER_BOOKING_REQUEST_REFERENCE_03', + 'AR1239719871', + 'CONFIRMED', + 'f521dbdb-a12b-48f5-b489-8594349731bf'::uuid, + 'f521dbdb-a12b-48f5-b489-8594349731bf'::uuid ); INSERT INTO reference ( reference_type_code, reference_value, - confirmed_booking_id + booking_data_id ) VALUES ( 'CR', 'AB-123743CR', - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'BR1239719871') + (SELECT booking.booking_data_id FROM booking WHERE carrier_booking_reference = 'BR1239719871') ), ( 'PO', 'PO0027', - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'BR1239719871') + (SELECT booking.booking_data_id FROM booking WHERE carrier_booking_reference = 'BR1239719871') ), ( 'CR', 'BC-346267CR', - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'CR1239719872') + (SELECT booking.booking_data_id FROM booking WHERE carrier_booking_reference = 'CR1239719872') ), ( 'PO', 'PO0028', - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'CR1239719872') + (SELECT booking.booking_data_id FROM booking WHERE carrier_booking_reference = 'CR1239719872') ); INSERT INTO voyage ( @@ -337,7 +351,7 @@ INSERT INTO vessel ( ); INSERT INTO shipment_transport ( - confirmed_booking_id, + booking_data_id, transport_plan_stage_sequence_number, transport_plan_stage_code, load_location_id, @@ -351,7 +365,7 @@ INSERT INTO shipment_transport ( carrier_service_code, dcsa_transport_type ) VALUES ( - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'BR1239719871'), + (SELECT booking_data_id FROM booking WHERE carrier_booking_reference = 'BR1239719871'), 1, 'PRC', '84bfcf2e-403b-11eb-bc4a-1fc4aa7d879d'::uuid, @@ -365,7 +379,7 @@ INSERT INTO shipment_transport ( null, 'TRUCK' ), ( - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'BR1239719871'), + (SELECT booking_data_id FROM booking WHERE carrier_booking_reference = 'BR1239719871'), 2, 'MNC', '770b7624-403d-11eb-b44b-d3f4ad185386'::uuid, @@ -379,7 +393,7 @@ INSERT INTO shipment_transport ( null, 'VESSEL' ), ( - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'BR1239719871'), + (SELECT booking_data_id FROM booking WHERE carrier_booking_reference = 'BR1239719871'), 3, 'ONC', '7f29ce3c-403d-11eb-9579-6bd2f4cf4ed6'::uuid, @@ -393,7 +407,7 @@ INSERT INTO shipment_transport ( null, 'RAIL' ), ( - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'AR1239719871'), + (SELECT booking_data_id FROM booking WHERE carrier_booking_reference = 'AR1239719871'), 1, 'MNC', '770b7624-403d-11eb-b44b-d3f4ad185386'::uuid, @@ -450,63 +464,52 @@ INSERT INTO party ( INSERT INTO document_party ( party_id, - confirmed_booking_id, + booking_data_id, party_function, - is_to_be_notified, - booking_request_id + is_to_be_notified ) VALUES ( '4e448f26-4035-11eb-a49d-7f9eb9bc8dd9', - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'BR1239719871'), + (SELECT booking_data_id FROM booking WHERE carrier_booking_reference = 'BR1239719871'), 'OS', - true, - (SELECT id FROM booking_request WHERE carrier_booking_request_reference = 'CARRIER_BOOKING_REQUEST_REFERENCE_01') + true ), ( '8dd9a4c4-4039-11eb-8770-0b2b19847fab', - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'BR1239719871'), + (SELECT booking_data_id FROM booking WHERE carrier_booking_reference = 'BR1239719871'), 'CN', - true, - (SELECT id FROM booking_request WHERE carrier_booking_request_reference = 'CARRIER_BOOKING_REQUEST_REFERENCE_01') + true ), ( '9dd9a4c4-4039-11eb-8770-0b2b19847fab', - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'AR1239719871'), + (SELECT booking_data_id FROM booking WHERE carrier_booking_reference = 'AR1239719871'), 'CN', - true, - (SELECT id FROM booking_request WHERE carrier_booking_request_reference = 'CARRIER_BOOKING_REQUEST_REFERENCE_01') - ); + true +); INSERT INTO shipment_location ( - confirmed_booking_id, - booking_request_id, + booking_data_id, location_id, shipment_location_type_code ) VALUES ( - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'BR1239719871'), - (SELECT id FROM booking_request WHERE carrier_booking_request_reference = 'CARRIER_BOOKING_REQUEST_REFERENCE_01'), + (SELECT booking_data_id FROM booking WHERE carrier_booking_reference = 'BR1239719871'), uuid('84bfcf2e-403b-11eb-bc4a-1fc4aa7d879d'), 'PRE' ), ( - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'BR1239719871'), - (SELECT id FROM booking_request WHERE carrier_booking_request_reference = 'CARRIER_BOOKING_REQUEST_REFERENCE_01'), + (SELECT booking_data_id FROM booking WHERE carrier_booking_reference = 'BR1239719871'), uuid('770b7624-403d-11eb-b44b-d3f4ad185386'), 'POL' ), ( - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'BR1239719871'), - (SELECT id FROM booking_request WHERE carrier_booking_request_reference = 'CARRIER_BOOKING_REQUEST_REFERENCE_01'), + (SELECT booking_data_id FROM booking WHERE carrier_booking_reference = 'BR1239719871'), uuid('7f29ce3c-403d-11eb-9579-6bd2f4cf4ed6'), 'POD' ), ( - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'BR1239719871'), - (SELECT id FROM booking_request WHERE carrier_booking_request_reference = 'CARRIER_BOOKING_REQUEST_REFERENCE_01'), + (SELECT booking_data_id FROM booking WHERE carrier_booking_reference = 'BR1239719871'), uuid('770b7624-403d-11eb-b44b-d3f4ad185387'), 'PDE' ), ( - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'AR1239719871'), - (SELECT id FROM booking_request WHERE carrier_booking_request_reference = 'CARRIER_BOOKING_REQUEST_REFERENCE_01'), + (SELECT booking_data_id FROM booking WHERE carrier_booking_reference = 'AR1239719871'), uuid('770b7624-403d-11eb-b44b-d3f4ad185386'), 'POL' ), ( - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'AR1239719871'), - (SELECT id FROM booking_request WHERE carrier_booking_request_reference = 'CARRIER_BOOKING_REQUEST_REFERENCE_01'), + (SELECT booking_data_id FROM booking WHERE carrier_booking_reference = 'AR1239719871'), uuid('7f29ce3c-403d-11eb-9579-6bd2f4cf4ed6'), 'POD' ); @@ -544,13 +547,7 @@ INSERT INTO utilized_transport_equipment ( 4000, 'KGM', false -),( - uuid('56812ad8-5d0b-4cbc-afca-e97f2f3c89de'), - 'BMOU2149612', - 4000, - 'KGM', - false -),( +), ( uuid('ca030eb6-009b-411c-985c-527ce008b35a'), 'BMOU2149612', 4000, @@ -590,18 +587,7 @@ INSERT INTO shipping_instruction ( TRUE, DATE '2022-01-24', DATE '2022-01-31' -),( - '877ce0f8-3126-45f5-b22e-2d1d27d42d85', - 'SI_REF_3', - 'RECEIVED', - TRUE, - 2, - 4, - TRUE, - TRUE, - DATE '2022-02-01', - DATE '2022-02-07' -),( +), ( '770f11e5-aae2-4ae4-b27e-0c689ed2e333', 'SI_REF_4', 'RECEIVED', @@ -612,29 +598,7 @@ INSERT INTO shipping_instruction ( TRUE, DATE '2021-02-08', DATE '2021-02-09' -),( - 'cb6354c9-1ceb-452c-aed0-3cb25a04647a', - 'SI_REF_5', - 'PENDING UPDATE', - TRUE, - 2, - 4, - TRUE, - TRUE, - DATE '2021-02-08', - DATE '2021-02-09' -),( - '8fbb78cc-e7c6-4e17-9a23-24dc3ad0378d', - 'SI_REF_6', - 'APPROVED', - TRUE, - 2, - 4, - TRUE, - TRUE, - DATE '2022-03-01', - DATE '2022-03-07' -),( +), ( '9fbb78cc-e7c6-4e17-9a23-24dc3ad0378d', 'SI_REF_7', 'APPROVED', @@ -649,13 +613,13 @@ INSERT INTO shipping_instruction ( INSERT INTO requested_equipment_group ( id, - booking_request_id, + booking_data_id, iso_equipment_code, units, is_shipper_owned ) VALUES ( 'd5ca0842-d90a-49fd-b929-1ef3fa375eec', - (SELECT booking_request.id FROM booking_request JOIN confirmed_booking ON booking_request.id=confirmed_booking.booking_request_id WHERE carrier_booking_reference = 'BR1239719871'), + (SELECT booking_data_id FROM booking WHERE carrier_booking_reference = 'BR1239719871'), '22GP', 1, false @@ -760,7 +724,7 @@ INSERT INTO consignment_item ( id, shipping_instruction_id, carrier_booking_reference, - confirmed_booking_id, + booking_id, commodity_id, commodity_subreference, description_of_goods, @@ -769,7 +733,7 @@ INSERT INTO consignment_item ( '10f41e70-0cae-47cd-8eb8-4ee6f05e85c1', '9d5965a5-9e2f-4c78-b8cb-fbb7095e13a0', 'BR1239719871', - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'BR1239719871'), + (SELECT id FROM booking WHERE carrier_booking_reference = 'BR1239719871'), '9d5965a5-9e2f-4c78-b8cb-fbb7095e13a0', (SELECT commodity_subreference FROM commodity WHERE id = '9d5965a5-9e2f-4c78-b8cb-fbb7095e13a0'), 'Expensive Shoes', @@ -778,52 +742,16 @@ INSERT INTO consignment_item ( 'c7104528-66d5-4d11-9b82-7af30e84d664', '9d5965a5-9e2f-4c78-b8cb-fbb7095e13a0', 'BR1239719871', - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'BR1239719871'), + (SELECT id FROM booking WHERE carrier_booking_reference = 'BR1239719871'), '5e900ef3-f929-4954-b145-eec22007f31b', (SELECT commodity_subreference FROM commodity WHERE id = '5e900ef3-f929-4954-b145-eec22007f31b'), 'Massive Yacht', 1 -), ( - '20e8aca5-4524-4ff9-a258-96c506966388', - '877ce0f8-3126-45f5-b22e-2d1d27d42d85', - 'bca68f1d3b804ff88aaa1e43055432f7', - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'bca68f1d3b804ff88aaa1e43055432f7'), - '877ce0f8-3126-45f5-b22e-2d1d27d42d85', - (SELECT commodity_subreference FROM commodity WHERE id = '877ce0f8-3126-45f5-b22e-2d1d27d42d85'), - 'Leather Jackets', - 0 -), ( - 'ca4ff535-407f-41ab-a009-830ddf06bdba', - '770f11e5-aae2-4ae4-b27e-0c689ed2e333', - '832deb4bd4ea4b728430b857c59bd057', - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = '832deb4bd4ea4b728430b857c59bd057'), - '770f11e5-aae2-4ae4-b27e-0c689ed2e333', - (SELECT commodity_subreference FROM commodity WHERE id = '770f11e5-aae2-4ae4-b27e-0c689ed2e333'), - 'Air ballons', - 0 -), ( - '83ec9f50-2eab-42f7-892d-cad2d25f3b9e', - 'cb6354c9-1ceb-452c-aed0-3cb25a04647a', - '994f0c2b590347ab86ad34cd1ffba505', - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = '994f0c2b590347ab86ad34cd1ffba505'), - 'cb6354c9-1ceb-452c-aed0-3cb25a04647a', - (SELECT commodity_subreference FROM commodity WHERE id = 'cb6354c9-1ceb-452c-aed0-3cb25a04647a'), - 'Leather Jackets', - 0 -), ( - '824e8fed-d181-4079-b6ca-9d9069a2a738', - '8fbb78cc-e7c6-4e17-9a23-24dc3ad0378d', - '02c965382f5a41feb9f19b24b5fe2906', - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = '02c965382f5a41feb9f19b24b5fe2906'), - '8fbb78cc-e7c6-4e17-9a23-24dc3ad0378d', - (SELECT commodity_subreference FROM commodity WHERE id = '8fbb78cc-e7c6-4e17-9a23-24dc3ad0378d'), - 'Leather Jackets', - 0 ), ( '1829548e-5938-4adc-a08e-3af55d8ccf63', '9fbb78cc-e7c6-4e17-9a23-24dc3ad0378d', 'AR1239719871', - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'AR1239719871'), + (SELECT id FROM booking WHERE carrier_booking_reference = 'AR1239719871'), '9fbb78cc-e7c6-4e17-9a23-24dc3ad0378d', (SELECT commodity_subreference FROM commodity WHERE id = '9fbb78cc-e7c6-4e17-9a23-24dc3ad0378d'), 'Leather Jackets', @@ -839,18 +767,6 @@ INSERT INTO hs_code_item ( ), ( 'c7104528-66d5-4d11-9b82-7af30e84d664', '720711' -), ( - '20e8aca5-4524-4ff9-a258-96c506966388', - '411510' -), ( - 'ca4ff535-407f-41ab-a009-830ddf06bdba', - '411510' -), ( - '83ec9f50-2eab-42f7-892d-cad2d25f3b9e', - '411510' -), ( - '824e8fed-d181-4079-b6ca-9d9069a2a738', - '411510' ), ( '1829548e-5938-4adc-a08e-3af55d8ccf63', '411510' @@ -870,30 +786,6 @@ INSERT INTO transport_document ( updated_date_time, issuing_party_id ) VALUES ( - '1af13f0b-a1ea-4ff8', - '01670315-a51f-4a11-b947-ce8e245128eb', - DATE '2020-11-25', - DATE '2020-12-24', - DATE '2020-12-31', - (SELECT id FROM carrier WHERE smdg_code = 'HLC'), - '877ce0f8-3126-45f5-b22e-2d1d27d42d85'::uuid, - 12, - '2021-11-28T14:12:56+01:00'::timestamptz, - '2021-12-01T07:41:00+08:30'::timestamptz, - '4e448f26-4035-11eb-a49d-7f9eb9bc8dd9' -), ( - '2b02401c-b2fb-5009', - '01670315-a51f-4a11-b947-ce8e245128eb', - DATE '2020-11-25', - DATE '2020-12-24', - DATE '2020-12-31', - (SELECT id FROM carrier WHERE smdg_code = 'HLC'), - '8fbb78cc-e7c6-4e17-9a23-24dc3ad0378d'::uuid, - 12, - '2022-03-03T18:22:53Z'::timestamptz, - '2022-03-05T13:56:12Z'::timestamptz, - '4e448f26-4035-11eb-a49d-7f9eb9bc8dd9' -), ( '9b02401c-b2fb-5009', '01670315-a51f-4a11-b947-ce8e245128eb', DATE '2020-11-25', @@ -946,36 +838,6 @@ INSERT INTO cargo_item ( 'KGM', (SELECT equipment_reference FROM utilized_transport_equipment WHERE id = '44068608-da9b-4039-b074-d9ac27ddbfbf'), uuid('44068608-da9b-4039-b074-d9ac27ddbfbf') -), ( - (SELECT id FROM consignment_item WHERE shipping_instruction_id = '877ce0f8-3126-45f5-b22e-2d1d27d42d85'), - 23.5, - 'KGM', - (SELECT equipment_reference FROM utilized_transport_equipment WHERE id = '56812ad8-5d0b-4cbc-afca-e97f2f3c89de'), - uuid('56812ad8-5d0b-4cbc-afca-e97f2f3c89de') -), ( - (SELECT id FROM consignment_item WHERE shipping_instruction_id = '877ce0f8-3126-45f5-b22e-2d1d27d42d85'), - 99.9, - 'KGM', - (SELECT equipment_reference FROM utilized_transport_equipment WHERE id = '44068608-da9b-4039-b074-d9ac27ddbfbf'), - uuid('44068608-da9b-4039-b074-d9ac27ddbfbf') -), ( - (SELECT id FROM consignment_item WHERE shipping_instruction_id = '770f11e5-aae2-4ae4-b27e-0c689ed2e333'), - 99.9, - 'KGM', - (SELECT equipment_reference FROM utilized_transport_equipment WHERE id = '44068608-da9b-4039-b074-d9ac27ddbfbf'), - uuid('44068608-da9b-4039-b074-d9ac27ddbfbf') -), ( - (SELECT id FROM consignment_item WHERE shipping_instruction_id = 'cb6354c9-1ceb-452c-aed0-3cb25a04647a'), - 23.5, - 'KGM', - (SELECT equipment_reference FROM utilized_transport_equipment WHERE id = 'ca030eb6-009b-411c-985c-527ce008b35a'), - uuid('ca030eb6-009b-411c-985c-527ce008b35a') -), ( - (SELECT id FROM consignment_item WHERE shipping_instruction_id = '8fbb78cc-e7c6-4e17-9a23-24dc3ad0378d'), - 23.5, - 'KGM', - (SELECT equipment_reference FROM utilized_transport_equipment WHERE id = 'ca030eb6-009b-411c-985c-527ce008b35a'), - uuid('ca030eb6-009b-411c-985c-527ce008b35a') ); INSERT INTO cargo_item ( @@ -985,7 +847,7 @@ INSERT INTO cargo_item ( weight_unit, equipment_reference, utilized_transport_equipment_id - ) VALUES ( +) VALUES ( '2d5965a5-9e2f-4c78-b8cb-fbb7095e13a0', (SELECT id FROM consignment_item WHERE shipping_instruction_id = '9fbb78cc-e7c6-4e17-9a23-24dc3ad0378d'), 23.5, @@ -1002,836 +864,53 @@ INSERT INTO shipping_mark ( 'shipping marks' ); -INSERT INTO booking_request ( - carrier_booking_request_reference, - booking_status, - receipt_type_at_origin, - delivery_type_at_destination, - cargo_movement_type_at_origin, - cargo_movement_type_at_destination, - booking_request_datetime, - service_contract_reference, - payment_term_code, - is_partial_load_allowed, - is_export_declaration_required, - export_declaration_reference, - is_import_license_required, - import_license_reference, - is_destination_filing_required, - incoterms, - expected_departure_date, - transport_document_type_code, - transport_document_reference, - booking_channel_reference, - communication_channel_code, - is_equipment_substitution_allowed, - vessel_id, - declared_value_currency_code, - declared_value, - place_of_issue_id, - updated_date_time +INSERT INTO requested_equipment_group ( + id, + booking_data_id, + iso_equipment_code, + units, + is_shipper_owned ) VALUES ( - 'CARRIER_BOOKING_REQUEST_REFERENCE_03', - 'CONFIRMED', - 'CY', - 'CFS', - 'FCL', - 'BB', - DATE '2020-03-07', - 'SERVICE_CONTRACT_REFERENCE_03', - 'PRE', - TRUE, - TRUE, - 'EXPORT_DECLARATION_REFERENCE_03', - FALSE, - 'IMPORT_LICENSE_REFERENCE_03', - TRUE, - 'FCA', - DATE '2020-03-07', - 'SWB', - 'TRANSPORT_DOC_REF_03', - 'BOOKING_CHA_REF_03', - 'EI', - FALSE, - (SELECT vessel.id FROM vessel WHERE vessel_imo_number = '9321483'), - 'WTK', - 12.12, - NULL, - DATE '2021-12-09' + '90ead08c-8e39-4fd9-8006-b2c01a463cb2', + (SELECT booking_data_id FROM booking WHERE carrier_booking_request_reference = 'CARRIER_BOOKING_REQUEST_REFERENCE_01'), + '22GP', + 1, + false ); -INSERT INTO booking_request ( - carrier_booking_request_reference, - booking_status, - receipt_type_at_origin, - delivery_type_at_destination, - cargo_movement_type_at_origin, - cargo_movement_type_at_destination, - booking_request_datetime, - service_contract_reference, - payment_term_code, - is_partial_load_allowed, - is_export_declaration_required, - export_declaration_reference, - is_import_license_required, - import_license_reference, - is_destination_filing_required, - incoterms, - invoice_payable_at_id, - expected_departure_date, - transport_document_type_code, - transport_document_reference, - booking_channel_reference, - communication_channel_code, - is_equipment_substitution_allowed, - vessel_id, - declared_value_currency_code, - declared_value, - place_of_issue_id, - updated_date_time +INSERT INTO commodity ( + id, + requested_equipment_group_id, + commodity_type, + cargo_gross_weight, + cargo_gross_weight_unit, + export_license_issue_date, + export_license_expiry_date ) VALUES ( - 'CARRIER_BOOKING_REQUEST_REFERENCE_04', - 'CONFIRMED', - 'CY', - 'CFS', - 'FCL', - 'BB', - DATE '2020-03-07', - 'SERVICE_CONTRACT_REFERENCE_04', - 'PRE', - TRUE, - TRUE, - 'EXPORT_DECLARATION_REFERENCE_04', - FALSE, - 'IMPORT_LICENSE_REFERENCE_04', - TRUE, - 'FCA', - '84bfcf2e-403b-11eb-bc4a-1fc4aa7d879d', - DATE '2020-03-07', - 'SWB', - 'TRANSPORT_DOC_REF_04', - 'BOOKING_CHA_REF_04', - 'EI', - FALSE, - (SELECT vessel.id FROM vessel WHERE vessel_imo_number = '9321483'), - 'WTK', - 12.12, - '01670315-a51f-4a11-b947-ce8e245128eb', - DATE '2021-12-16' + 'a5b681bf-68a0-4f90-8cc6-79bf77d3b2a1'::uuid, + '90ead08c-8e39-4fd9-8006-b2c01a463cb2', + 'Hand Bags', + 1200.0, + 'KGM', + NULL, + NULL ); - -INSERT INTO booking_request ( - carrier_booking_request_reference, - booking_status, - receipt_type_at_origin, - delivery_type_at_destination, - cargo_movement_type_at_origin, - cargo_movement_type_at_destination, - booking_request_datetime, - service_contract_reference, - payment_term_code, - is_partial_load_allowed, - is_export_declaration_required, - export_declaration_reference, - is_import_license_required, - import_license_reference, - is_destination_filing_required, - incoterms, - expected_departure_date, - transport_document_type_code, - transport_document_reference, - booking_channel_reference, - communication_channel_code, - is_equipment_substitution_allowed, - vessel_id, - declared_value_currency_code, - declared_value, - place_of_issue_id, - updated_date_time -) VALUES ( - 'CARRIER_BOOKING_REQUEST_REFERENCE_05', - 'CONFIRMED', - 'CY', - 'CFS', - 'FCL', - 'BB', - DATE '2020-03-07', - 'SERVICE_CONTRACT_REFERENCE_05', - 'PRE', - TRUE, - TRUE, - 'EXPORT_DECLARATION_REFERENCE_05', - FALSE, - 'IMPORT_LICENSE_REFERENCE_05', - TRUE, - 'FCA', - DATE '2020-03-07', - 'SWB', - 'TRANSPORT_DOC_REF_05', - 'BOOKING_CHA_REF_05', - 'EI', - FALSE, - (SELECT vessel.id FROM vessel WHERE vessel_imo_number = '9321483'), - 'WTK', - 12.12, - NULL, - DATE '2021-12-09' -); - -INSERT INTO booking_request ( - carrier_booking_request_reference, - booking_status, - receipt_type_at_origin, - delivery_type_at_destination, - cargo_movement_type_at_origin, - cargo_movement_type_at_destination, - booking_request_datetime, - service_contract_reference, - payment_term_code, - is_partial_load_allowed, - is_export_declaration_required, - export_declaration_reference, - is_import_license_required, - import_license_reference, - is_destination_filing_required, - incoterms, - invoice_payable_at_id, - expected_departure_date, - transport_document_type_code, - transport_document_reference, - booking_channel_reference, - communication_channel_code, - is_equipment_substitution_allowed, - vessel_id, - declared_value_currency_code, - declared_value, - place_of_issue_id, - updated_date_time -) VALUES ( - 'CARRIER_BOOKING_REQUEST_REFERENCE_06', - 'CONFIRMED', - 'CY', - 'CFS', - 'FCL', - 'BB', - DATE '2020-03-07', - 'SERVICE_CONTRACT_REFERENCE_06', - 'PRE', - TRUE, - TRUE, - 'EXPORT_DECLARATION_REFERENCE_06', - FALSE, - 'IMPORT_LICENSE_REFERENCE_06', - TRUE, - 'FCA', - '84bfcf2e-403b-11eb-bc4a-1fc4aa7d879d', - DATE '2020-03-07', - 'SWB', - 'TRANSPORT_DOC_REF_06', - 'BOOKING_CHA_REF_06', - 'EI', - FALSE, - (SELECT vessel.id FROM vessel WHERE vessel_imo_number = '9321483'), - 'WTK', - 12.12, - '01670315-a51f-4a11-b947-ce8e245128eb', - DATE '2021-12-16' -); - - - -INSERT INTO confirmed_booking ( - carrier_id, - booking_request_id, - carrier_booking_reference, - terms_and_conditions, - confirmation_datetime, - updated_date_time -) VALUES ( - (SELECT id FROM carrier WHERE smdg_code = 'MSK'), - (SELECT id FROM booking_request WHERE carrier_booking_request_reference = 'CARRIER_BOOKING_REQUEST_REFERENCE_03'), - '43f615138efc4d3286b36402405f851b', - 'TERMS AND CONDITIONS!', - DATE '2020-03-07T12:12:12', - DATE '2020-04-07T12:12:12' -),( - (SELECT id FROM carrier WHERE smdg_code = 'MSK'), - (SELECT id FROM booking_request WHERE carrier_booking_request_reference = 'CARRIER_BOOKING_REQUEST_REFERENCE_04'), - 'e8e9d64172934a40aec82e4308cdf97a', - 'TERMS AND CONDITIONS!', - DATE '2020-03-07T12:12:12', - DATE '2020-04-07T12:12:12' -),( - (SELECT id FROM carrier WHERE smdg_code = 'MSK'), - (SELECT id FROM booking_request WHERE carrier_booking_request_reference = 'CARRIER_BOOKING_REQUEST_REFERENCE_05'), - '6fe84758a4cc471fb5eb-4de63ddadc41', - 'TERMS AND CONDITIONS!', - DATE '2020-03-07T12:12:12', - DATE '2020-04-07T12:12:12' -), -( - (SELECT id FROM carrier WHERE smdg_code = 'MSK'), - (SELECT id FROM booking_request WHERE carrier_booking_request_reference = 'CARRIER_BOOKING_REQUEST_REFERENCE_06'), - '5dc92988f48a420495b786c224efce7d', - 'TERMS AND CONDITIONS!', - DATE '2020-03-07T12:12:12', - DATE '2020-04-07T12:12:12' -); - -INSERT INTO requested_equipment_group ( - id, - booking_request_id, - iso_equipment_code, - units, - is_shipper_owned -) VALUES ( - '90ead08c-8e39-4fd9-8006-b2c01a463cb2', - (SELECT booking_request.id FROM booking_request WHERE carrier_booking_request_reference = 'CARRIER_BOOKING_REQUEST_REFERENCE_01'), - '22GP', - 1, - false -); - -INSERT INTO commodity ( - id, - requested_equipment_group_id, - commodity_type, - cargo_gross_weight, - cargo_gross_weight_unit, - export_license_issue_date, - export_license_expiry_date -) VALUES ( - 'a5b681bf-68a0-4f90-8cc6-79bf77d3b2a1'::uuid, - '90ead08c-8e39-4fd9-8006-b2c01a463cb2', - 'Hand Bags', - 1200.0, - 'KGM', - NULL, - NULL -); - -INSERT INTO hs_code_item ( - commodity_id, - hs_code -) VALUES ( - 'a5b681bf-68a0-4f90-8cc6-79bf77d3b2a1'::uuid, - '411510' -); - --------- ShipmentLocationRepository.findByTransportDocumentID BEGIN -------- -------------------------------- DO NOT MODIFY ------------------------------ - -INSERT INTO party ( - id, - party_name -) VALUES ( - '499918a2-d12d-4df6-840c-dd92357002df', - 'FTL International' -); - -INSERT INTO party_contact_details ( - id, - party_id, - name, - email, - phone -) VALUES ( - '0a42252d-c8d5-4a0e-ab93-fa355992fb29'::uuid, - '499918a2-d12d-4df6-840c-dd92357002df', - 'DCSA', - 'info@dcsa.org', - '+31123456789' -); - -INSERT INTO displayed_address ( - id, - address_line_1, - address_line_2 -) VALUES ( - '8a5ccfed-f106-405b-a61f-c3a633e57ead'::uuid, - 'Gubener Str. 42', - 'Rhinstrasse 87' -); - -INSERT INTO shipping_instruction ( - id, - shipping_instruction_reference, - document_status, - is_shipped_onboard_type, - number_of_copies_with_charges, - number_of_originals_with_charges, - is_electronic, - is_to_order, - created_date_time, - updated_date_time, - displayed_name_for_place_of_delivery -) VALUES ( - 'a1c7b95d-3004-40a5-bae1-e379021b7782', - 'SI_REF_9', - 'RECEIVED', - TRUE, - 2, - 4, - TRUE, - TRUE, - DATE '2021-12-24', - DATE '2021-12-31', - '8a5ccfed-f106-405b-a61f-c3a633e57ead'::uuid -); - -INSERT INTO booking_request ( - id, - carrier_booking_request_reference, - booking_status, - receipt_type_at_origin, - delivery_type_at_destination, - cargo_movement_type_at_origin, - cargo_movement_type_at_destination, - booking_request_datetime, - service_contract_reference, - payment_term_code, - is_partial_load_allowed, - is_export_declaration_required, - export_declaration_reference, - is_import_license_required, - import_license_reference, - is_destination_filing_required, - incoterms, - expected_departure_date, - transport_document_type_code, - transport_document_reference, - booking_channel_reference, - communication_channel_code, - is_equipment_substitution_allowed, - vessel_id, - declared_value_currency_code, - declared_value, - place_of_issue_id, - updated_date_time, - invoice_payable_at_id -) VALUES ( - 'a169d494-d6dd-4334-b951-512e4e16f075'::uuid, - 'KUBERNETES_IN_ACTION_01', - 'RECEIVED', - 'CY', - 'CFS', - 'FCL', - 'BB', - DATE '2020-03-07', - 'SERVICE_CONTRACT_REFERENCE_01', - 'PRE', - TRUE, - TRUE, - 'EXPORT_DECLARATION_REFERENCE_01', - FALSE, - 'IMPORT_LICENSE_REFERENCE_01', - TRUE, - 'FCA', - DATE '2020-03-07', - 'SWB', - 'TRANSPORT_DOC_REF_01', - 'BOOKING_CHA_REF_01', - 'EI', - FALSE, - (SELECT vessel.id FROM vessel WHERE vessel_imo_number = '9321483'), - 'WTK', - 12.12, - NULL, - DATE '2021-12-09', - 'c703277f-84ca-4816-9ccf-fad8e202d3b6' -), ( - '59ede518-2224-4ecf-a0d0-4d641d365e1b'::uuid, - 'KUBERNETES_IN_ACTION_02', - 'RECEIVED', - 'CY', - 'CFS', - 'FCL', - 'BB', - DATE '2020-03-07', - 'SERVICE_CONTRACT_REFERENCE_01', - 'PRE', - TRUE, - TRUE, - 'EXPORT_DECLARATION_REFERENCE_01', - FALSE, - 'IMPORT_LICENSE_REFERENCE_01', - TRUE, - 'FCA', - DATE '2020-03-07', - 'SWB', - 'TRANSPORT_DOC_REF_01', - 'BOOKING_CHA_REF_01', - 'EI', - FALSE, - (SELECT vessel.id FROM vessel WHERE vessel_imo_number = '9321483'), - 'WTK', - 12.12, - NULL, - DATE '2021-12-09', - 'c703277f-84ca-4816-9ccf-fad8e202d3b6' -); - -INSERT INTO confirmed_booking ( - carrier_id, - booking_request_id, - carrier_booking_reference, - terms_and_conditions, - confirmation_datetime, - updated_date_time -) VALUES ( - (SELECT id FROM carrier WHERE smdg_code = 'MSK'), - (SELECT id FROM booking_request WHERE carrier_booking_request_reference = 'KUBERNETES_IN_ACTION_01'), - 'E379021B7782', - 'TERMS AND CONDITIONS!', - DATE '2020-03-07T12:12:12', - DATE '2020-04-07T12:12:12' -), ( - (SELECT id FROM carrier WHERE smdg_code = 'MSK'), - (SELECT id FROM booking_request WHERE carrier_booking_request_reference = 'KUBERNETES_IN_ACTION_02'), - 'A379021B7782', - 'TERMS AND CONDITIONS!', - DATE '2020-03-07T12:12:12', - DATE '2020-04-07T12:12:12' -); - -INSERT INTO consignment_item ( - id, - shipping_instruction_id, - carrier_booking_reference, - confirmed_booking_id, - description_of_goods, - commodity_subreference, - si_entry_order -) VALUES ( - '0e98eef4-6ebd-47eb-bd6e-d3878b341b7f', - 'a1c7b95d-3004-40a5-bae1-e379021b7782', - 'E379021B7782', - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'E379021B7782'), - 'Expensive shoes', - 'unmatched-subreference-1', - 0 -), ( - '06c0e716-3128-4172-be09-7f82b7ec02ca', - 'a1c7b95d-3004-40a5-bae1-e379021b7782', - 'E379021B7782', - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'E379021B7782'), - 'Slightly less expensive shoes', - 'unmatched-subreference-2', - 1 -), ( - 'cf1798fe-9447-4ea8-a4a6-9515de751d5e', - 'a1c7b95d-3004-40a5-bae1-e379021b7782', - 'A379021B7782', - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'A379021B7782'), - 'Even more expensive shoes', - 'unmatched-subreference-3', - 2 -); - -INSERT INTO hs_code_item ( - consignment_item_id, - hs_code -- TODO: HS Code probably does not match the description of the goods for any of these1 -) VALUES ( - '0e98eef4-6ebd-47eb-bd6e-d3878b341b7f', - '411510' -), ( - '06c0e716-3128-4172-be09-7f82b7ec02ca', - '411510' -), ( - 'cf1798fe-9447-4ea8-a4a6-9515de751d5e', - '411510' -); - -INSERT INTO location ( - id, - location_name, - location_type, - un_location_code -) VALUES ( - 'b4454ae5-dcd4-4955-8080-1f986aa5c6c3', - 'Copenhagen', - 'UNLO', - 'USMIA' -),( - '1d09e9e9-dba3-4de1-8ef8-3ab6d32dbb40', - 'Orlando', - 'UNLO', - 'USMIA' -),( - 'ea9af21d-8471-47ac-aa59-e949ea74b08e', - 'Miami', - 'UNLO', - 'USMIA' -); - -INSERT INTO shipment_location ( - confirmed_booking_id, - booking_request_id, - location_id, - shipment_location_type_code -) VALUES ( - null, - (SELECT id FROM booking_request WHERE carrier_booking_request_reference = 'KUBERNETES_IN_ACTION_01'), - uuid('b4454ae5-dcd4-4955-8080-1f986aa5c6c3'), - 'PRE' -), ( - null, - (SELECT id FROM booking_request WHERE carrier_booking_request_reference = 'KUBERNETES_IN_ACTION_01'), - uuid('1d09e9e9-dba3-4de1-8ef8-3ab6d32dbb40'), - 'POL' -), ( - null, - (SELECT id FROM booking_request WHERE carrier_booking_request_reference = 'KUBERNETES_IN_ACTION_01'), - uuid('ea9af21d-8471-47ac-aa59-e949ea74b08e'), - 'POD' -), ( - null, - (SELECT id FROM booking_request WHERE carrier_booking_request_reference = 'KUBERNETES_IN_ACTION_02'), - uuid('b4454ae5-dcd4-4955-8080-1f986aa5c6c3'), - 'PRE' -), ( - null, - (SELECT id FROM booking_request WHERE carrier_booking_request_reference = 'KUBERNETES_IN_ACTION_02'), - uuid('1d09e9e9-dba3-4de1-8ef8-3ab6d32dbb40'), - 'POL' -), ( - null, - (SELECT id FROM booking_request WHERE carrier_booking_request_reference = 'KUBERNETES_IN_ACTION_02'), - uuid('ea9af21d-8471-47ac-aa59-e949ea74b08e'), - 'POD' -); - -INSERT INTO cargo_item ( - consignment_item_id, - weight, - weight_unit, - equipment_reference, - utilized_transport_equipment_id -) VALUES ( - '0e98eef4-6ebd-47eb-bd6e-d3878b341b7f'::uuid, - 50.0, - 'KGM', - (SELECT equipment_reference FROM utilized_transport_equipment WHERE id = '6824b6ca-f3da-4154-96f1-264886b68d53'), - uuid('6824b6ca-f3da-4154-96f1-264886b68d53') -), ( - '06c0e716-3128-4172-be09-7f82b7ec02ca'::uuid, - 50.0, - 'KGM', - (SELECT equipment_reference FROM utilized_transport_equipment WHERE id = '6824b6ca-f3da-4154-96f1-264886b68d53'), - uuid('6824b6ca-f3da-4154-96f1-264886b68d53') -), ( - 'cf1798fe-9447-4ea8-a4a6-9515de751d5e'::uuid, - 50.0, - 'KGM', - (SELECT equipment_reference FROM utilized_transport_equipment WHERE id = '6824b6ca-f3da-4154-96f1-264886b68d53'), - uuid('6824b6ca-f3da-4154-96f1-264886b68d53') -); - --------- ShipmentLocationRepository.findByTransportDocumentID END -------- ------------------------------- DO NOT MODIFY ----------------------------- - - - - +INSERT INTO hs_code_item ( + commodity_id, + hs_code +) VALUES ( + 'a5b681bf-68a0-4f90-8cc6-79bf77d3b2a1'::uuid, + '411510' +); ----------------- Data for ApproveTransportDocument BEGIN ---------------- ------------------------------ DO NOT MODIFY ----------------------------- -INSERT INTO party ( - id, - party_name -) VALUES ( - '8e463a84-0a2d-47cd-9332-51e6cb36b635', - 'Superdæk Albertslund' -); - -INSERT INTO party_contact_details ( - id, - party_id, - name, - email, - phone -) VALUES ( - '0ffc61f0-c74d-4a57-8d32-009a32247c29'::uuid, - '8e463a84-0a2d-47cd-9332-51e6cb36b635', - 'DCSA', - 'info@dcsa.org', - '+31123456789' -); - -INSERT INTO shipping_instruction ( - id, - shipping_instruction_reference, - document_status, - is_shipped_onboard_type, - number_of_copies_with_charges, - number_of_originals_with_charges, - is_electronic, - is_to_order, - created_date_time, - updated_date_time -) VALUES ( - '2c337fcc-2814-42b3-a752-f1847e74cba7', - 'SI_REF_10', - 'DRAFT', - TRUE, - 2, - 4, - TRUE, - TRUE, - DATE '2021-12-24', - DATE '2021-12-31' -); - -INSERT INTO booking_request ( - id, - carrier_booking_request_reference, - booking_status, - receipt_type_at_origin, - delivery_type_at_destination, - cargo_movement_type_at_origin, - cargo_movement_type_at_destination, - booking_request_datetime, - service_contract_reference, - payment_term_code, - is_partial_load_allowed, - is_export_declaration_required, - export_declaration_reference, - is_import_license_required, - import_license_reference, - is_destination_filing_required, - incoterms, - expected_departure_date, - transport_document_type_code, - transport_document_reference, - booking_channel_reference, - communication_channel_code, - is_equipment_substitution_allowed, - vessel_id, - declared_value_currency_code, - declared_value, - place_of_issue_id, - updated_date_time, - invoice_payable_at_id -) VALUES ( - '66802442-4702-4464-9d61-d659fdb7e33c'::uuid, - 'KUBERNETES_IN_ACTION_03', - 'CONFIRMED', - 'CY', - 'CFS', - 'FCL', - 'BB', - DATE '2020-03-07', - 'SERVICE_CONTRACT_REFERENCE_01', - 'PRE', - TRUE, - TRUE, - 'EXPORT_DECLARATION_REFERENCE_01', - FALSE, - 'IMPORT_LICENSE_REFERENCE_01', - TRUE, - 'FCA', - DATE '2020-03-07', - 'SWB', - 'TRANSPORT_DOC_REF_01', - 'BOOKING_CHA_REF_01', - 'EI', - FALSE, - (SELECT vessel.id FROM vessel WHERE vessel_imo_number = '9321483'), - 'WTK', - 12.12, - NULL, - DATE '2021-12-09', - 'c703277f-84ca-4816-9ccf-fad8e202d3b6' -); - -INSERT INTO confirmed_booking ( - carrier_id, - booking_request_id, - carrier_booking_reference, - terms_and_conditions, - confirmation_datetime, - updated_date_time -) VALUES ( - (SELECT id FROM carrier WHERE smdg_code = 'MSK'), - (SELECT id FROM booking_request WHERE carrier_booking_request_reference = 'KUBERNETES_IN_ACTION_03'), - 'D659FDB7E33C', - 'TERMS AND CONDITIONS!', - DATE '2020-03-07T12:12:12', - DATE '2020-04-07T12:12:12' -); - -INSERT INTO consignment_item ( - id, - shipping_instruction_id, - carrier_booking_reference, - confirmed_booking_id, - description_of_goods, - commodity_subreference -) VALUES ( - '5d943239-23fc-4d5c-ab70-a33a469f9e59', - '2c337fcc-2814-42b3-a752-f1847e74cba7', - 'D659FDB7E33C', - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'D659FDB7E33C'), - 'Expensive shoes', - 'unmatched-subreference-4' -); - -INSERT INTO hs_code_item ( - consignment_item_id, - hs_code -) VALUES ( - '5d943239-23fc-4d5c-ab70-a33a469f9e59', - '411510' -- TODO: HS Code probably does not match the description of the goods. -); - -INSERT INTO transport_document ( - id, - transport_document_reference, - place_of_issue_id, - issue_date, - shipped_onboard_date, - received_for_shipment_date, - carrier_id, - shipping_instruction_id, - number_of_rider_pages, - created_date_time, - updated_date_time, - issuing_party_id -) VALUES ( - 'cf48ad0a-9a4b-48a7-b752-c248fb5d88d9'::uuid, - 'c90a0ed6-ccc9-48e3', - '01670315-a51f-4a11-b947-ce8e245128eb', - DATE '2022-05-16', - DATE '2022-05-15', - DATE '2022-05-14', - (SELECT id FROM carrier WHERE smdg_code = 'HLC'), - '2c337fcc-2814-42b3-a752-f1847e74cba7'::uuid, - 12, - '2021-11-28T14:12:56+01:00'::timestamptz, - '2021-12-01T07:41:00+08:30'::timestamptz, - '8e463a84-0a2d-47cd-9332-51e6cb36b635' -); - -INSERT INTO cargo_item ( - consignment_item_id, - weight, - weight_unit, - equipment_reference, - utilized_transport_equipment_id -) VALUES ( - '5d943239-23fc-4d5c-ab70-a33a469f9e59'::uuid, - 50.0, - 'KGM', - (SELECT equipment_reference FROM utilized_transport_equipment WHERE id = '6824b6ca-f3da-4154-96f1-264886b68d53'), - uuid('6824b6ca-f3da-4154-96f1-264886b68d53') -); - INSERT INTO charge ( id, transport_document_id, - confirmed_booking_id, + booking_data_id, charge_name, currency_amount, currency_code, @@ -1842,7 +921,7 @@ INSERT INTO charge ( ) VALUES ( '4816e01a-446b-4bc0-812e-a3a447c85668', (SELECT id FROM transport_document WHERE transport_document_reference = '9b02401c-b2fb-5009'), - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'AR1239719871'), + (SELECT booking_data_id FROM booking WHERE carrier_booking_reference = 'AR1239719871'), 'TBD', 100.12, 'EUR', diff --git a/edocumentation-domain/src/main/resources/db/testdata.d/V8_4__test_data_bkg.sql b/edocumentation-domain/src/main/resources/db/testdata.d/V8_4__test_data_bkg.sql index f05088b4..13bcc871 100644 --- a/edocumentation-domain/src/main/resources/db/testdata.d/V8_4__test_data_bkg.sql +++ b/edocumentation-domain/src/main/resources/db/testdata.d/V8_4__test_data_bkg.sql @@ -1,44 +1,18 @@ INSERT INTO shipment_cutoff_time ( - confirmed_booking_id, + booking_data_id, cut_off_time_code, cut_off_time ) VALUES ( - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'A379021B7782'), - 'AFD', - DATE '2021-03-09' -); - -INSERT INTO shipment_cutoff_time ( - confirmed_booking_id, - cut_off_time_code, - cut_off_time -) VALUES ( - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'BR1239719871'), + (SELECT booking_data_id FROM booking WHERE carrier_booking_reference = 'BR1239719871'), 'DCO', DATE '2021-05-01' -); - -INSERT INTO shipment_cutoff_time ( - confirmed_booking_id, - cut_off_time_code, - cut_off_time -) VALUES ( - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'CR1239719872'), +), ( + (SELECT booking_data_id FROM booking WHERE carrier_booking_reference = 'CR1239719872'), 'ECP', DATE '2020-07-07' ); -INSERT INTO shipment_cutoff_time ( - confirmed_booking_id, - cut_off_time_code, - cut_off_time -) VALUES ( - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'E379021B7782'), - 'EFC', - DATE '2020-01-06' -); - INSERT INTO party ( id, party_name @@ -75,20 +49,10 @@ INSERT INTO carrier_clauses ( ) VALUES ( '93eedc86-f8a3-4ec3-8d30-ad1eb8a079d2'::uuid, 'Shipment Carrier Clauses entity: address the carrier clauses for a shipment.' -); - -INSERT INTO carrier_clauses ( - id, - clause_content -) VALUES ( +), ( 'cbe900e7-7ad9-45fc-8d9e-0d1628a1b4f7'::uuid, 'Incoterms entity: Transport obligations, costs and risks as agreed between buyer and seller.' -); - -INSERT INTO carrier_clauses ( - id, - clause_content -) VALUES ( +), ( '3991a845-6cc8-404a-ac25-a1393e1d93a9'::uuid, 'Value Added Service Request entity: An entity containing data on requests for value added services. ' ); @@ -96,148 +60,27 @@ INSERT INTO carrier_clauses ( INSERT INTO shipment_carrier_clauses ( carrier_clause_id, - confirmed_booking_id -) VALUES ( - 'b8e312ad-7b00-4026-88ad-9881242ca4f4', - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'A379021B7782') -); - -INSERT INTO shipment_carrier_clauses ( - carrier_clause_id, - confirmed_booking_id + booking_data_id ) VALUES ( '93eedc86-f8a3-4ec3-8d30-ad1eb8a079d2', - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'BR1239719871') -); - -INSERT INTO shipment_carrier_clauses ( - carrier_clause_id, - confirmed_booking_id -) VALUES ( + (SELECT booking_data_id FROM booking WHERE carrier_booking_reference = 'BR1239719871') +), ( 'cbe900e7-7ad9-45fc-8d9e-0d1628a1b4f7', - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'CR1239719872') -); - -INSERT INTO shipment_carrier_clauses ( - carrier_clause_id, - confirmed_booking_id -) VALUES ( + (SELECT booking_data_id FROM booking WHERE carrier_booking_reference = 'CR1239719872') +), ( '3991a845-6cc8-404a-ac25-a1393e1d93a9', - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'BR1239719971') + (SELECT booking_data_id FROM booking WHERE carrier_booking_reference = 'BR1239719971') ); INSERT INTO shipment_carrier_clauses ( carrier_clause_id, - confirmed_booking_id, + booking_data_id, transport_document_id ) VALUES ( 'b8e312ad-7b00-4026-88ad-9881242ca4f4'::uuid, - (SELECT id FROM confirmed_booking WHERE carrier_booking_reference = 'AR1239719871'), + (SELECT booking_data_id FROM booking WHERE carrier_booking_reference = 'AR1239719871'), (SELECT id FROM transport_document WHERE transport_document_reference = '9b02401c-b2fb-5009') ); -INSERT INTO booking_request ( - id, - carrier_booking_request_reference, - booking_status, - receipt_type_at_origin, - delivery_type_at_destination, - cargo_movement_type_at_origin, - cargo_movement_type_at_destination, - booking_request_datetime, - service_contract_reference, - payment_term_code, - is_partial_load_allowed, - is_export_declaration_required, - export_declaration_reference, - is_import_license_required, - import_license_reference, - is_ams_aci_filing_required, - is_destination_filing_required, - contract_quotation_reference, - incoterms, - invoice_payable_at_id, - expected_departure_date, - transport_document_type_code, - transport_document_reference, - booking_channel_reference, - communication_channel_code, - is_equipment_substitution_allowed, - vessel_id, - declared_value_currency_code, - declared_value, - place_of_issue_id, - updated_date_time -) VALUES ( - '31629725-418b-41e1-9d10-521763c656c4'::uuid, - '52c2caa0-0137-44b7-9947-68687b3b4ae6', - 'PENDING UPDATES CONFIRMATION', - 'CY', - 'CY', - 'FCL', - 'LCL', - '2021-11-03 02:11:00.000', - 'Test', - NULL, - true, - true, - 'Export declaration reference', - true, - 'Import declaration reference', - true, - true, - NULL, - NULL, - 'c703277f-84ca-4816-9ccf-fad8e202d3b6', - DATE '2020-03-07', - NULL, - NULL, - NULL, - 'AO', - true, - NULL, - 'WTK', - 12.12, - NULL, - DATE '2021-12-01'); - - -INSERT INTO requested_equipment_group ( - id, - booking_request_id, - iso_equipment_code, - units, - is_shipper_owned -) VALUES ( - '98c4d459-42a3-42bc-992d-e1de670a9c08', - (SELECT booking_request_id FROM confirmed_booking WHERE carrier_booking_reference = 'A379021B7782'), - '22GP', - 1, - false -); - -INSERT INTO commodity ( - id, - requested_equipment_group_id, - commodity_type, - cargo_gross_weight, - cargo_gross_weight_unit, - export_license_issue_date, - export_license_expiry_date - ) VALUES ( - 'bf93f6fb-98b8-4268-a4dc-23a40eab95a8'::uuid, - '98c4d459-42a3-42bc-992d-e1de670a9c08', - 'Bloom', - 2000.0, - 'LBR', - NULL, - NULL); -INSERT INTO hs_code_item ( - commodity_id, - hs_code -) VALUES ( - 'bf93f6fb-98b8-4268-a4dc-23a40eab95a8'::uuid, - '720711' -); diff --git a/edocumentation-domain/src/test/java/org/dcsa/edocumentation/domain/booking/BookingRequestStateMachineTest.java b/edocumentation-domain/src/test/java/org/dcsa/edocumentation/domain/booking/BookingRequestStateMachineTest.java deleted file mode 100644 index 03938a45..00000000 --- a/edocumentation-domain/src/test/java/org/dcsa/edocumentation/domain/booking/BookingRequestStateMachineTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package org.dcsa.edocumentation.domain.booking; - -import org.dcsa.edocumentation.domain.persistence.entity.BookingRequest; -import org.dcsa.edocumentation.infra.enums.BookingStatus; -import org.dcsa.skernel.errors.exceptions.ConflictException; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import java.time.OffsetDateTime; - - -class BookingRequestStateMachineTest { - - @Test - void testBasic() { - BookingRequest bookingRequest = BookingRequest.builder().build(); - OffsetDateTime now = OffsetDateTime.now(); - bookingRequest.receive(); - Assertions.assertEquals(BookingStatus.RECEIVED, bookingRequest.getBookingStatus()); - bookingRequest.pendingUpdatesConfirmation("We provided what you requested. Please review it and confirm the booking", now); - Assertions.assertEquals(BookingStatus.PENDING_UPDATES_CONFIRMATION, bookingRequest.getBookingStatus()); - bookingRequest.pendingUpdate("Please provide foo!", now); - Assertions.assertEquals(BookingStatus.PENDING_UPDATE, bookingRequest.getBookingStatus()); - - bookingRequest = BookingRequest.builder().bookingStatus(BookingStatus.RECEIVED).build(); - Assertions.assertEquals(BookingStatus.RECEIVED, bookingRequest.getBookingStatus()); - bookingRequest.pendingUpdatesConfirmation("We provided what you requested. Please review it and confirm the booking", now); - Assertions.assertEquals(BookingStatus.PENDING_UPDATES_CONFIRMATION, bookingRequest.getBookingStatus()); - } - - @Test - void loadInvalidStateTransitions() { - String[] terminalStates = { - BookingStatus.COMPLETED, - BookingStatus.REJECTED, - BookingStatus.DECLINED, - BookingStatus.CANCELLED - }; - OffsetDateTime now = OffsetDateTime.now(); - for (String terminalState : terminalStates) { - BookingRequest bookingRequest = BookingRequest.builder().bookingStatus(terminalState).build(); - Assertions.assertThrows(ConflictException.class, - () -> bookingRequest.cancel("We decided to booking somewhere else.", now)); - Assertions.assertThrows(ConflictException.class, () -> bookingRequest.pendingUpdate("Please provide foo!", now)); - Assertions.assertThrows(ConflictException.class, bookingRequest::complete); - Assertions.assertThrows(ConflictException.class, - () -> bookingRequest.pendingUpdatesConfirmation( - "We provided what you requested. Please review it and confirm the booking", - now - )); - Assertions.assertThrows(ConflictException.class, () -> bookingRequest.reject("We cannot provide the service.")); - Assertions.assertThrows(ConflictException.class, bookingRequest::complete); - } - BookingRequest bookingRequest = BookingRequest.builder().bookingStatus(BookingStatus.PENDING_UPDATE).build(); - Assertions.assertThrows(ConflictException.class, () -> bookingRequest.confirm(now)); - Assertions.assertThrows(ConflictException.class, bookingRequest::complete); - } -} diff --git a/edocumentation-domain/src/test/java/org/dcsa/edocumentation/domain/booking/BookingStateMachineTest.java b/edocumentation-domain/src/test/java/org/dcsa/edocumentation/domain/booking/BookingStateMachineTest.java new file mode 100644 index 00000000..e9068ee1 --- /dev/null +++ b/edocumentation-domain/src/test/java/org/dcsa/edocumentation/domain/booking/BookingStateMachineTest.java @@ -0,0 +1,53 @@ +package org.dcsa.edocumentation.domain.booking; + +import org.dcsa.edocumentation.domain.persistence.entity.Booking; +import org.dcsa.edocumentation.domain.persistence.entity.BookingData; +import org.dcsa.edocumentation.infra.enums.BookingStatus; +import org.dcsa.skernel.errors.exceptions.ConflictException; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class BookingStateMachineTest { + + @Test + void testBasic() { + var booking = Booking.builder().build(); + var bookingData = BookingData.builder().build(); + booking.receive(); + Assertions.assertEquals(BookingStatus.RECEIVED, booking.getBookingStatus()); + booking.pendingUpdatesConfirmation(bookingData); + Assertions.assertEquals(BookingStatus.PENDING_UPDATES_CONFIRMATION, booking.getBookingStatus()); + booking.pendingUpdate("Please provide foo!"); + Assertions.assertEquals(BookingStatus.PENDING_UPDATE, booking.getBookingStatus()); + + booking = Booking.builder().bookingStatus(BookingStatus.RECEIVED).build(); + Assertions.assertEquals(BookingStatus.RECEIVED, booking.getBookingStatus()); + booking.pendingUpdatesConfirmation(bookingData); + Assertions.assertEquals(BookingStatus.PENDING_UPDATES_CONFIRMATION, booking.getBookingStatus()); + } + + @Test + void loadInvalidStateTransitions() { + String[] terminalStates = { + BookingStatus.COMPLETED, + BookingStatus.REJECTED, + BookingStatus.DECLINED, + BookingStatus.CANCELLED + }; + var bookingData = BookingData.builder().build(); + for (String terminalState : terminalStates) { + var booking = Booking.builder().bookingStatus(terminalState).build(); + Assertions.assertThrows(ConflictException.class, + () -> booking.cancel("We decided to booking somewhere else.")); + Assertions.assertThrows(ConflictException.class, () -> booking.pendingUpdate("Please provide foo!")); + Assertions.assertThrows(ConflictException.class, booking::complete); + Assertions.assertThrows(ConflictException.class, + () -> booking.pendingUpdatesConfirmation(bookingData)); + Assertions.assertThrows(ConflictException.class, () -> booking.reject("We cannot provide the service.")); + Assertions.assertThrows(ConflictException.class, booking::complete); + } + var booking = Booking.builder().bookingStatus(BookingStatus.PENDING_UPDATE).build(); + Assertions.assertThrows(ConflictException.class, booking::confirm); + Assertions.assertThrows(ConflictException.class, booking::complete); + } +} diff --git a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/BookingRequestService.java b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/BookingRequestService.java index ef865e83..82710d2b 100644 --- a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/BookingRequestService.java +++ b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/BookingRequestService.java @@ -1,13 +1,14 @@ package org.dcsa.edocumentation.service; import jakarta.transaction.Transactional; -import java.time.OffsetDateTime; import java.util.Objects; import java.util.Optional; import lombok.RequiredArgsConstructor; -import org.dcsa.edocumentation.domain.persistence.entity.BookingRequest; -import org.dcsa.edocumentation.domain.persistence.repository.BookingRequestRepository; -import org.dcsa.edocumentation.service.mapping.BookingRequestMapper; +import org.dcsa.edocumentation.domain.persistence.entity.Booking; +import org.dcsa.edocumentation.domain.persistence.entity.BookingData; +import org.dcsa.edocumentation.domain.persistence.repository.BookingRepository; +import org.dcsa.edocumentation.service.mapping.BookingDataMapper; +import org.dcsa.edocumentation.service.mapping.BookingMapper; import org.dcsa.edocumentation.service.mapping.RequestedEquipmentGroupMapper; import org.dcsa.edocumentation.transferobjects.BookingRequestRefStatusTO; import org.dcsa.edocumentation.transferobjects.BookingRequestTO; @@ -22,101 +23,88 @@ public class BookingRequestService { private final DocumentPartyService documentPartyService; private final ShipmentLocationService shipmentLocationService; - private final BookingRequestRepository bookingRequestRepository; + private final BookingRepository bookingRepository; - private final BookingRequestMapper bookingRequestMapper; + private final BookingMapper bookingMapper; + private final BookingDataMapper bookingDataMapper; private final RequestedEquipmentGroupMapper requestedEquipmentGroupMapper; @Transactional public Optional getBookingRequest(String carrierBookingRequestReference) { - return bookingRequestRepository - .findBookingByCarrierBookingRequestReference(carrierBookingRequestReference) - .map(bookingRequestMapper::toDTO); + return bookingRepository + .findByCarrierBookingRequestReference(carrierBookingRequestReference) + .map(bookingMapper::toDTO); } @Transactional public BookingRequestRefStatusTO createBookingRequest(BookingRequestTO bookingRequest) { - BookingRequest booking = mapToBooking(bookingRequest); + var bookingData = mapToBookingData(bookingRequest); + var booking = Booking.builder() + .bookingData(bookingData) + .build(); booking.receive(); - booking = saveBookingRequest(booking, bookingRequest); + booking = saveBooking(booking, bookingRequest); - return bookingRequestMapper.toStatusDTO(booking); + return bookingMapper.toStatusDTO(booking); } @Transactional public Optional updateBookingRequest(String carrierBookingRequestReference, BookingRequestTO bookingRequest) { - BookingRequest existingBookingRequest = bookingRequestRepository.findBookingByCarrierBookingRequestReference( + Booking existingBooking = bookingRepository.findByCarrierBookingRequestReference( carrierBookingRequestReference ).orElse(null); - if (existingBookingRequest == null) { + if (existingBooking == null) { return Optional.empty(); } - OffsetDateTime updateTime = OffsetDateTime.now(); - existingBookingRequest.lockVersion(updateTime); - var updatedBooking = mapToBooking(bookingRequest, existingBookingRequest); - updatedBooking.pendingUpdatesConfirmation(null, updateTime); + var updatedBookingData = mapToBookingData(bookingRequest); + existingBooking.pendingUpdatesConfirmation(updatedBookingData); // We have to flush the existing booking. Otherwise, JPA might be tempted to re-order that // write/save until after the updatedBooking is saved (which triggers the unique constraint // in the database). - bookingRequestRepository.saveAndFlush(existingBookingRequest); - updatedBooking = saveBookingRequest(updatedBooking, bookingRequest); + existingBooking = bookingRepository.saveAndFlush(existingBooking); + existingBooking = saveBooking(existingBooking, bookingRequest); // A couple of fail-safe checks that should be unnecessary unless we introduce bugs. - assert existingBookingRequest.getValidUntil() != null; - assert Objects.equals(existingBookingRequest.getCarrierBookingRequestReference(), updatedBooking.getBookingChannelReference()); - assert updatedBooking.getId() != null && !updatedBooking.getId().equals(existingBookingRequest.getId()); + assert Objects.equals(existingBooking.getCarrierBookingRequestReference(), updatedBookingData.getBookingChannelReference()); + assert updatedBookingData.getId() != null && !updatedBookingData.getId().equals(existingBooking.getId()); - return Optional.of(bookingRequestMapper.toStatusDTO(updatedBooking)); + return Optional.of(bookingMapper.toStatusDTO(existingBooking)); } - private void createDeepObjectsForBookingRequest(BookingRequestTO bookingRequest, BookingRequest booking) { - referenceService.createReferences(bookingRequest.references(), booking); - documentPartyService.createDocumentParties(bookingRequest.documentParties(), booking); - shipmentLocationService.createShipmentLocations(bookingRequest.shipmentLocations(), booking); + private void createDeepObjectsForBookingData(BookingRequestTO bookingRequest, BookingData bookingData) { + referenceService.createReferences(bookingRequest.references(), bookingData); + documentPartyService.createDocumentParties(bookingRequest.documentParties(), bookingData); + shipmentLocationService.createShipmentLocations(bookingRequest.shipmentLocations(), bookingData); } @Transactional - public Optional cancelBookingRequest(String carrierBookingRequestReference, - String reason) { - BookingRequest bookingRequest = bookingRequestRepository.findBookingByCarrierBookingRequestReference( + public Optional cancelBooking(String carrierBookingRequestReference, + String reason) { + var booking = bookingRepository.findByCarrierBookingRequestReference( carrierBookingRequestReference ).orElse(null); - if (bookingRequest == null) { + if (booking == null) { return Optional.empty(); } - OffsetDateTime updateTime = OffsetDateTime.now(); // This works because we do not need to support versioning/rollback - bookingRequest.cancel(reason, updateTime); - bookingRequest = bookingRequestRepository.save(bookingRequest); - return Optional.of(bookingRequestMapper.toStatusDTO(bookingRequest)); + booking.cancel(reason); + booking = bookingRepository.save(booking); + return Optional.of(bookingMapper.toStatusDTO(booking)); } - private BookingRequest saveBookingRequest(BookingRequest booking, BookingRequestTO bookingRequest) { - BookingRequest updatedBookingRequest = bookingRequestRepository.save(booking); - createDeepObjectsForBookingRequest(bookingRequest, updatedBookingRequest); - return updatedBookingRequest; + private Booking saveBooking(Booking booking, BookingRequestTO bookingRequest) { + var updatedBooking = bookingRepository.save(booking); + createDeepObjectsForBookingData(bookingRequest, updatedBooking.getBookingData()); + return updatedBooking; } - private BookingRequest mapToBooking(BookingRequestTO bookingRequest) { - return mapToBooking(bookingRequest, null); - } - - private BookingRequest mapToBooking(BookingRequestTO bookingRequest, BookingRequest updateFor) { + private BookingData mapToBookingData(BookingRequestTO bookingRequest) { var voyage = voyageService.resolveVoyage(bookingRequest); var vessel = vesselService.resolveVessel(bookingRequest); - var bookingBuilder = bookingRequestMapper.toDAO(bookingRequest, voyage, vessel).toBuilder(); - if (updateFor != null) { - bookingBuilder = bookingBuilder - // Carry over from the existing booking - // FIXME: This should not be done via a builder. - .carrierBookingRequestReference(updateFor.getCarrierBookingRequestReference()) - .bookingStatus(updateFor.getBookingStatus()) - .bookingRequestCreatedDateTime(updateFor.getBookingRequestCreatedDateTime()); - } - var booking = bookingBuilder.build(); + var booking = bookingDataMapper.toDAO(bookingRequest, voyage, vessel); booking.assignRequestedEquipment( bookingRequest.requestedEquipments() .stream() diff --git a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/ConfirmedBookingService.java b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/ConfirmedBookingService.java index 4f1959e9..573f4354 100644 --- a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/ConfirmedBookingService.java +++ b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/ConfirmedBookingService.java @@ -1,8 +1,8 @@ package org.dcsa.edocumentation.service; import lombok.RequiredArgsConstructor; -import org.dcsa.edocumentation.domain.persistence.repository.ConfirmedBookingRepository; -import org.dcsa.edocumentation.service.mapping.ConfirmedBookingMapper; +import org.dcsa.edocumentation.domain.persistence.repository.BookingRepository; +import org.dcsa.edocumentation.service.mapping.BookingMapper; import org.dcsa.edocumentation.transferobjects.ConfirmedBookingTO; import org.dcsa.skernel.errors.exceptions.ConcreteRequestErrorMessageException; import org.springframework.stereotype.Service; @@ -10,13 +10,13 @@ @Service @RequiredArgsConstructor public class ConfirmedBookingService { - private final ConfirmedBookingRepository confirmedBookingRepository; - private final ConfirmedBookingMapper confirmedBookingMapper; + private final BookingRepository bookingRepository; + private final BookingMapper bookingMapper; public ConfirmedBookingTO findConfirmedBooking(String carrierBookingReference) { - return confirmedBookingRepository - .findConfirmedBookingByCarrierBookingReference(carrierBookingReference) - .map(confirmedBookingMapper::confirmedBookingToConfirmedBookingTO) + return bookingRepository + .findByCarrierBookingReference(carrierBookingReference) + .map(bookingMapper::toConfirmedDTO) .orElseThrow( () -> ConcreteRequestErrorMessageException.notFound( diff --git a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/DocumentPartyService.java b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/DocumentPartyService.java index 65275227..7d86f00c 100644 --- a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/DocumentPartyService.java +++ b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/DocumentPartyService.java @@ -1,7 +1,11 @@ package org.dcsa.edocumentation.service; +import jakarta.transaction.Transactional; +import jakarta.transaction.Transactional.TxType; +import java.util.Collection; +import java.util.List; import lombok.RequiredArgsConstructor; -import org.dcsa.edocumentation.domain.persistence.entity.BookingRequest; +import org.dcsa.edocumentation.domain.persistence.entity.BookingData; import org.dcsa.edocumentation.domain.persistence.entity.DocumentParty; import org.dcsa.edocumentation.domain.persistence.entity.ShippingInstruction; import org.dcsa.edocumentation.domain.persistence.repository.DocumentPartyRepository; @@ -10,11 +14,6 @@ import org.dcsa.edocumentation.transferobjects.DocumentPartyTO; import org.springframework.stereotype.Service; -import jakarta.transaction.Transactional; -import jakarta.transaction.Transactional.TxType; -import java.util.Collection; -import java.util.List; - @Service @RequiredArgsConstructor public class DocumentPartyService { @@ -26,9 +25,9 @@ public class DocumentPartyService { private final PartyService partyService; @Transactional(TxType.MANDATORY) - public void createDocumentParties(Collection documentParties, BookingRequest bookingRequest) { + public void createDocumentParties(Collection documentParties, BookingData bookingData) { if (documentParties != null && !documentParties.isEmpty()) { - documentParties.forEach(documentPartyTO -> createDocumentParty(documentPartyTO, bookingRequest)); + documentParties.forEach(documentPartyTO -> createDocumentParty(documentPartyTO, bookingData)); } } @@ -47,9 +46,9 @@ public void createDocumentParties( } } - private void createDocumentParty(DocumentPartyTO documentPartyTO, BookingRequest bookingRequest) { + private void createDocumentParty(DocumentPartyTO documentPartyTO, BookingData bookingData) { DocumentParty documentPartyWithBooking = - documentPartyMapper.toDAO(documentPartyTO, bookingRequest).toBuilder() + documentPartyMapper.toDAO(documentPartyTO, bookingData).toBuilder() .party(partyService.createParty(documentPartyTO.party())) .displayedAddress(displayedAddressMapper.toDAO(documentPartyTO.displayedAddress())) .build(); diff --git a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/ReferenceService.java b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/ReferenceService.java index 00250a26..6736eee9 100644 --- a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/ReferenceService.java +++ b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/ReferenceService.java @@ -1,7 +1,11 @@ package org.dcsa.edocumentation.service; +import jakarta.transaction.Transactional; +import jakarta.transaction.Transactional.TxType; +import java.util.Collection; +import java.util.List; import lombok.RequiredArgsConstructor; -import org.dcsa.edocumentation.domain.persistence.entity.BookingRequest; +import org.dcsa.edocumentation.domain.persistence.entity.BookingData; import org.dcsa.edocumentation.domain.persistence.entity.Reference; import org.dcsa.edocumentation.domain.persistence.entity.ShippingInstruction; import org.dcsa.edocumentation.domain.persistence.repository.ReferenceRepository; @@ -9,11 +13,6 @@ import org.dcsa.edocumentation.transferobjects.ReferenceTO; import org.springframework.stereotype.Service; -import jakarta.transaction.Transactional; -import jakarta.transaction.Transactional.TxType; -import java.util.Collection; -import java.util.List; - @Service @RequiredArgsConstructor public class ReferenceService { @@ -21,10 +20,10 @@ public class ReferenceService { private final ReferenceMapper referenceMapper; @Transactional(TxType.MANDATORY) - public void createReferences(Collection references, BookingRequest bookingRequest) { + public void createReferences(Collection references, BookingData bookingData) { if (references != null && !references.isEmpty()) { List referenceDAOs = - references.stream().map(r -> referenceMapper.toDAO(r, bookingRequest)).toList(); + references.stream().map(r -> referenceMapper.toDAO(r, bookingData)).toList(); saveReferenceDAOs(referenceDAOs); } } diff --git a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/ShipmentLocationService.java b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/ShipmentLocationService.java index 42c72c05..5a0257a9 100644 --- a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/ShipmentLocationService.java +++ b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/ShipmentLocationService.java @@ -5,8 +5,7 @@ import java.util.Collection; import java.util.function.Function; import lombok.RequiredArgsConstructor; -import org.dcsa.edocumentation.domain.persistence.entity.BookingRequest; -import org.dcsa.edocumentation.domain.persistence.entity.ConfirmedBooking; +import org.dcsa.edocumentation.domain.persistence.entity.BookingData; import org.dcsa.edocumentation.domain.persistence.entity.ShipmentLocation; import org.dcsa.edocumentation.domain.persistence.repository.ShipmentLocationRepository; import org.dcsa.edocumentation.service.mapping.ShipmentLocationMapper; @@ -20,17 +19,9 @@ public class ShipmentLocationService { private final ShipmentLocationMapper shipmentLocationMapper; @Transactional(TxType.MANDATORY) - public void createShipmentLocations( - Collection shipmentLocations, BookingRequest bookingRequest) { + public void createShipmentLocations(Collection shipmentLocations, BookingData bookingData) { createShipments(shipmentLocations, - (slTO) -> this.shipmentLocationMapper.toDAO(slTO, bookingRequest) - ); - } - - @Transactional(TxType.MANDATORY) - public void createShipmentLocations(Collection shipmentLocations, ConfirmedBooking confirmedBooking) { - createShipments(shipmentLocations, - (slTO) -> this.shipmentLocationMapper.toDAO(slTO, confirmedBooking) + slTO -> this.shipmentLocationMapper.toDAO(slTO, bookingData) ); } diff --git a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/ShipmentTransportService.java b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/ShipmentTransportService.java index 5e20d289..43ec30e6 100644 --- a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/ShipmentTransportService.java +++ b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/ShipmentTransportService.java @@ -4,7 +4,7 @@ import jakarta.transaction.Transactional.TxType; import java.util.Collection; import lombok.RequiredArgsConstructor; -import org.dcsa.edocumentation.domain.persistence.entity.ConfirmedBooking; +import org.dcsa.edocumentation.domain.persistence.entity.BookingData; import org.dcsa.edocumentation.domain.persistence.repository.ShipmentTransportRepository; import org.dcsa.edocumentation.service.mapping.ShipmentTransportMapper; import org.dcsa.edocumentation.transferobjects.TransportTO; @@ -17,7 +17,7 @@ public class ShipmentTransportService { private final ShipmentTransportMapper shipmentTransportMapper; @Transactional(TxType.MANDATORY) - public void createShipmentTransports(Collection shipmentTransports, ConfirmedBooking confirmedBooking) { + public void createShipmentTransports(Collection shipmentTransports, BookingData bookingData) { if (shipmentTransports != null && !shipmentTransports.isEmpty()) { shipmentTransportRepository.saveAll( shipmentTransports.stream() @@ -25,7 +25,7 @@ public void createShipmentTransports(Collection shipmentTransports, sl -> shipmentTransportMapper.toDAO( sl, - confirmedBooking, + bookingData, sl.loadLocation(), sl.dischargeLocation() )) diff --git a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/ShippingInstructionService.java b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/ShippingInstructionService.java index c106a69e..87eeef8c 100644 --- a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/ShippingInstructionService.java +++ b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/ShippingInstructionService.java @@ -8,10 +8,9 @@ import lombok.RequiredArgsConstructor; import org.dcsa.edocumentation.domain.persistence.entity.*; import org.dcsa.edocumentation.domain.persistence.entity.CargoItem; -import org.dcsa.edocumentation.domain.persistence.entity.ConfirmedBooking; import org.dcsa.edocumentation.domain.persistence.entity.ShippingInstruction; import org.dcsa.edocumentation.domain.persistence.entity.UtilizedTransportEquipment; -import org.dcsa.edocumentation.domain.persistence.repository.ConfirmedBookingRepository; +import org.dcsa.edocumentation.domain.persistence.repository.BookingRepository; import org.dcsa.edocumentation.domain.persistence.repository.ShippingInstructionRepository; import org.dcsa.edocumentation.service.mapping.ShippingInstructionMapper; import org.dcsa.edocumentation.transferobjects.ShippingInstructionRefStatusTO; @@ -28,7 +27,7 @@ public class ShippingInstructionService { private final DocumentPartyService documentPartyService; private final ReferenceService referenceService; private final UtilizedTransportEquipmentService utilizedTransportEquipmentService; - private final ConfirmedBookingRepository confirmedBookingRepository; + private final BookingRepository bookingRepository; @Transactional public Optional findByReference(String shippingInstructionReference) { @@ -82,14 +81,14 @@ public void resolveStuffing( // A Shipping instruction must link to a shipment (=approved booking) consignmentItems acts like a // 'join-table' between shipping instruction and shipment - private ConfirmedBooking resolveConfirmedBooking(String carrierBookingReference) { - return confirmedBookingRepository + private Booking resolveConfirmedBooking(String carrierBookingReference) { + return bookingRepository .findByCarrierBookingReference(carrierBookingReference) .orElse(null); } - private Commodity resolveCommodity(@NotNull ConfirmedBooking shipment, @NotNull String commoditySubreference) { - for (var reg : shipment.getBooking().getRequestedEquipments()) { + private Commodity resolveCommodity(@NotNull Booking booking, @NotNull String commoditySubreference) { + for (var reg : booking.getBookingData().getRequestedEquipments()) { for (var commodity : reg.getCommodities()) { if (Objects.equals(commoditySubreference, commodity.getCommoditySubreference())) { return commodity; diff --git a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/TransportDocumentService.java b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/TransportDocumentService.java index 088b5298..ab24d3d6 100644 --- a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/TransportDocumentService.java +++ b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/TransportDocumentService.java @@ -1,6 +1,7 @@ package org.dcsa.edocumentation.service; import jakarta.transaction.Transactional; + import java.util.Optional; import lombok.RequiredArgsConstructor; import org.dcsa.edocumentation.domain.persistence.entity.*; @@ -44,33 +45,34 @@ public Optional findByReference(String transportDocumentRef private String getTermsAndConditions(TransportDocument transportDocument) { return Optional.ofNullable(transportDocument.getShippingInstruction()) - .map(ShippingInstruction::retrieveOneShipment) - .map(ConfirmedBooking::getTermsAndConditions) + .map(ShippingInstruction::retrieveOneBooking) + .map(Booking::getLastConfirmedBookingData) + .map(BookingData::getTermsAndConditions) .orElse(null); } private Float getDeclaredValue(TransportDocument transportDocument) { - return getBooking(transportDocument) - .map(BookingRequest::getDeclaredValue) + return getLastConfirmedBookingData(transportDocument) + .map(BookingData::getDeclaredValue) .orElse(null); } private String getDeclaredValueCurrency(TransportDocument transportDocument) { - return getBooking(transportDocument) - .map(BookingRequest::getDeclaredValueCurrency) + return getLastConfirmedBookingData(transportDocument) + .map(BookingData::getDeclaredValueCurrency) .orElse(null); } private String getServiceContractReference(TransportDocument transportDocument) { - return getBooking(transportDocument) - .map(BookingRequest::getServiceContractReference) + return getLastConfirmedBookingData(transportDocument) + .map(BookingData::getServiceContractReference) .orElse(null); } - private Optional getBooking(TransportDocument transportDocument) { + private Optional getLastConfirmedBookingData(TransportDocument transportDocument) { return Optional.ofNullable(transportDocument.getShippingInstruction()) - .map(ShippingInstruction::retrieveOneShipment) - .map(ConfirmedBooking::getBooking); + .map(ShippingInstruction::retrieveOneBooking) + .map(Booking::getLastConfirmedBookingData); } private TransportDocumentTO.TransportDocumentTOBuilder resolveCarrierCodeListProvider( diff --git a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/AdvanceManifestFilingMapper.java b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/AdvanceManifestFilingMapper.java index 68cfdce6..17d20276 100644 --- a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/AdvanceManifestFilingMapper.java +++ b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/AdvanceManifestFilingMapper.java @@ -1,9 +1,7 @@ package org.dcsa.edocumentation.service.mapping; import org.dcsa.edocumentation.domain.persistence.entity.AdvanceManifestFiling; -import org.dcsa.edocumentation.domain.persistence.entity.Location; import org.dcsa.edocumentation.transferobjects.AdvanceManifestFilingTO; -import org.dcsa.edocumentation.transferobjects.LocationTO; import org.mapstruct.Mapper; import org.mapstruct.Mapping; @@ -11,6 +9,6 @@ public interface AdvanceManifestFilingMapper { AdvanceManifestFilingTO toDTO(AdvanceManifestFiling filing); @Mapping(target = "manifest_id", ignore = true) - @Mapping(target = "confirmedBooking", ignore = true) + @Mapping(target = "bookingData", ignore = true) AdvanceManifestFiling toDAO(AdvanceManifestFilingTO manifestFilingTO); } diff --git a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/BookingRequestMapper.java b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/BookingDataMapper.java similarity index 55% rename from edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/BookingRequestMapper.java rename to edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/BookingDataMapper.java index 466c1abe..b714b367 100644 --- a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/BookingRequestMapper.java +++ b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/BookingDataMapper.java @@ -1,9 +1,8 @@ package org.dcsa.edocumentation.service.mapping; -import org.dcsa.edocumentation.domain.persistence.entity.BookingRequest; +import org.dcsa.edocumentation.domain.persistence.entity.BookingData; import org.dcsa.edocumentation.domain.persistence.entity.Vessel; import org.dcsa.edocumentation.domain.persistence.entity.Voyage; -import org.dcsa.edocumentation.transferobjects.BookingRequestRefStatusTO; import org.dcsa.edocumentation.transferobjects.BookingRequestTO; import org.mapstruct.Mapper; import org.mapstruct.Mapping; @@ -22,28 +21,27 @@ ShipmentLocationMapper.class, } ) -public interface BookingRequestMapper { +public interface BookingDataMapper { @Mapping(target = "requestedEquipments", ignore = true) @Mapping(target = "shipmentLocations", ignore = true) @Mapping(target = "documentParties", ignore = true) @Mapping(target = "id", ignore = true) - @Mapping(target = "isNew", ignore = true) - @Mapping(target = "validUntil", ignore = true) // To make it pick up the parameter @Mapping(source = "voyage", target = "voyage") // TODO: Align names between TO and DAO @Mapping(source = "bookingRequestTO.placeOfBLIssue", target = "placeOfIssue") - BookingRequest toDAO(BookingRequestTO bookingRequestTO, Voyage voyage, Vessel vessel); + // Carrier-only fields - they cannot (and should not) provided by the shipper. + // Therefore, it is fine to ignore these. + @Mapping(target = "carrier", ignore = true) + @Mapping(target = "termsAndConditions", ignore = true) + @Mapping(target = "carrierClauses", ignore = true) + @Mapping(target = "shipmentTransports", ignore = true) + @Mapping(target = "shipmentCutOffTimes", ignore = true) + @Mapping(target = "confirmedEquipments", ignore = true) + @Mapping(target = "charges", ignore = true) + @Mapping(target = "advanceManifestFilings", ignore = true) + BookingData toDAO(BookingRequestTO bookingRequestTO, Voyage voyage, Vessel vessel); - @Mapping(source = "placeOfIssue", target = "placeOfBLIssue") - @Mapping(source = "voyage.universalVoyageReference", target = "universalExportVoyageReference") - @Mapping(source = "voyage.carrierVoyageNumber", target = "carrierExportVoyageNumber") - @Mapping(source = "voyage.service.carrierServiceCode", target = "carrierServiceCode") - @Mapping(source = "voyage.service.universalServiceReference", target = "universalServiceReference") - @Mapping(source = "vessel.vesselIMONumber", target = "vesselIMONumber") - BookingRequestTO toDTO(BookingRequest bookingRequest); - - BookingRequestRefStatusTO toStatusDTO(BookingRequest bookingRequest); } diff --git a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/BookingMapper.java b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/BookingMapper.java new file mode 100644 index 00000000..d07e1eb4 --- /dev/null +++ b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/BookingMapper.java @@ -0,0 +1,84 @@ +package org.dcsa.edocumentation.service.mapping; + +import org.dcsa.edocumentation.domain.persistence.entity.Booking; +import org.dcsa.edocumentation.transferobjects.BookingRequestRefStatusTO; +import org.dcsa.edocumentation.transferobjects.BookingRequestTO; +import org.dcsa.edocumentation.transferobjects.ConfirmedBookingTO; +import org.dcsa.edocumentation.transferobjects.unofficial.ConfirmedBookingRefStatusTO; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +@Mapper( + componentModel = "spring", + config = EDocumentationMappingConfig.class, + uses = { + LocationMapper.class, + DisplayedAddressMapper.class, + DocumentPartyMapper.class, + RequestedEquipmentGroupMapper.class, + CommodityMapper.class, + RequestedChangeMapper.class, + ReferenceMapper.class, + ShipmentLocationMapper.class, + TransportMapper.class, + } +) +public interface BookingMapper { + + @Mapping(source = "bookingData.receiptTypeAtOrigin", target = "receiptTypeAtOrigin") + @Mapping(source = "bookingData.deliveryTypeAtDestination", target = "deliveryTypeAtDestination") + @Mapping(source = "bookingData.cargoMovementTypeAtOrigin", target = "cargoMovementTypeAtOrigin") + @Mapping(source = "bookingData.cargoMovementTypeAtDestination", target = "cargoMovementTypeAtDestination") + @Mapping(source = "bookingData.serviceContractReference", target = "serviceContractReference") + @Mapping(source = "bookingData.declaredValue", target = "declaredValue") + @Mapping(source = "bookingData.declaredValueCurrency", target = "declaredValueCurrency") + @Mapping(source = "bookingData.paymentTermCode", target = "paymentTermCode") + @Mapping(source = "bookingData.isPartialLoadAllowed", target = "isPartialLoadAllowed") + @Mapping(source = "bookingData.isExportDeclarationRequired", target = "isExportDeclarationRequired") + @Mapping(source = "bookingData.exportDeclarationReference", target = "exportDeclarationReference") + @Mapping(source = "bookingData.isImportLicenseRequired", target = "isImportLicenseRequired") + @Mapping(source = "bookingData.importLicenseReference", target = "importLicenseReference") + @Mapping(source = "bookingData.isAMSACIFilingRequired", target = "isAMSACIFilingRequired") + @Mapping(source = "bookingData.isDestinationFilingRequired", target = "isDestinationFilingRequired") + @Mapping(source = "bookingData.contractQuotationReference", target = "contractQuotationReference") + @Mapping(source = "bookingData.expectedDepartureDate", target = "expectedDepartureDate") + @Mapping(source = "bookingData.expectedArrivalAtPlaceOfDeliveryStartDate", target = "expectedArrivalAtPlaceOfDeliveryStartDate") + @Mapping(source = "bookingData.expectedArrivalAtPlaceOfDeliveryEndDate", target = "expectedArrivalAtPlaceOfDeliveryEndDate") + @Mapping(source = "bookingData.transportDocumentTypeCode", target = "transportDocumentTypeCode") + @Mapping(source = "bookingData.transportDocumentReference", target = "transportDocumentReference") + @Mapping(source = "bookingData.bookingChannelReference", target = "bookingChannelReference") + @Mapping(source = "bookingData.incoTerms", target = "incoTerms") + @Mapping(source = "bookingData.communicationChannelCode", target = "communicationChannelCode") + @Mapping(source = "bookingData.isEquipmentSubstitutionAllowed", target = "isEquipmentSubstitutionAllowed") + @Mapping(source = "bookingData.invoicePayableAt", target = "invoicePayableAt") + @Mapping(source = "bookingData.requestedEquipments", target = "requestedEquipments") + @Mapping(source = "bookingData.references", target = "references") + @Mapping(source = "bookingData.documentParties", target = "documentParties") + @Mapping(source = "bookingData.shipmentLocations", target = "shipmentLocations") + @Mapping(source = "bookingData.placeOfIssue", target = "placeOfBLIssue") + @Mapping(source = "bookingData.voyage.universalVoyageReference", target = "universalExportVoyageReference") + @Mapping(source = "bookingData.voyage.carrierVoyageNumber", target = "carrierExportVoyageNumber") + @Mapping(source = "bookingData.voyage.service.carrierServiceCode", target = "carrierServiceCode") + @Mapping(source = "bookingData.voyage.service.universalServiceReference", target = "universalServiceReference") + @Mapping(source = "bookingData.vessel.vesselIMONumber", target = "vesselIMONumber") + BookingRequestTO toDTO(Booking booking); + + @Mapping(source = "bookingData.termsAndConditions", target = "termsAndConditions") + @Mapping(source = "booking", target = "booking") + @Mapping(source = "bookingData.shipmentTransports", target = "transports") + @Mapping(source = "bookingData.shipmentCutOffTimes", target = "shipmentCutOffTimes") + @Mapping(source = "bookingData.shipmentLocations", target = "shipmentLocations") + @Mapping(source = "bookingData.confirmedEquipments", target = "confirmedEquipments") + @Mapping(source = "bookingData.advanceManifestFilings", target = "advanceManifestFilings") + @Mapping(source = "bookingData.charges", target = "charges") + @Mapping(source = "bookingData.carrierClauses", target = "carrierClauses") + // TODO: Remove later (in DT-389) + @Mapping(source = "bookingRequestCreatedDateTime", target = "shipmentCreatedDateTime") + @Mapping(source = "bookingRequestUpdatedDateTime", target = "shipmentUpdatedDateTime") + ConfirmedBookingTO toConfirmedDTO(Booking booking); + + BookingRequestRefStatusTO toStatusDTO(Booking booking); + + ConfirmedBookingRefStatusTO toConfirmedStatusDTO(Booking booking); +} + diff --git a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/ConfirmedBookingMapper.java b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/ConfirmedBookingMapper.java deleted file mode 100644 index 9cdf2d33..00000000 --- a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/ConfirmedBookingMapper.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.dcsa.edocumentation.service.mapping; - -import org.dcsa.edocumentation.domain.persistence.entity.ConfirmedBooking; -import org.dcsa.edocumentation.transferobjects.unofficial.ConfirmedBookingRefStatusTO; -import org.dcsa.edocumentation.transferobjects.ConfirmedBookingTO; -import org.mapstruct.InjectionStrategy; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.ReportingPolicy; - -@Mapper(componentModel = "spring", - injectionStrategy = InjectionStrategy.CONSTRUCTOR, - unmappedTargetPolicy = ReportingPolicy.WARN, // FIXME; Remove this line when we can migrate to ERROR - config = EDocumentationMappingConfig.class, - uses = { - LocationMapper.class, - BookingRequestMapper.class, - TransportMapper.class, - ConfirmedEquipmentMapper.class, - ShipmentCutOffTimeMapper.class, - AdvanceManifestFilingMapper.class - }) -public interface ConfirmedBookingMapper { - @Mapping(source = "shipmentTransports", target = "transports") - ConfirmedBookingTO confirmedBookingToConfirmedBookingTO(ConfirmedBooking confirmedBooking); - - @Mapping(source = "confirmedBooking.booking.bookingRequestUpdatedDateTime", target = "bookingRequestUpdatedDateTime") - @Mapping(source = "confirmedBooking.booking.bookingRequestCreatedDateTime", target = "bookingRequestCreatedDateTime") - ConfirmedBookingRefStatusTO toStatusDTO(ConfirmedBooking confirmedBooking, String bookingStatus); -} diff --git a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/ConfirmedEquipmentMapper.java b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/ConfirmedEquipmentMapper.java index aa583b34..071015a7 100644 --- a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/ConfirmedEquipmentMapper.java +++ b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/ConfirmedEquipmentMapper.java @@ -11,7 +11,7 @@ @Mapper(componentModel = "spring", config = EDocumentationMappingConfig.class) public interface ConfirmedEquipmentMapper { @Mapping(target = "id", ignore = true) - @Mapping(target = "confirmedBooking", ignore = true) + @Mapping(target = "bookingData", ignore = true) ConfirmedEquipment toDAO(ConfirmedEquipmentTO shipmentCutOffTimeTO); ConfirmedEquipmentTO toTO(ConfirmedEquipment shipmentCutOffTime); diff --git a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/ConsignmentItemMapper.java b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/ConsignmentItemMapper.java index df66c684..4a972678 100644 --- a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/ConsignmentItemMapper.java +++ b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/ConsignmentItemMapper.java @@ -4,7 +4,6 @@ import org.dcsa.edocumentation.transferobjects.ConsignmentItemTO; import org.mapstruct.Mapper; import org.mapstruct.Mapping; -import org.springframework.beans.factory.annotation.Autowired; @Mapper( componentModel = "spring", @@ -19,7 +18,7 @@ public interface ConsignmentItemMapper { @Mapping(target = "id", ignore = true) @Mapping(target = "shippingInstruction", ignore = true) - @Mapping(target = "confirmedBooking", ignore = true) + @Mapping(target = "booking", ignore = true) @Mapping(target = "commodity", ignore = true) ConsignmentItem toDAO(ConsignmentItemTO consignmentItemTO); diff --git a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/DocumentPartyMapper.java b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/DocumentPartyMapper.java index d1a04ff8..f13cc60e 100644 --- a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/DocumentPartyMapper.java +++ b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/DocumentPartyMapper.java @@ -14,11 +14,11 @@ }) public interface DocumentPartyMapper { - @Mapping(source = "bookingRequest", target = "bookingRequest") - @Mapping(source = "bookingRequest.id", target = "id", ignore = true) + @Mapping(source = "bookingData", target = "bookingData") + @Mapping(source = "bookingData.id", target = "id", ignore = true) @Mapping(source = "documentPartyTO.displayedAddress", target = "displayedAddress", ignore = true) @Mapping(target = "shippingInstructionID", ignore = true) - DocumentParty toDAO(DocumentPartyTO documentPartyTO, BookingRequest bookingRequest); + DocumentParty toDAO(DocumentPartyTO documentPartyTO, BookingData bookingData); default DocumentParty toDAO(DocumentPartyTO documentPartyTO) { return this.toDAO(documentPartyTO, null); diff --git a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/ReferenceMapper.java b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/ReferenceMapper.java index 6948e67d..c6704f3c 100644 --- a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/ReferenceMapper.java +++ b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/ReferenceMapper.java @@ -1,9 +1,6 @@ package org.dcsa.edocumentation.service.mapping; -import org.dcsa.edocumentation.domain.persistence.entity.BookingRequest; -import org.dcsa.edocumentation.domain.persistence.entity.ConsignmentItem; -import org.dcsa.edocumentation.domain.persistence.entity.Reference; -import org.dcsa.edocumentation.domain.persistence.entity.ShippingInstruction; +import org.dcsa.edocumentation.domain.persistence.entity.*; import org.dcsa.edocumentation.transferobjects.ReferenceTO; import org.mapstruct.Mapper; import org.mapstruct.Mapping; @@ -11,13 +8,13 @@ @Mapper(componentModel = "spring", config = EDocumentationMappingConfig.class) public interface ReferenceMapper { - @Mapping(source = "bookingRequest", target = "bookingRequest") + @Mapping(source = "bookingData", target = "bookingData") @Mapping(source = "shippingInstruction.id", target = "shippingInstructionID") @Mapping(target = "referenceID", ignore = true) - Reference toDAO(ReferenceTO referenceTO, BookingRequest bookingRequest, ShippingInstruction shippingInstruction, ConsignmentItem consignmentItem); + Reference toDAO(ReferenceTO referenceTO, BookingData bookingData, ShippingInstruction shippingInstruction, ConsignmentItem consignmentItem); - default Reference toDAO(ReferenceTO referenceTO, BookingRequest bookingRequest) { - return toDAO(referenceTO, bookingRequest, null, null); + default Reference toDAO(ReferenceTO referenceTO, BookingData bookingData) { + return toDAO(referenceTO, bookingData, null, null); } default Reference toDAO(ReferenceTO referenceTO, ShippingInstruction shippingInstruction) { diff --git a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/RequestedEquipmentGroupMapper.java b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/RequestedEquipmentGroupMapper.java index 47a8f6fd..eb547571 100644 --- a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/RequestedEquipmentGroupMapper.java +++ b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/RequestedEquipmentGroupMapper.java @@ -19,7 +19,7 @@ public abstract class RequestedEquipmentGroupMapper { @Autowired protected CommodityMapper commodityMapper; - @Mapping(target = "bookingRequest", ignore = true) + @Mapping(target = "bookingData", ignore = true) @Mapping(target = "id", ignore = true) @Mapping(target = "commodities", ignore = true) protected abstract RequestedEquipmentGroup toDAOInternal(RequestedEquipmentTO requestedEquipment); diff --git a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/ShipmentCutOffTimeMapper.java b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/ShipmentCutOffTimeMapper.java index 2e2375c5..d54c12ce 100644 --- a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/ShipmentCutOffTimeMapper.java +++ b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/ShipmentCutOffTimeMapper.java @@ -9,7 +9,7 @@ @Mapper(componentModel = "spring", config = EDocumentationMappingConfig.class) public interface ShipmentCutOffTimeMapper { @Mapping(target = "id", ignore = true) - @Mapping(target = "confirmedBooking", ignore = true) + @Mapping(target = "bookingData", ignore = true) ShipmentCutOffTime toDAO(ShipmentCutOffTimeTO shipmentCutOffTimeTO); ShipmentCutOffTimeTO toTO(ShipmentCutOffTime shipmentCutOffTime); diff --git a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/ShipmentLocationMapper.java b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/ShipmentLocationMapper.java index 8c6422bd..e162100d 100644 --- a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/ShipmentLocationMapper.java +++ b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/ShipmentLocationMapper.java @@ -1,7 +1,6 @@ package org.dcsa.edocumentation.service.mapping; -import org.dcsa.edocumentation.domain.persistence.entity.BookingRequest; -import org.dcsa.edocumentation.domain.persistence.entity.ConfirmedBooking; +import org.dcsa.edocumentation.domain.persistence.entity.BookingData; import org.dcsa.edocumentation.domain.persistence.entity.ShipmentLocation; import org.dcsa.edocumentation.transferobjects.ShipmentLocationTO; import org.mapstruct.Mapper; @@ -10,15 +9,9 @@ @Mapper(componentModel = "spring", config = EDocumentationMappingConfig.class, uses = LocationMapper.class) public interface ShipmentLocationMapper { - @Mapping(target = "id", ignore = true) /* It defaults to pulling booking.getId(), which is wrong */ - @Mapping(target = "confirmedBooking", ignore = true) - ShipmentLocation toDAO(ShipmentLocationTO shipmentLocationTO, BookingRequest bookingRequest); - - @Mapping(target = "id", ignore = true) /* It defaults to pulling booking.getId(), which is wrong */ - // Otherwise, it pulls the booking out of the confirmedBooking and throws away the confirmedBooking - @Mapping(target = "bookingRequest", ignore = true) - @Mapping(source = "confirmedBooking", target = "confirmedBooking") - ShipmentLocation toDAO(ShipmentLocationTO shipmentLocationTO, ConfirmedBooking confirmedBooking); + @Mapping(target = "id", ignore = true) /* It defaults to pulling bookingData.getId(), which is wrong */ + @Mapping(source = "bookingData", target = "bookingData") + ShipmentLocation toDAO(ShipmentLocationTO shipmentLocationTO, BookingData bookingData); ShipmentLocationTO toDTO(ShipmentLocation shipmentLocation); } diff --git a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/ShipmentTransportMapper.java b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/ShipmentTransportMapper.java index 6db72a2d..d6dd6c5a 100644 --- a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/ShipmentTransportMapper.java +++ b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/ShipmentTransportMapper.java @@ -1,6 +1,6 @@ package org.dcsa.edocumentation.service.mapping; -import org.dcsa.edocumentation.domain.persistence.entity.ConfirmedBooking; +import org.dcsa.edocumentation.domain.persistence.entity.BookingData; import org.dcsa.edocumentation.domain.persistence.entity.ShipmentTransport; import org.dcsa.edocumentation.transferobjects.LocationTO; import org.dcsa.edocumentation.transferobjects.TransportTO; @@ -11,13 +11,13 @@ public interface ShipmentTransportMapper { // Required to make the mapper use the argument rather than throwing it away - @Mapping(source = "confirmedBooking", target = "confirmedBooking") + @Mapping(source = "bookingData", target = "bookingData") @Mapping(source = "loadLocation", target = "loadLocation") @Mapping(source = "dischargeLocation", target = "dischargeLocation") @Mapping(source = "shipmentTransportTO.transportPlanStage", target = "transportPlanStageCode") @Mapping(target = "id", ignore = true) ShipmentTransport toDAO(TransportTO shipmentTransportTO, - ConfirmedBooking confirmedBooking, + BookingData bookingData, LocationTO loadLocation, LocationTO dischargeLocation ); diff --git a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/TransportDocumentMapper.java b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/TransportDocumentMapper.java index 38962681..762f541b 100755 --- a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/TransportDocumentMapper.java +++ b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/mapping/TransportDocumentMapper.java @@ -1,7 +1,7 @@ package org.dcsa.edocumentation.service.mapping; import java.time.LocalDate; - +import java.util.Objects; import org.dcsa.edocumentation.domain.persistence.entity.*; import org.dcsa.edocumentation.domain.persistence.entity.enums.DCSATransportType; import org.dcsa.edocumentation.domain.persistence.entity.enums.LocationType; @@ -93,40 +93,54 @@ Transport Document Type Code (if provided) @Mapping(source= "transportDocument.shippingInstruction.customsReferences", target = "customsReferences") public abstract TransportDocumentTO toDTO(TransportDocument transportDocument); - protected ConfirmedBooking resolveAnyShipment(TransportDocument document) { - return document.getShippingInstruction().getConsignmentItems().iterator().next().getConfirmedBooking(); + protected Booking resolveAnyBooking(TransportDocument document) { + return resolveAnyBooking(document.getShippingInstruction()); + } + + protected Booking resolveAnyBooking(ShippingInstruction shippingInstruction) { + return shippingInstruction.getConsignmentItems().iterator().next().getBooking(); + } + + protected BookingData resolveAnyBookingData(TransportDocument document) { + return Objects.requireNonNull( + resolveAnyBooking(document).getLastConfirmedBookingData(), + "Cannot generate a transport document if the booking was never confirmed!" + ); } - protected BookingRequest resolveAnyBooking(TransportDocument document) { - return resolveAnyShipment(document).getBooking(); + protected BookingData resolveAnyBookingData(ShippingInstruction shippingInstruction) { + return Objects.requireNonNull( + resolveAnyBooking(shippingInstruction).getLastConfirmedBookingData(), + "Cannot generate a transport document if the booking was never confirmed!" + ); } protected String termsAndConditions(TransportDocument document) { - return resolveAnyShipment(document).getTermsAndConditions(); + return resolveAnyBookingData(document).getTermsAndConditions(); } protected String serviceContractReference(TransportDocument document) { - return resolveAnyBooking(document).getServiceContractReference(); + return resolveAnyBookingData(document).getServiceContractReference(); } protected String contractQuotationReference(TransportDocument document) { - return resolveAnyBooking(document).getContractQuotationReference(); + return resolveAnyBookingData(document).getContractQuotationReference(); } protected ReceiptDeliveryType receiptTypeAtOrigin(TransportDocument document) { - return eMapper.toTO(resolveAnyBooking(document).getReceiptTypeAtOrigin()); + return eMapper.toTO(resolveAnyBookingData(document).getReceiptTypeAtOrigin()); } protected ReceiptDeliveryType deliveryTypeAtDestination(TransportDocument document) { - return eMapper.toTO(resolveAnyBooking(document).getDeliveryTypeAtDestination()); + return eMapper.toTO(resolveAnyBookingData(document).getDeliveryTypeAtDestination()); } protected CargoMovementType cargoMovementTypeAtOrigin(TransportDocument document) { - return eMapper.toTO(resolveAnyBooking(document).getCargoMovementTypeAtOrigin()); + return eMapper.toTO(resolveAnyBookingData(document).getCargoMovementTypeAtOrigin()); } protected CargoMovementType cargoMovementTypeAtDestination(TransportDocument document) { - return eMapper.toTO(resolveAnyBooking(document).getCargoMovementTypeAtDestination()); + return eMapper.toTO(resolveAnyBookingData(document).getCargoMovementTypeAtDestination()); } @@ -162,9 +176,9 @@ private boolean isSameLocation(Location lhs, Location rhs) { } protected TDTransportTO mapSIToTransports(ShippingInstruction shippingInstruction) { - var confirmedBooking = shippingInstruction.getConsignmentItems().iterator().next().getConfirmedBooking(); - var shipmentLocations = confirmedBooking.getShipmentLocations(); - var shipmentTransports = confirmedBooking.getShipmentTransports(); + var bookingData = resolveAnyBookingData(shippingInstruction); + var shipmentLocations = bookingData.getShipmentLocations(); + var shipmentTransports = bookingData.getShipmentTransports(); var preLoc = findLocation(shipmentLocations, LocationType.PRE); var polLoc = findLocation(shipmentLocations, LocationType.POL); diff --git a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/unofficial/ManageShipmentService.java b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/unofficial/ManageShipmentService.java index 36f2dd42..650ff645 100755 --- a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/unofficial/ManageShipmentService.java +++ b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/unofficial/ManageShipmentService.java @@ -1,43 +1,36 @@ package org.dcsa.edocumentation.service.unofficial; import jakarta.transaction.Transactional; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; import java.security.SecureRandom; import java.time.OffsetDateTime; import java.util.*; import java.util.function.Predicate; import java.util.stream.Collectors; - -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Pattern; -import jakarta.validation.constraints.Size; import lombok.RequiredArgsConstructor; -import org.dcsa.edocumentation.domain.persistence.entity.BookingRequest; -import org.dcsa.edocumentation.domain.persistence.entity.RequestedEquipmentGroup; -import org.dcsa.edocumentation.domain.persistence.entity.ConfirmedBooking; +import org.dcsa.edocumentation.domain.persistence.entity.*; import org.dcsa.edocumentation.domain.persistence.entity.unofficial.ValidationResult; import org.dcsa.edocumentation.domain.persistence.repository.*; import org.dcsa.edocumentation.service.ShipmentLocationService; import org.dcsa.edocumentation.service.ShipmentTransportService; -import org.dcsa.edocumentation.service.mapping.ConfirmedEquipmentMapper; -import org.dcsa.edocumentation.service.mapping.ShipmentCutOffTimeMapper; -import org.dcsa.edocumentation.service.mapping.AdvanceManifestFilingMapper; -import org.dcsa.edocumentation.service.mapping.ConfirmedBookingMapper; +import org.dcsa.edocumentation.service.mapping.*; import org.dcsa.edocumentation.transferobjects.*; import org.dcsa.edocumentation.transferobjects.enums.DCSATransportType; import org.dcsa.edocumentation.transferobjects.enums.ShipmentLocationTypeCode; import org.dcsa.edocumentation.transferobjects.enums.TransportPlanStageCode; -import org.dcsa.edocumentation.transferobjects.unofficial.ManageConfirmedBookingRequestTO; import org.dcsa.edocumentation.transferobjects.unofficial.ConfirmedBookingRefStatusTO; +import org.dcsa.edocumentation.transferobjects.unofficial.ManageConfirmedBookingRequestTO; import org.dcsa.skernel.errors.exceptions.ConcreteRequestErrorMessageException; import org.springframework.stereotype.Service; @Service @RequiredArgsConstructor public class ManageShipmentService { - private final ConfirmedBookingRepository confirmedBookingRepository; - private final BookingRequestRepository bookingRequestRepository; - private final ConfirmedBookingMapper confirmedBookingMapper; + private final BookingRepository bookingRepository; + private final BookingMapper bookingMapper; private final CarrierRepository carrierRepository; private final UnofficialBookingRequestService unofficialBookingRequestService; private final ShipmentLocationService shipmentLocationService; @@ -99,7 +92,7 @@ private String generateCommoditySubreference() { } private void assignCommoditySubreferences( - BookingRequest bookingRequest, + BookingData bookingData, List<@Valid List<@Valid @NotBlank @Size(max = 100) @Pattern(regexp = "^\\S(\\s+\\S+)*$") String>> subreferences ) { if (subreferences != null) { @@ -112,7 +105,7 @@ private void assignCommoditySubreferences( throw ConcreteRequestErrorMessageException.invalidInput("All commoditySubreferences must be unique" + " across the confirmedBooking"); } - var requestedEquipments = bookingRequest.getRequestedEquipments(); + var requestedEquipments = bookingData.getRequestedEquipments(); if (subreferences.size() != requestedEquipments.size()) { throw ConcreteRequestErrorMessageException.invalidInput("There are " + requestedEquipments.size() + " requested equipment groups but subreferences for " + subreferences.size() @@ -143,7 +136,7 @@ private void assignCommoditySubreferences( } } else { Set seen = new HashSet<>(); - bookingRequest.getRequestedEquipments().stream() + bookingData.getRequestedEquipments().stream() .map(RequestedEquipmentGroup::getCommodities) .flatMap(Collection::stream) .filter(c -> c.getCommoditySubreference() == null) @@ -166,35 +159,37 @@ private void assignCommoditySubreferences( @Transactional public ConfirmedBookingRefStatusTO create(ManageConfirmedBookingRequestTO shipmentRequestTO) { - BookingRequest bookingRequest = getBooking(shipmentRequestTO); + Booking booking = getBooking(shipmentRequestTO); var carrier = carrierRepository.findBySmdgCode(shipmentRequestTO.carrierSMDGCode()); if (carrier == null) { throw ConcreteRequestErrorMessageException.invalidInput("Unrecognized SMDG LCL party code \"" + shipmentRequestTO.carrierSMDGCode() + "\". Note the code may be valid but not loaded into this system."); } - OffsetDateTime confirmationTime = OffsetDateTime.now(); - ValidationResult validationResult = unofficialBookingRequestService.validateBooking(bookingRequest, false); - - assignCommoditySubreferences(bookingRequest, shipmentRequestTO.commoditySubreferences()); - - bookingRequest.confirm(confirmationTime); - - // FIXME: Check if the confirmedBooking (CBR) already exists and then attempt to reconfirm it if possible rather than - // die with a 409 Conflict (or create a duplicate or whatever happens). Probably just set "valid_until = now()" - // on the old confirmedBooking if it exists and then create a new one. - // On reconfirm: If a CBR is not provided, then keep the original CBR. Otherwise, if they are distinct, replace - // the old one with the new. - ConfirmedBooking confirmedBooking = ConfirmedBooking.builder() - // FIXME: The booking must be deeply cloned, so the confirmedBooking is not mutable via PUT /bookings/{...} - .booking(bookingRequest) - .carrier(carrier) - .carrierBookingReference(Objects.requireNonNullElseGet(shipmentRequestTO.carrierBookingReference(), this::generateCarrierBookingReference)) - .shipmentCreatedDateTime(confirmationTime) - .shipmentUpdatedDateTime(confirmationTime) - .termsAndConditions(shipmentRequestTO.termsAndConditions()) - .build(); - - confirmedBooking.assignAdvanceManifestFiling( + + if (booking.getCarrierBookingReference() != null && !booking.getCarrierBookingReference().equals(shipmentRequestTO.carrierBookingReference())) { + throw ConcreteRequestErrorMessageException.invalidInput("The booking already has a *different* carrier booking reference"); + } else if (booking.getCarrierBookingReference() == null) { + // Note: The carrier booking reference (CBR) can be assigned earlier than the time of confirmation ( + // but it is required once the booking has been confirmed). + // In the RI, we assign as a part attempting to confirm the booking (no matter if the validation succeeds). + // Other implementations can choose differently here as long as they obey the condition of CBR being + // mandatory at and after the CONFIRMED state. + booking.assignCarrierBookingReference( + Objects.requireNonNullElseGet(shipmentRequestTO.carrierBookingReference(), this::generateCarrierBookingReference) + ); + } + + ValidationResult validationResult = unofficialBookingRequestService.validateBooking(booking, false); + + + if (!validationResult.validationErrors().isEmpty()) { + return bookingMapper.toConfirmedStatusDTO(booking); + } + + assignCommoditySubreferences(booking.getBookingData(), shipmentRequestTO.commoditySubreferences()); + + var bookingData = booking.getBookingData(); + bookingData.assignAdvanceManifestFiling( Objects.requireNonNullElse( shipmentRequestTO.advanceManifestFilings(), Collections.emptyList() @@ -203,23 +198,20 @@ public ConfirmedBookingRefStatusTO create(ManageConfirmedBookingRequestTO shipme .toList() ); - if (!validationResult.validationErrors().isEmpty()) { - return confirmedBookingMapper.toStatusDTO(confirmedBooking, validationResult.proposedStatus()); - } // FIXME: This should be processed into a status DTO rather than exception style. validateTransportPlans(shipmentRequestTO, shipmentRequestTO.shipmentLocations()); - confirmedBooking.assignConfirmedEquipments( + bookingData.assignConfirmedEquipments( Objects.requireNonNullElse( - shipmentRequestTO.confirmedEquipments(), - Collections.emptyList() - ).stream() + shipmentRequestTO.confirmedEquipments(), + Collections.emptyList() + ).stream() .map(confirmedEquipmentMapper::toDAO) .toList() ); - confirmedBooking.assignShipmentCutOffTimes( + bookingData.assignShipmentCutOffTimes( Objects.requireNonNullElse( shipmentRequestTO.shipmentCutOffTimes(), Collections.emptyList() @@ -227,12 +219,13 @@ public ConfirmedBookingRefStatusTO create(ManageConfirmedBookingRequestTO shipme .map(shipmentCutOffTimeMapper::toDAO) .toList() ); - - - confirmedBooking = confirmedBookingRepository.save(confirmedBooking); - shipmentLocationService.createShipmentLocations(shipmentRequestTO.shipmentLocations(), confirmedBooking); - shipmentTransportService.createShipmentTransports(shipmentRequestTO.transports(), confirmedBooking); - return confirmedBookingMapper.toStatusDTO(confirmedBooking, bookingRequest.getBookingStatus()); + bookingData.assignTermsAndConditions(shipmentRequestTO.termsAndConditions()); + bookingData.assignCarrier(carrier); + shipmentLocationService.createShipmentLocations(shipmentRequestTO.shipmentLocations(), booking.getBookingData()); + shipmentTransportService.createShipmentTransports(shipmentRequestTO.transports(), booking.getBookingData()); + booking.confirm(); + booking = bookingRepository.save(booking); + return bookingMapper.toConfirmedStatusDTO(booking); } private Boolean validateTransportPlans(ManageConfirmedBookingRequestTO manageConfirmedBookingRequestTO, List shipmentLocationTOS) { @@ -416,8 +409,8 @@ void validateModeOfTransport(List transportToList, Map ConcreteRequestErrorMessageException.notFound("No booking with reference " + shipmentRequestTO.carrierBookingRequestReference())); } diff --git a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/unofficial/UnofficialBookingRequestService.java b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/unofficial/UnofficialBookingRequestService.java index 99d98514..01e8b265 100644 --- a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/unofficial/UnofficialBookingRequestService.java +++ b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/unofficial/UnofficialBookingRequestService.java @@ -4,16 +4,15 @@ import jakarta.validation.Validator; import java.time.OffsetDateTime; import java.util.Optional; - import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.dcsa.edocumentation.domain.persistence.entity.BookingRequest; +import org.dcsa.edocumentation.domain.persistence.entity.Booking; import org.dcsa.edocumentation.domain.persistence.entity.unofficial.ValidationResult; -import org.dcsa.edocumentation.domain.persistence.repository.BookingRequestRepository; +import org.dcsa.edocumentation.domain.persistence.repository.BookingRepository; import org.dcsa.edocumentation.infra.enums.BookingStatus; -import org.dcsa.edocumentation.service.mapping.BookingRequestMapper; -import org.dcsa.edocumentation.transferobjects.unofficial.BookingCancelRequestTO; +import org.dcsa.edocumentation.service.mapping.BookingMapper; import org.dcsa.edocumentation.transferobjects.BookingRequestRefStatusTO; +import org.dcsa.edocumentation.transferobjects.unofficial.BookingCancelRequestTO; import org.dcsa.skernel.errors.exceptions.ConcreteRequestErrorMessageException; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; @@ -23,29 +22,29 @@ @Service @RequiredArgsConstructor public class UnofficialBookingRequestService { - private final BookingRequestRepository bookingRequestRepository; - private final BookingRequestMapper bookingRequestMapper; + private final BookingRepository bookingRepository; + private final BookingMapper bookingMapper; @Qualifier("eagerValidator") private final Validator validator; @Transactional public BookingRequestRefStatusTO performBookingValidation(String carrierBookingRequestReference) { - BookingRequest bookingRequest = bookingRequestRepository.findBookingByCarrierBookingRequestReference(carrierBookingRequestReference) + Booking booking = bookingRepository.findByCarrierBookingRequestReference(carrierBookingRequestReference) .orElseThrow(() -> ConcreteRequestErrorMessageException.notFound( "No booking request found with carrierBookingRequestReference='" + carrierBookingRequestReference + "'")); - validateBooking(bookingRequest, true); + validateBooking(booking, true); - return bookingRequestMapper.toStatusDTO(bookingRequest); + return bookingMapper.toStatusDTO(booking); } @Transactional - public ValidationResult validateBooking(BookingRequest bookingRequest, boolean persistOnPENC) { - var carrierBookingRequestReference = bookingRequest.getCarrierBookingRequestReference(); + public ValidationResult validateBooking(Booking booking, boolean persistOnPENC) { + var carrierBookingRequestReference = booking.getCarrierBookingRequestReference(); ValidationResult validationResult; try { - validationResult = bookingRequest.asyncValidation(validator); + validationResult = booking.asyncValidation(validator); } catch (IllegalStateException e) { throw ConcreteRequestErrorMessageException.conflict(e.getLocalizedMessage(), e); } @@ -53,14 +52,14 @@ public ValidationResult validateBooking(BookingRequest bookingRequest, b if (validationResult.validationErrors().isEmpty()) { log.debug("Booking {} passed validation", carrierBookingRequestReference); if (persistOnPENC) { - bookingRequest.pendingUpdatesConfirmation("Booking passed validation", OffsetDateTime.now()); - bookingRequestRepository.save(bookingRequest); + booking.pendingUpdatesConfirmation(); + bookingRepository.save(booking); } } else { String reason = validationResult.presentErrors(5000); - bookingRequest.pendingUpdate(reason, OffsetDateTime.now()); + booking.pendingUpdate(reason); log.debug("Booking {} failed validation because {}", carrierBookingRequestReference, reason); - bookingRequestRepository.save(bookingRequest); + bookingRepository.save(booking); } return validationResult; } @@ -68,10 +67,10 @@ public ValidationResult validateBooking(BookingRequest bookingRequest, b @Transactional public Optional cancelBooking(String carrierBookingRequestReference, BookingCancelRequestTO bookingCancelRequestTO) { - BookingRequest bookingRequest = bookingRequestRepository.findBookingByCarrierBookingRequestReference( + Booking booking = bookingRepository.findByCarrierBookingRequestReference( carrierBookingRequestReference ).orElse(null); - if (bookingRequest == null) { + if (booking == null) { return Optional.empty(); } @@ -81,14 +80,14 @@ API Caller (typically carrier) can cancel booking by requesting to change bookin - DECLINED (in the case that booking has already been confirmed) */ if (bookingCancelRequestTO.bookingStatus().equals(BookingStatus.REJECTED)) { - bookingRequest.reject(bookingCancelRequestTO.reason()); + booking.reject(bookingCancelRequestTO.reason()); } else if (bookingCancelRequestTO.bookingStatus().equals(BookingStatus.DECLINED)) { - bookingRequest.decline(bookingCancelRequestTO.reason()); + booking.decline(bookingCancelRequestTO.reason()); } else { throw ConcreteRequestErrorMessageException.invalidInput("bookingStatus must be either REJECTED or DECLINED"); } - bookingRequest = bookingRequestRepository.save(bookingRequest); - return Optional.of(bookingRequestMapper.toStatusDTO(bookingRequest)); + booking = bookingRepository.save(booking); + return Optional.of(bookingMapper.toStatusDTO(booking)); } } diff --git a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/unofficial/UnofficialTransportDocumentService.java b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/unofficial/UnofficialTransportDocumentService.java index c549e39a..6c6723a3 100755 --- a/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/unofficial/UnofficialTransportDocumentService.java +++ b/edocumentation-service/src/main/java/org/dcsa/edocumentation/service/unofficial/UnofficialTransportDocumentService.java @@ -17,6 +17,7 @@ import org.dcsa.edocumentation.domain.validations.EBLValidation; import org.dcsa.edocumentation.domain.validations.PaperBLValidation; import org.dcsa.edocumentation.infra.enums.BookingStatus; +import org.dcsa.edocumentation.infra.enums.EblDocumentStatus; import org.dcsa.edocumentation.service.PartyService; import org.dcsa.edocumentation.service.mapping.TransportDocumentMapper; import org.dcsa.edocumentation.transferobjects.PartyIdentifyingCodeTO; @@ -27,7 +28,6 @@ import org.dcsa.edocumentation.transferobjects.unofficial.DraftTransportDocumentRequestTO; import org.dcsa.skernel.errors.exceptions.ConcreteRequestErrorMessageException; import org.springframework.stereotype.Service; -import org.dcsa.edocumentation.infra.enums.EblDocumentStatus; @Slf4j @Service @@ -66,9 +66,10 @@ public Optional issueDraft(DraftTransportDocumentR boolean shouldHaveDeclaredValue = shippingInstruction.getConsignmentItems() .stream() - .map(ConsignmentItem::getConfirmedBooking) - .map(ConfirmedBooking::getBooking) - .map(BookingRequest::getDeclaredValue) + .map(ConsignmentItem::getBooking) + .map(Booking::getLastConfirmedBookingData) + .filter(Objects::nonNull) + .map(BookingData::getDeclaredValue) .anyMatch(Objects::nonNull); if (shouldHaveDeclaredValue && transportDocumentRequestTO.declaredValue() == null) { diff --git a/edocumentation-service/src/test/java/org/dcsa/edocumentation/datafactories/BookingDataFactory.java b/edocumentation-service/src/test/java/org/dcsa/edocumentation/datafactories/BookingDataFactory.java index c047545e..55172b79 100644 --- a/edocumentation-service/src/test/java/org/dcsa/edocumentation/datafactories/BookingDataFactory.java +++ b/edocumentation-service/src/test/java/org/dcsa/edocumentation/datafactories/BookingDataFactory.java @@ -6,7 +6,8 @@ import java.util.Set; import java.util.UUID; import lombok.experimental.UtilityClass; -import org.dcsa.edocumentation.domain.persistence.entity.BookingRequest; +import org.dcsa.edocumentation.domain.persistence.entity.Booking; +import org.dcsa.edocumentation.domain.persistence.entity.BookingData; import org.dcsa.edocumentation.domain.persistence.entity.Vessel; import org.dcsa.edocumentation.domain.persistence.entity.enums.CargoMovementType; import org.dcsa.edocumentation.domain.persistence.entity.enums.CommunicationChannelCode; @@ -20,200 +21,109 @@ @UtilityClass public class BookingDataFactory { - public BookingRequest singleShallowBooking() { - return BookingRequest.builder() - .id(UUID.fromString("1bc6f4d1-c728-4504-89fe-98ab10aaf5fd")) - .carrierBookingRequestReference("BOOKING_REQ_REF_01") - .bookingStatus(BookingStatus.RECEIVED) - .receiptTypeAtOrigin(ReceiptDeliveryType.CY) - .deliveryTypeAtDestination(ReceiptDeliveryType.CY) - .cargoMovementTypeAtOrigin(CargoMovementType.FCL) - .cargoMovementTypeAtDestination(CargoMovementType.FCL) - .bookingRequestCreatedDateTime(OffsetDateTime.now()) - .serviceContractReference("serviceRef") - .paymentTermCode(PaymentTerm.COL) - .isPartialLoadAllowed(false) - .isExportDeclarationRequired(true) - .exportDeclarationReference("exportRef") - .isImportLicenseRequired(true) - .importLicenseReference("importRef") - .isAMSACIFilingRequired(true) - .isDestinationFilingRequired(true) - .contractQuotationReference("contractRef") - .incoTerms(IncoTerms.FCA.name()) - .expectedDepartureDate(LocalDate.of(2023, 10, 12)) - .expectedArrivalAtPlaceOfDeliveryStartDate(LocalDate.of(2023, 11, 9)) - .expectedArrivalAtPlaceOfDeliveryEndDate(LocalDate.of(2023, 11, 15)) - .transportDocumentTypeCode(TransportDocumentTypeCode.BOL) - .communicationChannelCode(CommunicationChannelCode.AO.name()) - .isEquipmentSubstitutionAllowed(false) - .declaredValueCurrency("EUR") - .declaredValue(10000F) - .build(); - } - - public BookingRequest singleShallowBookingWithVesselAndModeOfTransport() { - Vessel mockVessel = VesselDataFactory.vessel(); + public Booking singleShallowBooking() { - return BookingRequest.builder() - .id(UUID.fromString("1bc6f4d1-c728-4504-89fe-98ab10aaf5fd")) - .carrierBookingRequestReference("BOOKING_REQ_REF_01") - .bookingStatus(BookingStatus.RECEIVED) - .receiptTypeAtOrigin(ReceiptDeliveryType.CY) - .deliveryTypeAtDestination(ReceiptDeliveryType.CY) - .cargoMovementTypeAtOrigin(CargoMovementType.FCL) - .cargoMovementTypeAtDestination(CargoMovementType.FCL) - .bookingRequestCreatedDateTime(OffsetDateTime.now()) - .serviceContractReference("serviceRef") - .paymentTermCode(PaymentTerm.COL) - .isPartialLoadAllowed(false) - .isExportDeclarationRequired(true) - .exportDeclarationReference("exportRef") - .isImportLicenseRequired(true) - .importLicenseReference("importRef") - .isAMSACIFilingRequired(true) - .isDestinationFilingRequired(true) - .contractQuotationReference("contractRef") - .incoTerms(IncoTerms.FCA.name()) - .expectedDepartureDate(LocalDate.of(2023, 10, 12)) - .expectedArrivalAtPlaceOfDeliveryStartDate(LocalDate.of(2023, 11, 9)) - .expectedArrivalAtPlaceOfDeliveryEndDate(LocalDate.of(2023, 11, 15)) - .transportDocumentTypeCode(TransportDocumentTypeCode.BOL) - .communicationChannelCode(CommunicationChannelCode.AO.name()) - .isEquipmentSubstitutionAllowed(false) - .declaredValueCurrency("EUR") - .declaredValue(10000F) - .vessel(mockVessel) - .build(); + return Booking.builder() + .id(UUID.fromString("1bc6f4d1-c728-4504-89fe-98ab10aaf5fd")) + .carrierBookingRequestReference("BOOKING_REQ_REF_01") + .bookingStatus(BookingStatus.RECEIVED) + .bookingRequestCreatedDateTime(OffsetDateTime.now()) + .bookingData( + BookingData.builder() + .receiptTypeAtOrigin(ReceiptDeliveryType.CY) + .deliveryTypeAtDestination(ReceiptDeliveryType.CY) + .cargoMovementTypeAtOrigin(CargoMovementType.FCL) + .cargoMovementTypeAtDestination(CargoMovementType.FCL) + .serviceContractReference("serviceRef") + .paymentTermCode(PaymentTerm.COL) + .isPartialLoadAllowed(false) + .isExportDeclarationRequired(true) + .exportDeclarationReference("exportRef") + .isImportLicenseRequired(true) + .importLicenseReference("importRef") + .isAMSACIFilingRequired(true) + .isDestinationFilingRequired(true) + .contractQuotationReference("contractRef") + .incoTerms(IncoTerms.FCA.name()) + .expectedDepartureDate(LocalDate.of(2023, 10, 12)) + .expectedArrivalAtPlaceOfDeliveryStartDate(LocalDate.of(2023, 11, 9)) + .expectedArrivalAtPlaceOfDeliveryEndDate(LocalDate.of(2023, 11, 15)) + .transportDocumentTypeCode(TransportDocumentTypeCode.BOL) + .communicationChannelCode(CommunicationChannelCode.AO.name()) + .isEquipmentSubstitutionAllowed(false) + .declaredValueCurrency("EUR") + .declaredValue(10000F) + .build() + ) + .build(); } - public List multipleShallowBookingsWithVesselAndModeOfTransport() { + public Booking singleDeepBooking() { Vessel mockVessel = VesselDataFactory.vessel(); - BookingRequest bookingRequest1 = - BookingRequest.builder() - .id(UUID.fromString("1bc6f4d1-c728-4504-89fe-98ab10aaf5fd")) - .carrierBookingRequestReference("BOOKING_REQ_REF_01") - .bookingStatus(BookingStatus.RECEIVED) - .receiptTypeAtOrigin(ReceiptDeliveryType.CY) - .deliveryTypeAtDestination(ReceiptDeliveryType.CY) - .cargoMovementTypeAtOrigin(CargoMovementType.FCL) - .cargoMovementTypeAtDestination(CargoMovementType.FCL) - .bookingRequestCreatedDateTime(OffsetDateTime.now()) - .serviceContractReference("serviceRef") - .paymentTermCode(PaymentTerm.COL) - .isPartialLoadAllowed(false) - .isExportDeclarationRequired(true) - .exportDeclarationReference("exportRef") - .isImportLicenseRequired(true) - .importLicenseReference("importRef") - .isAMSACIFilingRequired(true) - .isDestinationFilingRequired(true) - .contractQuotationReference("contractRef") - .incoTerms(IncoTerms.FCA.name()) - .expectedDepartureDate(LocalDate.of(2023, 10, 12)) - .expectedArrivalAtPlaceOfDeliveryStartDate(LocalDate.of(2023, 11, 9)) - .expectedArrivalAtPlaceOfDeliveryEndDate(LocalDate.of(2023, 11, 15)) - .transportDocumentTypeCode(TransportDocumentTypeCode.BOL) - .communicationChannelCode(CommunicationChannelCode.AO.name()) - .isEquipmentSubstitutionAllowed(false) - .declaredValueCurrency("EUR") - .declaredValue(10000F) - .vessel(mockVessel) - .build(); - - BookingRequest bookingRequest2 = - BookingRequest.builder() - .id(UUID.fromString("3262f836-65d1-43e1-b759-dbeb53ac24ee")) - .carrierBookingRequestReference("BOOKING_REQ_REF_02") - .bookingStatus(BookingStatus.RECEIVED) - .receiptTypeAtOrigin(ReceiptDeliveryType.CY) - .deliveryTypeAtDestination(ReceiptDeliveryType.CY) - .cargoMovementTypeAtOrigin(CargoMovementType.FCL) - .cargoMovementTypeAtDestination(CargoMovementType.FCL) - .bookingRequestCreatedDateTime(OffsetDateTime.now()) - .serviceContractReference("serviceRef") - .paymentTermCode(PaymentTerm.COL) - .isPartialLoadAllowed(false) - .isExportDeclarationRequired(true) - .exportDeclarationReference("exportRef2") - .isImportLicenseRequired(true) - .importLicenseReference("importRef") - .isAMSACIFilingRequired(true) - .isDestinationFilingRequired(true) - .contractQuotationReference("contractRef2") - .incoTerms(IncoTerms.FCA.name()) - .expectedDepartureDate(LocalDate.of(2023, 10, 12)) - .expectedArrivalAtPlaceOfDeliveryStartDate(LocalDate.of(2023, 11, 9)) - .expectedArrivalAtPlaceOfDeliveryEndDate(LocalDate.of(2023, 11, 15)) - .transportDocumentTypeCode(TransportDocumentTypeCode.BOL) - .communicationChannelCode(CommunicationChannelCode.AO.name()) - .isEquipmentSubstitutionAllowed(false) - .declaredValueCurrency("EUR") - .declaredValue(2000F) - .vessel(mockVessel) - .build(); - - return List.of(bookingRequest1, bookingRequest2); + return Booking.builder() + .id(UUID.fromString("1bc6f4d1-c728-4504-89fe-98ab10aaf5fd")) + .carrierBookingRequestReference("BOOKING_REQ_REF_01") + .bookingStatus(BookingStatus.RECEIVED) + .bookingRequestCreatedDateTime(OffsetDateTime.now()) + .bookingData( + BookingData.builder() + .receiptTypeAtOrigin(ReceiptDeliveryType.CY) + .deliveryTypeAtDestination(ReceiptDeliveryType.CY) + .cargoMovementTypeAtOrigin(CargoMovementType.FCL) + .cargoMovementTypeAtDestination(CargoMovementType.FCL) + .serviceContractReference("serviceRef") + .paymentTermCode(PaymentTerm.COL) + .isPartialLoadAllowed(false) + .isExportDeclarationRequired(true) + .exportDeclarationReference("exportRef") + .isImportLicenseRequired(true) + .importLicenseReference("importRef") + .isAMSACIFilingRequired(true) + .isDestinationFilingRequired(true) + .contractQuotationReference("contractRef") + .incoTerms(IncoTerms.FCA.name()) + .expectedDepartureDate(LocalDate.of(2023, 10, 12)) + .expectedArrivalAtPlaceOfDeliveryStartDate(LocalDate.of(2023, 11, 9)) + .expectedArrivalAtPlaceOfDeliveryEndDate(LocalDate.of(2023, 11, 15)) + .transportDocumentTypeCode(TransportDocumentTypeCode.BOL) + .communicationChannelCode(CommunicationChannelCode.AO.name()) + .isEquipmentSubstitutionAllowed(false) + .declaredValueCurrency("EUR") + .declaredValue(10000F) + .vessel(mockVessel) + .requestedEquipments(List.of(RequestedEquipmentDataFactory.singleRequestedEquipment())) + .references(Set.of(ReferenceDataFactory.singleReference())) + .documentParties(Set.of(DocumentPartyDataFactory.singleDocumentParty())) + .shipmentLocations(Set.of(ShipmentLocationDataFactory.singleShipmentLocation())) + .build() + ) + .build(); } - public BookingRequest singleDeepBooking() { - Vessel mockVessel = VesselDataFactory.vessel(); + public Booking singleMinimalBooking() { - return BookingRequest.builder() - .id(UUID.fromString("1bc6f4d1-c728-4504-89fe-98ab10aaf5fd")) - .carrierBookingRequestReference("BOOKING_REQ_REF_01") - .bookingStatus(BookingStatus.RECEIVED) - .receiptTypeAtOrigin(ReceiptDeliveryType.CY) - .deliveryTypeAtDestination(ReceiptDeliveryType.CY) - .cargoMovementTypeAtOrigin(CargoMovementType.FCL) - .cargoMovementTypeAtDestination(CargoMovementType.FCL) - .bookingRequestCreatedDateTime(OffsetDateTime.now()) - .serviceContractReference("serviceRef") - .paymentTermCode(PaymentTerm.COL) - .isPartialLoadAllowed(false) - .isExportDeclarationRequired(true) - .exportDeclarationReference("exportRef") - .isImportLicenseRequired(true) - .importLicenseReference("importRef") - .isAMSACIFilingRequired(true) - .isDestinationFilingRequired(true) - .contractQuotationReference("contractRef") - .incoTerms(IncoTerms.FCA.name()) - .expectedDepartureDate(LocalDate.of(2023, 10, 12)) - .expectedArrivalAtPlaceOfDeliveryStartDate(LocalDate.of(2023, 11, 9)) - .expectedArrivalAtPlaceOfDeliveryEndDate(LocalDate.of(2023, 11, 15)) - .transportDocumentTypeCode(TransportDocumentTypeCode.BOL) - .communicationChannelCode(CommunicationChannelCode.AO.name()) - .isEquipmentSubstitutionAllowed(false) - .declaredValueCurrency("EUR") - .declaredValue(10000F) - .vessel(mockVessel) - .requestedEquipments(List.of(RequestedEquipmentDataFactory.singleRequestedEquipment())) - .references(Set.of(ReferenceDataFactory.singleReference())) - .documentParties(Set.of(DocumentPartyDataFactory.singleDocumentParty())) - .shipmentLocations(Set.of(ShipmentLocationDataFactory.singleShipmentLocation())) - .build(); - } - - public BookingRequest singleMinimalBooking() { - return BookingRequest.builder() - .id(UUID.fromString("1bc6f4d1-c728-4504-89fe-98ab10aaf5fd")) - .carrierBookingRequestReference("BOOKING_REQ_REF_01") - .bookingStatus(BookingStatus.RECEIVED) - .receiptTypeAtOrigin(ReceiptDeliveryType.CY) - .deliveryTypeAtDestination(ReceiptDeliveryType.CY) - .cargoMovementTypeAtOrigin(CargoMovementType.FCL) - .cargoMovementTypeAtDestination(CargoMovementType.FCL) - .bookingRequestCreatedDateTime(OffsetDateTime.now()) - .serviceContractReference("serviceRef") - .isPartialLoadAllowed(false) - .isExportDeclarationRequired(false) - .isImportLicenseRequired(false) - .communicationChannelCode(CommunicationChannelCode.AO.name()) - .isEquipmentSubstitutionAllowed(false) - .requestedEquipments(List.of(RequestedEquipmentDataFactory.singleRequestedEquipment())) - .build(); + return Booking.builder() + .id(UUID.fromString("1bc6f4d1-c728-4504-89fe-98ab10aaf5fd")) + .carrierBookingRequestReference("BOOKING_REQ_REF_01") + .bookingStatus(BookingStatus.RECEIVED) + .bookingRequestCreatedDateTime(OffsetDateTime.now()) + .bookingData( + BookingData.builder() + .receiptTypeAtOrigin(ReceiptDeliveryType.CY) + .deliveryTypeAtDestination(ReceiptDeliveryType.CY) + .cargoMovementTypeAtOrigin(CargoMovementType.FCL) + .cargoMovementTypeAtDestination(CargoMovementType.FCL) + .serviceContractReference("serviceRef") + .isPartialLoadAllowed(false) + .isExportDeclarationRequired(false) + .isImportLicenseRequired(false) + .communicationChannelCode(CommunicationChannelCode.AO.name()) + .isEquipmentSubstitutionAllowed(false) + .requestedEquipments(List.of(RequestedEquipmentDataFactory.singleRequestedEquipment())) + .build() + ) + .build(); } public BookingRequestTO singleFullBookingRequestTO() { diff --git a/edocumentation-service/src/test/java/org/dcsa/edocumentation/datafactories/ConfirmedBookingDataFactory.java b/edocumentation-service/src/test/java/org/dcsa/edocumentation/datafactories/ConfirmedBookingDataFactory.java deleted file mode 100644 index 0558db9a..00000000 --- a/edocumentation-service/src/test/java/org/dcsa/edocumentation/datafactories/ConfirmedBookingDataFactory.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.dcsa.edocumentation.datafactories; - -import lombok.experimental.UtilityClass; -import org.dcsa.edocumentation.domain.persistence.entity.BookingRequest; -import org.dcsa.edocumentation.domain.persistence.entity.ConfirmedBooking; - -import java.time.OffsetDateTime; -import java.util.List; -import java.util.UUID; - -@UtilityClass -public class ConfirmedBookingDataFactory { - - public ConfirmedBooking singleConfirmedBookingWithoutBooking() { - return ConfirmedBooking.builder() - .id(UUID.fromString("1bc6f4d1-c728-4504-89fe-98ab10aaf5f2")) - .carrierBookingReference("carrierBookingReference") - .shipmentCreatedDateTime(OffsetDateTime.now()) - .shipmentUpdatedDateTime(OffsetDateTime.now()) - .termsAndConditions("TERMS AND CONDITIONS") - .build(); - } - - public ConfirmedBooking singleConfirmedBookingWithBooking() { - BookingRequest bookingRequest = BookingDataFactory.singleShallowBooking(); - return ConfirmedBooking.builder() - .id(UUID.fromString("1bc6f4d1-c728-4504-89fe-98ab10aaf5f2")) - .carrierBookingReference("carrierBookingReference") - .booking(bookingRequest) - .shipmentCreatedDateTime(OffsetDateTime.now()) - .shipmentUpdatedDateTime(OffsetDateTime.now()) - .termsAndConditions("TERMS AND CONDITIONS") - .build(); - } - - public List multipleConfirmedBookingsWithBooking() { - List bookingRequest = - BookingDataFactory.multipleShallowBookingsWithVesselAndModeOfTransport(); - ConfirmedBooking confirmedBooking1 = - ConfirmedBooking.builder() - .id(UUID.fromString("1bc6f4d1-c728-4504-89fe-98ab10aaf5f2")) - .carrierBookingReference("carrierBookingReference") - .booking(bookingRequest.get(0)) - .shipmentCreatedDateTime(OffsetDateTime.now()) - .shipmentUpdatedDateTime(OffsetDateTime.now()) - .termsAndConditions("TERMS AND CONDITIONS") - .build(); - - ConfirmedBooking confirmedBooking2 = - ConfirmedBooking.builder() - .id(UUID.fromString("1bc6f4d1-c728-4504-89fe-98ab10aaf5f2")) - .carrierBookingReference("carrierBookingReference") - .booking(bookingRequest.get(1)) - .shipmentCreatedDateTime(OffsetDateTime.now()) - .shipmentUpdatedDateTime(OffsetDateTime.now()) - .termsAndConditions("TERMS AND CONDITIONS") - .build(); - - return List.of(confirmedBooking1, confirmedBooking2); - } -} diff --git a/edocumentation-service/src/test/java/org/dcsa/edocumentation/datafactories/ShipmentLocationDataFactory.java b/edocumentation-service/src/test/java/org/dcsa/edocumentation/datafactories/ShipmentLocationDataFactory.java index ec6fa095..3fc2486c 100644 --- a/edocumentation-service/src/test/java/org/dcsa/edocumentation/datafactories/ShipmentLocationDataFactory.java +++ b/edocumentation-service/src/test/java/org/dcsa/edocumentation/datafactories/ShipmentLocationDataFactory.java @@ -1,16 +1,14 @@ package org.dcsa.edocumentation.datafactories; +import java.time.OffsetDateTime; +import java.util.UUID; import lombok.experimental.UtilityClass; -import org.dcsa.edocumentation.domain.persistence.entity.BookingRequest; import org.dcsa.edocumentation.domain.persistence.entity.Location; import org.dcsa.edocumentation.domain.persistence.entity.ShipmentLocation; import org.dcsa.edocumentation.domain.persistence.entity.enums.LocationType; import org.dcsa.edocumentation.transferobjects.ShipmentLocationTO; import org.dcsa.edocumentation.transferobjects.enums.ShipmentLocationTypeCode; -import java.time.OffsetDateTime; -import java.util.UUID; - @UtilityClass public class ShipmentLocationDataFactory { @@ -34,13 +32,4 @@ public ShipmentLocationTO shipmentLocationTO(OffsetDateTime now) { .eventDateTime(now) .build(); } - - public ShipmentLocation shipmentLocation(BookingRequest bookingRequest, OffsetDateTime now) { - return ShipmentLocation.builder() - .bookingRequest(bookingRequest) - .location(LocationDataFactory.addressLocationWithId()) - .shipmentLocationTypeCode(LocationType.OIR.name()) - .eventDateTime(now) - .build(); - } } diff --git a/edocumentation-service/src/test/java/org/dcsa/edocumentation/datafactories/ShippingInstructionDataFactory.java b/edocumentation-service/src/test/java/org/dcsa/edocumentation/datafactories/ShippingInstructionDataFactory.java index 79994bf9..b9fae199 100644 --- a/edocumentation-service/src/test/java/org/dcsa/edocumentation/datafactories/ShippingInstructionDataFactory.java +++ b/edocumentation-service/src/test/java/org/dcsa/edocumentation/datafactories/ShippingInstructionDataFactory.java @@ -55,40 +55,41 @@ public ShippingInstruction singleShallowShippingInstructionWithPlaceOfIssueAndSh .build()) .build(); - ConfirmedBooking shipments = - ConfirmedBooking.builder() - .carrierBookingReference(UUID.randomUUID().toString()) - .shipmentCreatedDateTime(OffsetDateTime.now()) - .shipmentCreatedDateTime(OffsetDateTime.now()) - .termsAndConditions("dummy terms and conditions") - .booking(BookingDataFactory.singleShallowBooking()) - .shipmentLocations( - Set.of( - ShipmentLocation.builder() - .location(Location.builder().UNLocationCode("DKCPH").build()) - .shipmentLocationTypeCode(LocationType.POL.name()) - .build(), - ShipmentLocation.builder() - .location(Location.builder().UNLocationCode("DEHAM").build()) - .shipmentLocationTypeCode(LocationType.POD.name()) - .build() - )) - .shipmentTransports(Set.of( - ShipmentTransport.builder() - .plannedArrivalDate(LocalDate.of(2020, 1, 1)) - .plannedDepartureDate(LocalDate.of(2020, 1, 8)) - .loadLocation(Location.builder().UNLocationCode("NLRTM").build()) - .dischargeLocation(Location.builder().UNLocationCode("USMIA").build()) - .modeOfTransport(DCSATransportType.VESSEL.name()) - .vesselName("Emma Maersk") - .vesselIMONumber("9321483") - .build() - )) - .carrier(Carrier.builder().carrierName("dummy carrier").build()) - .build(); + Booking origBooking = BookingDataFactory.singleShallowBooking(); + var bookingData = origBooking.getBookingData().toBuilder() + .termsAndConditions("dummy terms and conditions") + .shipmentLocations( + Set.of( + ShipmentLocation.builder() + .location(Location.builder().UNLocationCode("DKCPH").build()) + .shipmentLocationTypeCode(LocationType.POL.name()) + .build(), + ShipmentLocation.builder() + .location(Location.builder().UNLocationCode("DEHAM").build()) + .shipmentLocationTypeCode(LocationType.POD.name()) + .build() + )) + .shipmentTransports(Set.of( + ShipmentTransport.builder() + .plannedArrivalDate(LocalDate.of(2020, 1, 1)) + .plannedDepartureDate(LocalDate.of(2020, 1, 8)) + .loadLocation(Location.builder().UNLocationCode("NLRTM").build()) + .dischargeLocation(Location.builder().UNLocationCode("USMIA").build()) + .modeOfTransport(DCSATransportType.VESSEL.name()) + .vesselName("Emma Maersk") + .vesselIMONumber("9321483") + .build() + )) + .carrier(Carrier.builder().carrierName("dummy carrier").build()) + .build(); + var booking = origBooking.toBuilder() + .bookingStatus("CONFIRMED") + .bookingData(bookingData) + .lastConfirmedBookingData(bookingData) + .build(); var consignmentItems = List.of(ConsignmentItem.builder() - .confirmedBooking(shipments) + .booking(booking) .build()); return ShippingInstruction.builder() @@ -124,62 +125,4 @@ public ShippingInstruction singleShallowShippingInstructionWithPlaceOfIssueAndSh .build(); } - public List multipleShallowShippingInstructionWithPlaceOfIssueAndShipments() { - Location placeOfIssue = Location.builder() - .id(UUID.randomUUID()) - .address(Address.builder() - .name("dummy address") - .city("dummy street") - .postCode("dummy postcode") - .country("dummy country") - .build()) - .build(); - - ConfirmedBooking confirmedBooking = ConfirmedBooking.builder() - .carrierBookingReference(UUID.randomUUID().toString()) - .shipmentCreatedDateTime(OffsetDateTime.now()) - .shipmentCreatedDateTime(OffsetDateTime.now()) - .termsAndConditions("dummy terms and conditions") - .booking(BookingDataFactory.singleShallowBooking()) - .carrier(Carrier.builder() - .carrierName("dummy carrier") - .build()) - .build(); - - var consignmentItems = List.of( - ConsignmentItem.builder() - .confirmedBooking(confirmedBooking) - .build() - ); - - return List.of(ShippingInstruction.builder() - .id(UUID.randomUUID()) - .shippingInstructionReference(UUID.randomUUID().toString()) - .documentStatus(EblDocumentStatus.RECEIVED) - .shippingInstructionCreatedDateTime(OffsetDateTime.now()) - .shippingInstructionUpdatedDateTime(OffsetDateTime.now()) - .isShippedOnBoardType(true) - .isElectronic(true) - .isToOrder(false) - .placeOfIssue(placeOfIssue) - .transportDocumentTypeCode(TransportDocumentTypeCode.BOL) - .displayedNameForPlaceOfReceipt( - DisplayedAddress.builder() - .addressLine1("Amsterdam") - .build()) - .displayedNameForPlaceOfDelivery( - DisplayedAddress.builder() - .addressLine1("Singapore") - .build()) - .displayedNameForPortOfLoad( - DisplayedAddress.builder() - .addressLine1("Port of Rotterdam") - .build()) - .displayedNameForPortOfDischarge( - DisplayedAddress.builder() - .addressLine1("Port of Singapore") - .build()) - .consignmentItems(consignmentItems) - .build(), singleShallowShippingInstructionWithPlaceOfIssueAndShipments()); - } } diff --git a/edocumentation-service/src/test/java/org/dcsa/edocumentation/service/BookingRequestServiceTest.java b/edocumentation-service/src/test/java/org/dcsa/edocumentation/service/BookingRequestServiceTest.java index 21991912..f52fa573 100644 --- a/edocumentation-service/src/test/java/org/dcsa/edocumentation/service/BookingRequestServiceTest.java +++ b/edocumentation-service/src/test/java/org/dcsa/edocumentation/service/BookingRequestServiceTest.java @@ -16,10 +16,8 @@ import org.dcsa.edocumentation.datafactories.LocationDataFactory; import org.dcsa.edocumentation.datafactories.VesselDataFactory; import org.dcsa.edocumentation.datafactories.VoyageDataFactory; -import org.dcsa.edocumentation.domain.persistence.entity.BookingRequest; -import org.dcsa.edocumentation.domain.persistence.entity.Vessel; -import org.dcsa.edocumentation.domain.persistence.entity.Voyage; -import org.dcsa.edocumentation.domain.persistence.repository.BookingRequestRepository; +import org.dcsa.edocumentation.domain.persistence.entity.*; +import org.dcsa.edocumentation.domain.persistence.repository.BookingRepository; import org.dcsa.edocumentation.infra.enums.BookingStatus; import org.dcsa.edocumentation.service.mapping.*; import org.dcsa.edocumentation.transferobjects.BookingRequestRefStatusTO; @@ -40,9 +38,9 @@ class BookingRequestServiceTest { @Nested class GetBookingRequest { - @Mock private BookingRequestRepository repository; + @Mock private BookingRepository repository; - @Spy private BookingRequestMapper bookingRequestMapper = Mappers.getMapper(BookingRequestMapper.class); + @Spy private BookingMapper bookingMapper = Mappers.getMapper(BookingMapper.class); @Spy private AddressMapper addressMapper = Mappers.getMapper(AddressMapper.class); @Spy private LocationMapper locationMapper = Mappers.getMapper(LocationMapper.class); @@ -58,21 +56,22 @@ class GetBookingRequest { @BeforeEach void setupMappers() { DisplayedAddressMapper displayedAddressMapper = new DisplayedAddressMapper(); - ReflectionTestUtils.setField(bookingRequestMapper, "locationMapper", locationMapper); - ReflectionTestUtils.setField(bookingRequestMapper, "documentPartyMapper", documentPartyMapper); - ReflectionTestUtils.setField(bookingRequestMapper, "shipmentLocationMapper", shipmentLocationMapper); - ReflectionTestUtils.setField(bookingRequestMapper, "requestedEquipmentGroupMapper", requestedEquipmentGroupMapper); + ReflectionTestUtils.setField(bookingMapper, "locationMapper", locationMapper); + ReflectionTestUtils.setField(bookingMapper, "documentPartyMapper", documentPartyMapper); + ReflectionTestUtils.setField(bookingMapper, "shipmentLocationMapper", shipmentLocationMapper); + ReflectionTestUtils.setField(bookingMapper, "requestedEquipmentGroupMapper", requestedEquipmentGroupMapper); ReflectionTestUtils.setField(requestedEquipmentGroupMapper, "activeReeferSettingsMapper", activeReeferSettingsMapper); ReflectionTestUtils.setField(documentPartyMapper, "displayedAddressMapper", displayedAddressMapper); ReflectionTestUtils.setField(documentPartyMapper, "partyMapper", partyMapper); ReflectionTestUtils.setField(partyMapper, "addressMapper", addressMapper); ReflectionTestUtils.setField(locationMapper, "addressMapper", addressMapper); ReflectionTestUtils.setField(shipmentLocationMapper, "locationMapper", locationMapper); + } @Test void bookingServiceTest_testGetFullBooking() { - when(repository.findBookingByCarrierBookingRequestReference(any())) + when(repository.findByCarrierBookingRequestReference(any())) .thenReturn(Optional.of(BookingDataFactory.singleDeepBooking())); Optional result = service.getBookingRequest("test"); @@ -87,7 +86,7 @@ void bookingServiceTest_testGetFullBooking() { @Test void bookingServiceTest_testGetMinimalBooking() { - when(repository.findBookingByCarrierBookingRequestReference(any())) + when(repository.findByCarrierBookingRequestReference(any())) .thenReturn(Optional.of(BookingDataFactory.singleMinimalBooking())); Optional result = service.getBookingRequest("test"); @@ -100,7 +99,7 @@ void bookingServiceTest_testGetMinimalBooking() { @Test void bookingServiceTest_testNoBookingFound() { - when(repository.findBookingByCarrierBookingRequestReference(any())).thenReturn(Optional.empty()); + when(repository.findByCarrierBookingRequestReference(any())).thenReturn(Optional.empty()); Optional result = service.getBookingRequest("test"); assertFalse(result.isPresent()); @@ -108,7 +107,7 @@ void bookingServiceTest_testNoBookingFound() { @Test void bookingServiceTest_testNullCarrierBookingRequestReference() { - when(repository.findBookingByCarrierBookingRequestReference(null)).thenReturn(Optional.empty()); + when(repository.findByCarrierBookingRequestReference(null)).thenReturn(Optional.empty()); Optional result = service.getBookingRequest(null); assertFalse(result.isPresent()); @@ -123,11 +122,12 @@ class CreateBookingRequest { @Mock private DocumentPartyService documentPartyService; @Mock private ShipmentLocationService shipmentLocationService; - @Mock private BookingRequestRepository bookingRequestRepository; + @Mock private BookingRepository bookingRepository; @Spy private AddressMapper addressMapper = Mappers.getMapper(AddressMapper.class); @Spy private LocationMapper locationMapper = Mappers.getMapper(LocationMapper.class); - @Spy private BookingRequestMapper bookingRequestMapper = Mappers.getMapper(BookingRequestMapper.class); + @Spy private BookingMapper bookingMapper = Mappers.getMapper(BookingMapper.class); + @Spy private BookingDataMapper bookingDataMapper = Mappers.getMapper(BookingDataMapper.class); @Spy private ReferenceMapper referenceMapper = Mappers.getMapper(ReferenceMapper.class); @Spy private RequestedEquipmentGroupMapper requestedEquipmentGroupMapper = Mappers.getMapper(RequestedEquipmentGroupMapper.class); @Spy private CommodityMapper commodityMapper = Mappers.getMapper(CommodityMapper.class); @@ -140,14 +140,15 @@ class CreateBookingRequest { @BeforeEach public void resetMocks() { ReflectionTestUtils.setField(locationMapper, "addressMapper", addressMapper); - ReflectionTestUtils.setField(bookingRequestMapper, "locationMapper", locationMapper); - ReflectionTestUtils.setField(bookingRequestMapper, "referenceMapper", referenceMapper); - ReflectionTestUtils.setField(bookingRequestMapper, "requestedEquipmentGroupMapper", requestedEquipmentGroupMapper); + ReflectionTestUtils.setField(bookingDataMapper, "locationMapper", locationMapper); + ReflectionTestUtils.setField(bookingDataMapper, "referenceMapper", referenceMapper); +// ReflectionTestUtils.setField(bookingDataMapper, "requestedEquipmentGroupMapper", requestedEquipmentGroupMapper); ReflectionTestUtils.setField(requestedEquipmentGroupMapper, "activeReeferSettingsMapper", activeReeferSettingsMapper); ReflectionTestUtils.setField(requestedEquipmentGroupMapper, "commodityMapper", commodityMapper); ReflectionTestUtils.setField(commodityMapper, "outerPackagingMapper", outerPackagingMapper); + reset(voyageService, vesselService,referenceService, documentPartyService, shipmentLocationService, - bookingRequestRepository); + bookingRepository); } @Test @@ -158,46 +159,39 @@ void testCreateFullBooking() { OffsetDateTime now = OffsetDateTime.now(); BookingRequestTO bookingRequest = BookingDataFactory.singleFullBookingRequestTO(); - BookingRequest bookingRequestToSave = bookingRequestMapper.toDAO(bookingRequest, voyage, vessel).toBuilder() + BookingData bookingDataToSave = bookingDataMapper.toDAO(bookingRequest, voyage, vessel).toBuilder() .placeOfIssue(location) .invoicePayableAt(location) .build(); - BookingRequest bookingRequestSaved = bookingRequestToSave.toBuilder() + Booking bookingRequestSaved = Booking.builder() .carrierBookingRequestReference("carrierBookingRequestRef") .bookingRequestCreatedDateTime(now) .bookingRequestUpdatedDateTime(now) .bookingStatus(BookingStatus.RECEIVED) + .bookingData(bookingDataToSave) .build(); when(voyageService.resolveVoyage(any())).thenReturn(voyage); when(vesselService.resolveVessel(any())).thenReturn(vessel); - when(bookingRequestRepository.save(any())).thenReturn(bookingRequestSaved); + when(bookingRepository.save(any())).thenReturn(bookingRequestSaved); // Execute BookingRequestRefStatusTO result = bookingRequestService.createBookingRequest(bookingRequest); // Verify assertEquals("carrierBookingRequestRef", result.carrierBookingRequestReference()); - assertEquals(now, result.bookingRequestCreatedDateTime()); - assertEquals(now, result.bookingRequestUpdatedDateTime()); assertEquals(BookingStatus.RECEIVED, result.bookingStatus()); - ArgumentCaptor bookingArgumentCaptor = ArgumentCaptor.forClass(BookingRequest.class); + ArgumentCaptor bookingArgumentCaptor = ArgumentCaptor.forClass(Booking.class); verify(voyageService).resolveVoyage(bookingRequest); verify(vesselService).resolveVessel(bookingRequest); - verify(bookingRequestRepository).save(bookingArgumentCaptor.capture()); - verify(referenceService).createReferences(eq(bookingRequest.references()), any(BookingRequest.class)); - verify(documentPartyService).createDocumentParties(eq(bookingRequest.documentParties()), any(BookingRequest.class)); - verify(shipmentLocationService).createShipmentLocations(eq(bookingRequest.shipmentLocations()), any(BookingRequest.class)); - - BookingRequest bookingRequestActuallySaved = bookingArgumentCaptor.getValue(); - assertEquals(bookingRequestToSave, bookingRequestActuallySaved.toBuilder() - .id(null) - .carrierBookingRequestReference(null) - .bookingRequestCreatedDateTime(null) - .bookingRequestUpdatedDateTime(null) - .bookingStatus(null) - .build()); + verify(bookingRepository).save(bookingArgumentCaptor.capture()); + verify(referenceService).createReferences(eq(bookingRequest.references()), any(BookingData.class)); + verify(documentPartyService).createDocumentParties(eq(bookingRequest.documentParties()), any(BookingData.class)); + verify(shipmentLocationService).createShipmentLocations(eq(bookingRequest.shipmentLocations()), any(BookingData.class)); + + Booking bookingRequestActuallySaved = bookingArgumentCaptor.getValue(); + assertEquals(bookingDataToSave, bookingRequestActuallySaved.getBookingData()); assertNotNull(bookingRequestActuallySaved.getCarrierBookingRequestReference()); assertNotNull(bookingRequestActuallySaved.getBookingRequestCreatedDateTime()); assertNotNull(bookingRequestActuallySaved.getBookingRequestUpdatedDateTime()); diff --git a/edocumentation-service/src/test/java/org/dcsa/edocumentation/service/DocumentPartyServiceTest.java b/edocumentation-service/src/test/java/org/dcsa/edocumentation/service/DocumentPartyServiceTest.java index 7b9c7eef..9494254d 100644 --- a/edocumentation-service/src/test/java/org/dcsa/edocumentation/service/DocumentPartyServiceTest.java +++ b/edocumentation-service/src/test/java/org/dcsa/edocumentation/service/DocumentPartyServiceTest.java @@ -8,10 +8,7 @@ import org.dcsa.edocumentation.datafactories.BookingDataFactory; import org.dcsa.edocumentation.datafactories.DocumentPartyDataFactory; import org.dcsa.edocumentation.datafactories.ShippingInstructionDataFactory; -import org.dcsa.edocumentation.domain.persistence.entity.BookingRequest; -import org.dcsa.edocumentation.domain.persistence.entity.DocumentParty; -import org.dcsa.edocumentation.domain.persistence.entity.Party; -import org.dcsa.edocumentation.domain.persistence.entity.ShippingInstruction; +import org.dcsa.edocumentation.domain.persistence.entity.*; import org.dcsa.edocumentation.domain.persistence.repository.*; import org.dcsa.edocumentation.service.mapping.AddressMapper; import org.dcsa.edocumentation.service.mapping.DisplayedAddressMapper; @@ -69,7 +66,7 @@ public void resetMocks() { @Test void documentPartyServiceTest_testCreateNullWithBooking() { - documentPartyService.createDocumentParties(null, (BookingRequest) null); + documentPartyService.createDocumentParties(null, (BookingData) null); verify(documentPartyRepository, never()).save(any()); verify(documentPartyMapper, never()).toDAO(any(DocumentPartyTO.class), any()); @@ -97,7 +94,7 @@ void documentPartyServiceTest_testCreateNullWithShippingInstruction() { @Test void documentPartyServiceTest_testCreateEmptyWithBooking() { - documentPartyService.createDocumentParties(Collections.emptyList(), (BookingRequest) null); + documentPartyService.createDocumentParties(Collections.emptyList(), (BookingData) null); verify(documentPartyRepository, never()).save(any()); verify(documentPartyMapper, never()).toDAO(any(DocumentPartyTO.class), any()); @@ -126,7 +123,7 @@ void documentPartyServiceTest_testCreateEmptyWithShippingInstruction() { @Test void documentPartyServiceTest_createFullDocumentPartyWithBooking() { // Setup - BookingRequest bookingRequest = BookingDataFactory.singleMinimalBooking(); + var booking = BookingDataFactory.singleMinimalBooking(); DocumentPartyTO documentPartyTO = DocumentPartyDataFactory.fullDocumentPartyTO(); Party party = DocumentPartyDataFactory.partialParty(); DocumentParty documentParty = DocumentPartyDataFactory.partialDocumentParty(party); @@ -135,7 +132,7 @@ void documentPartyServiceTest_createFullDocumentPartyWithBooking() { when(documentPartyRepository.save(any())).thenReturn(documentParty); // Execute - documentPartyService.createDocumentParties(List.of(documentPartyTO), bookingRequest); + documentPartyService.createDocumentParties(List.of(documentPartyTO), booking.getBookingData()); // Verify verify(partyService).createParty(documentPartyTO.party()); diff --git a/edocumentation-service/src/test/java/org/dcsa/edocumentation/service/ReferenceServiceTest.java b/edocumentation-service/src/test/java/org/dcsa/edocumentation/service/ReferenceServiceTest.java index 11e23f97..ae6bf6d4 100644 --- a/edocumentation-service/src/test/java/org/dcsa/edocumentation/service/ReferenceServiceTest.java +++ b/edocumentation-service/src/test/java/org/dcsa/edocumentation/service/ReferenceServiceTest.java @@ -1,9 +1,14 @@ package org.dcsa.edocumentation.service; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +import java.util.Collections; +import java.util.List; import org.dcsa.edocumentation.datafactories.BookingDataFactory; import org.dcsa.edocumentation.datafactories.ReferenceDataFactory; import org.dcsa.edocumentation.datafactories.ShippingInstructionDataFactory; -import org.dcsa.edocumentation.domain.persistence.entity.BookingRequest; +import org.dcsa.edocumentation.domain.persistence.entity.BookingData; import org.dcsa.edocumentation.domain.persistence.entity.Reference; import org.dcsa.edocumentation.domain.persistence.entity.ShippingInstruction; import org.dcsa.edocumentation.domain.persistence.repository.ReferenceRepository; @@ -18,12 +23,6 @@ import org.mockito.Spy; import org.mockito.junit.jupiter.MockitoExtension; -import java.util.Collections; -import java.util.List; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; - @ExtendWith(MockitoExtension.class) class ReferenceServiceTest { @Mock private ReferenceRepository referenceRepository; @@ -38,10 +37,10 @@ public void resetMocks() { @Test void referenceServiceTest_testCreateWithNullBooking() { - referenceService.createReferences(null, (BookingRequest) null); + referenceService.createReferences(null, (BookingData) null); verify(referenceRepository, never()).saveAll(any()); - verify(referenceMapper, never()).toDAO(any(), any(BookingRequest.class)); + verify(referenceMapper, never()).toDAO(any(), any(BookingData.class)); } @Test @@ -54,10 +53,10 @@ void referenceServiceTest_testCreateWithNullShippingInstruction() { @Test void referenceServiceTest_testCreateWithEmptyBooking() { - referenceService.createReferences(Collections.emptyList(), (BookingRequest) null); + referenceService.createReferences(Collections.emptyList(), (BookingData) null); verify(referenceRepository, never()).saveAll(any()); - verify(referenceMapper, never()).toDAO(any(), any(BookingRequest.class)); + verify(referenceMapper, never()).toDAO(any(), any(BookingData.class)); } @Test @@ -71,15 +70,15 @@ void referenceServiceTest_testCreateWithEmptyShippingInstruction() { @Test void referenceServiceTest_testCreateWithBooking() { // Setup - BookingRequest bookingRequest = BookingDataFactory.singleMinimalBooking(); + var booking = BookingDataFactory.singleMinimalBooking(); ReferenceTO referenceTO = ReferenceDataFactory.singleReferenceTO(); Reference reference = ReferenceDataFactory.singleReferenceWithoutId(); // Execute - referenceService.createReferences(List.of(referenceTO), bookingRequest); + referenceService.createReferences(List.of(referenceTO), booking.getBookingData()); // Verify - verify(referenceMapper).toDAO(referenceTO, bookingRequest); + verify(referenceMapper).toDAO(referenceTO, booking.getBookingData()); verify(referenceRepository).saveAll(List.of(reference)); }