123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- // Package shipping contains the heart of the domain model.
- package model
- import (
- "errors"
- "strings"
- "time"
- "github.com/pborman/uuid"
- )
- // TrackingID uniquely identifies a particular cargo.
- type TrackingID string
- // Cargo is the central class in the domain model.
- type Cargo struct {
- TrackingID TrackingID
- Origin UNLocode
- RouteSpecification RouteSpecification
- Itinerary Itinerary
- Delivery Delivery
- }
- // SpecifyNewRoute specifies a new route for this cargo.
- func (c *Cargo) SpecifyNewRoute(rs RouteSpecification) {
- c.RouteSpecification = rs
- c.Delivery = c.Delivery.UpdateOnRouting(c.RouteSpecification, c.Itinerary)
- }
- // AssignToRoute attaches a new itinerary to this cargo.
- func (c *Cargo) AssignToRoute(itinerary Itinerary) {
- c.Itinerary = itinerary
- c.Delivery = c.Delivery.UpdateOnRouting(c.RouteSpecification, c.Itinerary)
- }
- // DeriveDeliveryProgress updates all aspects of the cargo aggregate status
- // based on the current route specification, itinerary and handling of the cargo.
- func (c *Cargo) DeriveDeliveryProgress(history HandlingHistory) {
- c.Delivery = DeriveDeliveryFrom(c.RouteSpecification, c.Itinerary, history)
- }
- // NewCargo creates a new, unrouted cargo.
- func NewCargo(id TrackingID, rs RouteSpecification) *Cargo {
- itinerary := Itinerary{}
- history := HandlingHistory{make([]HandlingEvent, 0)}
- return &Cargo{
- TrackingID: id,
- Origin: rs.Origin,
- RouteSpecification: rs,
- Delivery: DeriveDeliveryFrom(rs, itinerary, history),
- }
- }
- // CargoRepository provides access a cargo store.
- type CargoRepository interface {
- Store(cargo *Cargo) (bool, error)
- Find(id TrackingID) (*Cargo, error)
- FindAll() []*Cargo
- }
- // ErrUnknownCargo is used when a cargo could not be found.
- var ErrUnknownCargo = errors.New("unknown cargo")
- // NextTrackingID generates a new tracking ID.
- // TODO: Move to infrastructure(?)
- func NextTrackingID() TrackingID {
- return TrackingID(strings.Split(strings.ToUpper(uuid.New()), "-")[0])
- }
- // RouteSpecification Contains information about a route: its origin,
- // destination and arrival deadline.
- type RouteSpecification struct {
- Origin UNLocode
- Destination UNLocode
- ArrivalDeadline time.Time
- }
- // IsSatisfiedBy checks whether provided itinerary satisfies this
- // specification.
- func (s RouteSpecification) IsSatisfiedBy(itinerary Itinerary) bool {
- return itinerary.Legs != nil &&
- s.Origin == itinerary.InitialDepartureLocation() &&
- s.Destination == itinerary.FinalArrivalLocation()
- }
- // RoutingStatus describes status of cargo routing.
- type RoutingStatus int
- // Valid routing statuses.
- const (
- NotRouted RoutingStatus = iota
- Misrouted
- Routed
- )
- func (s RoutingStatus) String() string {
- switch s {
- case NotRouted:
- return "Not routed"
- case Misrouted:
- return "Misrouted"
- case Routed:
- return "Routed"
- }
- return ""
- }
- // TransportStatus describes status of cargo transportation.
- type TransportStatus int
- // Valid transport statuses.
- const (
- NotReceived TransportStatus = iota
- InPort
- OnboardCarrier
- Claimed
- Unknown
- )
- func (s TransportStatus) String() string {
- switch s {
- case NotReceived:
- return "Not received"
- case InPort:
- return "In port"
- case OnboardCarrier:
- return "Onboard carrier"
- case Claimed:
- return "Claimed"
- case Unknown:
- return "Unknown"
- }
- return ""
- }
|