cargo.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. // Package shipping contains the heart of the domain model.
  2. package model
  3. import (
  4. "errors"
  5. "strings"
  6. "time"
  7. "github.com/pborman/uuid"
  8. )
  9. // TrackingID uniquely identifies a particular cargo.
  10. type TrackingID string
  11. // Cargo is the central class in the domain model.
  12. type Cargo struct {
  13. TrackingID TrackingID
  14. Origin UNLocode
  15. RouteSpecification RouteSpecification
  16. Itinerary Itinerary
  17. Delivery Delivery
  18. }
  19. // SpecifyNewRoute specifies a new route for this cargo.
  20. func (c *Cargo) SpecifyNewRoute(rs RouteSpecification) {
  21. c.RouteSpecification = rs
  22. c.Delivery = c.Delivery.UpdateOnRouting(c.RouteSpecification, c.Itinerary)
  23. }
  24. // AssignToRoute attaches a new itinerary to this cargo.
  25. func (c *Cargo) AssignToRoute(itinerary Itinerary) {
  26. c.Itinerary = itinerary
  27. c.Delivery = c.Delivery.UpdateOnRouting(c.RouteSpecification, c.Itinerary)
  28. }
  29. // DeriveDeliveryProgress updates all aspects of the cargo aggregate status
  30. // based on the current route specification, itinerary and handling of the cargo.
  31. func (c *Cargo) DeriveDeliveryProgress(history HandlingHistory) {
  32. c.Delivery = DeriveDeliveryFrom(c.RouteSpecification, c.Itinerary, history)
  33. }
  34. // NewCargo creates a new, unrouted cargo.
  35. func NewCargo(id TrackingID, rs RouteSpecification) *Cargo {
  36. itinerary := Itinerary{}
  37. history := HandlingHistory{make([]HandlingEvent, 0)}
  38. return &Cargo{
  39. TrackingID: id,
  40. Origin: rs.Origin,
  41. RouteSpecification: rs,
  42. Delivery: DeriveDeliveryFrom(rs, itinerary, history),
  43. }
  44. }
  45. // CargoRepository provides access a cargo store.
  46. type CargoRepository interface {
  47. Store(cargo *Cargo) (bool, error)
  48. Find(id TrackingID) (*Cargo, error)
  49. FindAll() []*Cargo
  50. }
  51. // ErrUnknownCargo is used when a cargo could not be found.
  52. var ErrUnknownCargo = errors.New("unknown cargo")
  53. // NextTrackingID generates a new tracking ID.
  54. // TODO: Move to infrastructure(?)
  55. func NextTrackingID() TrackingID {
  56. return TrackingID(strings.Split(strings.ToUpper(uuid.New()), "-")[0])
  57. }
  58. // RouteSpecification Contains information about a route: its origin,
  59. // destination and arrival deadline.
  60. type RouteSpecification struct {
  61. Origin UNLocode
  62. Destination UNLocode
  63. ArrivalDeadline time.Time
  64. }
  65. // IsSatisfiedBy checks whether provided itinerary satisfies this
  66. // specification.
  67. func (s RouteSpecification) IsSatisfiedBy(itinerary Itinerary) bool {
  68. return itinerary.Legs != nil &&
  69. s.Origin == itinerary.InitialDepartureLocation() &&
  70. s.Destination == itinerary.FinalArrivalLocation()
  71. }
  72. // RoutingStatus describes status of cargo routing.
  73. type RoutingStatus int
  74. // Valid routing statuses.
  75. const (
  76. NotRouted RoutingStatus = iota
  77. Misrouted
  78. Routed
  79. )
  80. func (s RoutingStatus) String() string {
  81. switch s {
  82. case NotRouted:
  83. return "Not routed"
  84. case Misrouted:
  85. return "Misrouted"
  86. case Routed:
  87. return "Routed"
  88. }
  89. return ""
  90. }
  91. // TransportStatus describes status of cargo transportation.
  92. type TransportStatus int
  93. // Valid transport statuses.
  94. const (
  95. NotReceived TransportStatus = iota
  96. InPort
  97. OnboardCarrier
  98. Claimed
  99. Unknown
  100. )
  101. func (s TransportStatus) String() string {
  102. switch s {
  103. case NotReceived:
  104. return "Not received"
  105. case InPort:
  106. return "In port"
  107. case OnboardCarrier:
  108. return "Onboard carrier"
  109. case Claimed:
  110. return "Claimed"
  111. case Unknown:
  112. return "Unknown"
  113. }
  114. return ""
  115. }