/// <summary> /// Checks whether provided itinerary (a description of transporting steps) satisfies this /// specification. /// </summary> /// <param name="itinerary">An itinerary.</param> /// <returns>True, if cargo can be transported from <see cref="Origin"/> to <see cref="Destination"/> /// before <see cref="ArrivalDeadline"/> using provided itinerary. /// </returns> public virtual bool IsSatisfiedBy(Itinerary itinerary) { return itinerary != null && _origin == itinerary.InitialDepartureLocation && _destination == itinerary.FinalArrivalLocation && _arrivalDeadline > itinerary.FinalArrivalDate; }
public ItineraryTests() { _voyage = new VoyageBuilder(new VoyageNumber("0123"), _shanghai) .AddMovement(_rotterdam, DateTime.Now, DateTime.Now) .AddMovement(_gothenburg, DateTime.Now, DateTime.Now) .Build(); _wrongVoyage = new VoyageBuilder(new VoyageNumber("666"), _newyork) .AddMovement(new BookingApi.Domain.Location.Location(UnLocodeHelpers.GetNewUnLocode(), "STOCKHOLM"), DateTime.Now, DateTime.Now) .AddMovement(_helsinki, DateTime.Now, DateTime.Now) .Build(); _trackingId = new TrackingId("CARGO1"); _routeSpecification = new RouteSpecification(_shanghai, _gothenburg, DateTime.Now); _cargo = new BookingApi.Domain.Cargo.Cargo(_trackingId, _routeSpecification); _itinerary = new Itinerary(new List<Leg> { new Leg(_voyage, _shanghai, DateTime.Now, _rotterdam, DateTime.Now), new Leg(_voyage, _rotterdam, DateTime.Now, _gothenburg, DateTime.Now) }); }
private bool CalculateMisdirectionStatus(Itinerary itinerary) { if (_lastEvent == null) return false; if (itinerary == null) return false; return !itinerary.IsExpected(_lastEvent); }
private static RoutingStatus CalculateRoutingStatus(Itinerary itinerary, RouteSpecification specification) { if (itinerary == null) return RoutingStatus.NotRouted; return specification.IsSatisfiedBy(itinerary) ? RoutingStatus.Routed : RoutingStatus.Misrouted; }
private HandlingActivity CalculateNextExpectedActivity(RouteSpecification routeSpecification, Itinerary itinerary) { if (!OnTrack) return null; if (LastEvent == null) return new HandlingActivity(HandlingEventType.Receive, routeSpecification.Origin); switch (LastEvent.EventType) { case HandlingEventType.Load: Leg firstOrDefaultLeg = itinerary.Legs.FirstOrDefault(x => x.LoadLocation == LastEvent.Location); return firstOrDefaultLeg != null ? new HandlingActivity(HandlingEventType.Unload, firstOrDefaultLeg.UnloadLocation, firstOrDefaultLeg.Voyage) : null; case HandlingEventType.Unload: IEnumerator<Leg> enumerator = itinerary.Legs.GetEnumerator(); while (enumerator.MoveNext()) { if (enumerator.Current.UnloadLocation == LastEvent.Location) { Leg currentLeg = enumerator.Current; return enumerator.MoveNext() ? new HandlingActivity(HandlingEventType.Load, enumerator.Current.LoadLocation) : new HandlingActivity(HandlingEventType.Claim, currentLeg.UnloadLocation); } } return null; case HandlingEventType.Receive: Leg firstLeg = itinerary.Legs.First(); return new HandlingActivity(HandlingEventType.Load, firstLeg.LoadLocation, firstLeg.Voyage); default: return null; } }
private DateTime? CalculateEta(Itinerary itinerary) { return OnTrack ? itinerary.FinalArrivalDate : null; }
private Delivery(HandlingEvent lastHandlingEvent, Itinerary itinerary, RouteSpecification specification) { _calculatedAt = DateTime.Now; _lastEvent = lastHandlingEvent; _misdirected = CalculateMisdirectionStatus(itinerary); _routingStatus = CalculateRoutingStatus(itinerary, specification); _transportStatus = CalculateTransportStatus(); _lastKnownLocation = CalculateLastKnownLocation(); _currentVoyage = CalculateCurrentVoyage(); _eta = CalculateEta(itinerary); _nextExpectedActivity = CalculateNextExpectedActivity(specification, itinerary); _isUnloadedAtDestination = CalculateUnloadedAtDestination(specification); }
/// <summary> /// Creates a new delivery snapshot to reflect changes in routing, i.e. when the route /// specification or the itinerary has changed but no additional handling of the /// cargo has been performed. /// </summary> /// <param name="routeSpecification">Current route specification.</param> /// <param name="itinerary">Current itinerary.</param> /// <returns>New delivery status description.</returns> public Delivery UpdateOnRouting(RouteSpecification routeSpecification, Itinerary itinerary) { if (routeSpecification == null) throw new ArgumentNullException("Route specification is required.", "routeSpecification"); return new Delivery(_lastEvent, itinerary, routeSpecification); }
/// <summary> /// Creates a new delivery snapshot based on the complete handling history of a cargo, as well /// as its route specification and itinerary. /// </summary> /// <param name="specification">Current route specification.</param> /// <param name="itinerary">Current itinerary.</param> /// <param name="handlingHistory">Delivery history.</param> /// <returns>Delivery status description.</returns> public static Delivery DerivedFrom(RouteSpecification specification, Itinerary itinerary, HandlingHistory handlingHistory) { if (specification == null) throw new ArgumentNullException("specification", "Route specification is required"); if (handlingHistory == null) throw new ArgumentNullException("handlingHistory", "Handling history is required"); var lastHandlingEvent = handlingHistory.MostRecentlyCompletedEvent; return new Delivery(lastHandlingEvent, itinerary, specification); }
/// <summary> /// Assigns cargo to a provided route. /// Attach a new itinerary to this cargo. /// </summary> /// <param name="itinerary">New itinerary</param> public virtual void AssignToRoute(Itinerary itinerary) { if (itinerary == null) throw new ArgumentNullException("itinerary", "Itinerary is required for assignment"); CargoHasBeenAssignedToRouteEvent @event = new CargoHasBeenAssignedToRouteEvent(this, Itinerary); Itinerary = itinerary; // Handling consistency within the Cargo aggregate synchronously Delivery = Delivery.UpdateOnRouting(RouteSpecification, Itinerary); DomainEvents.Raise(@event); }
public void should_correctly_route_cargo() { var cargo = new BookingApi.Domain.Cargo.Cargo(new TrackingId("XYZ"), new RouteSpecification(_stockholm, _melbourne, DateTime.Now)); var good = new Itinerary(new List<Leg> { new Leg(BookingApi.Domain.Voyage.Voyage.Empty, _stockholm, DateTime.Now, _melbourne, DateTime.Now) }); // modif refactoring var bad = new Itinerary(new List<Leg> { new Leg(BookingApi.Domain.Voyage.Voyage.Empty, _hongkong, DateTime.Now, _hambourg, DateTime.Now) }); // modif refactoring var acceptOnlyGood = new FakeRouteSpecification(cargo.Origine, cargo.RouteSpecification.Destination, DateTime.Now, good); cargo.SpecifyNewRoute(acceptOnlyGood); Assert.Equal(RoutingStatus.NotRouted, cargo.Delivery.RoutingStatus); cargo.AssignToRoute(bad); Assert.Equal(RoutingStatus.Misrouted, cargo.Delivery.RoutingStatus); cargo.AssignToRoute(good); Assert.Equal(RoutingStatus.Routed, cargo.Delivery.RoutingStatus); }
public override bool IsSatisfiedBy(Itinerary itinerary) { return itinerary == _compareToThis; }
public FakeRouteSpecification(BookingApi.Domain.Location.Location origin, BookingApi.Domain.Location.Location destination, DateTime arrivalDeadline, Itinerary compareToThis) : base(origin, destination, arrivalDeadline) { _compareToThis = compareToThis; }
private BookingApi.Domain.Cargo.Cargo SetUpCargoWithItinerary(BookingApi.Domain.Location.Location origin, BookingApi.Domain.Location.Location midpoint, BookingApi.Domain.Location.Location destination) { var cargo = new BookingApi.Domain.Cargo.Cargo(new TrackingId("CARGO1"), new RouteSpecification(origin, destination, DateTime.Now)); var itinerary = new Itinerary(new List<Leg> { new Leg(_voyage, origin, DateTime.Now, midpoint, DateTime.Now), new Leg(_voyage, midpoint, DateTime.Now, destination, DateTime.Now) }); cargo.AssignToRoute(itinerary); return cargo; }
public DeliveryTests() { _chicago = new BookingApi.Domain.Location.Location(UnLocodeHelpers.GetNewUnLocode(), "CHICAGO"); _hambourg = new BookingApi.Domain.Location.Location(UnLocodeHelpers.GetNewUnLocode(), "HAMBOURG"); _gdansk = new BookingApi.Domain.Location.Location(UnLocodeHelpers.GetNewUnLocode(), "GDANSK"); _voyage = new BookingApi.Domain.Voyage.Voyage(new VoyageNumber("CM01"), new Schedule(new List<CarrierMovement> { new CarrierMovement(_chicago, _hambourg, DateTime. Now, DateTime. Now) })); _voyage2 = new BookingApi.Domain.Voyage.Voyage(new VoyageNumber("CM03"), new Schedule(new List<CarrierMovement> { new CarrierMovement(_chicago, _hambourg, DateTime. Now, DateTime. Now), new CarrierMovement(_hambourg, _gdansk, DateTime. Now, DateTime. Now) })); _itineraryCHtoHAM = new Itinerary(new List<Leg> { new Leg(_voyage, _chicago, DateTime.Now, _hambourg, DateTime.Now) }); _itineraryCHtoGD = new Itinerary(new List<Leg> { new Leg(_voyage2, _chicago, DateTime.Now, _hambourg, DateTime.Now), new Leg(_voyage2, _hambourg, DateTime.Now, _gdansk, DateTime.Now) }); _itineraryHAMtoCH = new Itinerary(new List<Leg> { new Leg(new BookingApi.Domain.Voyage.Voyage(new VoyageNumber("CM02"), new Schedule(new List<CarrierMovement> { new CarrierMovement(_hambourg, _chicago, DateTime.Now, DateTime.Now) })), _hambourg, DateTime.Now, _chicago, DateTime.Now) }); _cargo = new BookingApi.Domain.Cargo.Cargo(new TrackingId("CAR01"), new RouteSpecification(_chicago, _hambourg, DateTime.Now)); }