This repository has been archived by the owner on Oct 13, 2021. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 273
/
cargo.go
135 lines (115 loc) · 3.28 KB
/
cargo.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Package shipping contains the heart of the domain model.
package shipping
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) 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 ""
}