@CompileStatic class BookingOfferCargos extends Object
Handles cargos at the BookingOfferAggregate level, by encapsulating some invariant checks and keeping the internal bookingOfferCargoCollection
consolidated.
BookingOfferCargoEquality
. Internal bookingOfferCargoCollection
is consolidated when it contains only a single
Cargo
instance for corresponding BookingOfferCargoEquality
. When adding or removing Cargo
instances, internal bookingOfferCargoCollection
has to be kept
consolidated.
For example, if we add multiple cargos with the same commodity type, container type, and requested storage temperature (those properties together define booking offer cargo equality),
BookingOfferCargos
will summarize all their weights inside a new booking offer cargo instance (this is a consolidated cargo instance) with the same commodity type, container type, and
requested storage temperature. In the process, consolidated cargo will also contain correctly updated maxRecommendedWeightPerContainerKg
, containerCount
, and
containerTeuCount
properties.
The new consolidated cargo instance will take maxAllowedWeightPerContainer
of equivalent cargo instances that are just added (or removed) to the BookingOfferCargos
. This means that
old maxAllowedWeightPerContainer
is dropped and forgotten.
Why are we using cargo consolidation at all? In the context of a booking offer, we are not interested in multiple submissions of the equivalent cargos that are different only in their weight.
Instead, we are consolidating all such requests with a single record of equivalent cargo with correctly summed up container weight and other derived properties like
maxRecommendedWeightPerContainerKg
, containerCount
, and containerTeuCount
.
Type | Name and description |
---|---|
Collection<Cargo> |
bookingOfferCargoCollection |
Constructor and description |
---|
BookingOfferCargos() |
Type Params | Return Type | Name and description |
---|---|---|
|
static Tuple2<Quantity<Mass>, BigDecimal> |
calculateTotalsForCargoCollectionAddition(Collection<Cargo> existingConsolidatedCargoCollection, Collection<Cargo> cargoCollectionToAdd) Calculates commodity weight and container TEU count totals of the existing consolidated cargo collection if additional cargo collection is added to it. |
|
static boolean |
canAcceptCargoCollectionAddition(Collection<Cargo> existingConsolidatedCargoCollection, Collection<Cargo> cargoCollectionToAdd, MaxAllowedTeuCountPolicy maxAllowedTeuCountPolicy) Checks if we can accept addition of a Cargo collection at the existing cargo collection in compliance with the current MaxAllowedTeuCountPolicy. |
|
static void |
checkIfCargoCollectionIsConsolidated(Collection<Cargo> existingConsolidatedCargoCollection) |
|
static Collection<Cargo> |
consolidateCargoCollectionsForCargoAddition(Collection<Cargo> existingConsolidatedCargos, Collection<Cargo> cargosToAdd) |
|
Cargo |
findCargoByEquality(BookingOfferCargoEquality cargoEquality) |
|
Cargo |
findCargoByExample(Cargo cargoExample) |
|
Quantity<Mass> |
getTotalCommodityWeight() |
|
BigDecimal |
getTotalContainerTeuCount() |
|
void |
storeCargoCollectionAddition(Collection<Cargo> cargoCollectionToAdd) Stores the cargo collection addition in the internal map by replacing any previously stored equivalent cargos. |
Calculates commodity weight and container TEU count totals of the existing consolidated cargo collection if additional cargo collection is added to it.
The method returns a tuple of 2 where value v1 is the newtotalCommodityWeight
and value v2 is the new totalContainerTeuCount
.
Before executing this method from the command handler, one should check if cargo can be accepted at all according to the current MaxAllowedTeuCountPolicy. One can use
canAcceptCargoCollectionAddition(Collection, Collection, MaxAllowedTeuCountPolicy) for that purpose.
Checks if we can accept addition of a Cargo collection at the existing cargo collection in compliance with the current MaxAllowedTeuCountPolicy.
Consider an example. The largest ship in the world can carry 24000 TEU of containers. Based on that fact, we can limit the total container TEU count per a single booking to the max of 5000 TEUs. Of course, the number of 5000 TEUs is entirely arbitrary and is used only as an example. We could enrich behavior with two different policies here. For example, one limiting container TEU count per commodity type and another limiting container TEU count for the whole booking. In a simpler case, both policies can be the same. We can allocate full booking capacity with a single commodity type in that case. Intended to be used to verify potential cargo addition at the level of the BookingOfferAggregate instance. We should use this method from the aggregate's command handlers to check if it is valid to add the cargo collection to the aggregate state. Actual state change happens later in the event sourcing handler. Note that we cannot make this check in the event sourcing handler because it must make changes unconditionally to support rehydration from past events.Stores the cargo collection addition in the internal map by replacing any previously stored equivalent cargos.
We should use this method only from the event sourcing handler as it changes the aggregate state and does it unconditionally without checking any invariants. This is necessary to support correct rehydration of the aggregate from previous events. We should do all invariant checking in the aggregate's command handler.Groovy Documentation