forked from marcusolsson/goddd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
handling.go
118 lines (100 loc) · 3.06 KB
/
handling.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
package shipping
// TODO: It would make sense to have this in its own package. Unfortunately,
// then there would be a circular dependency between the cargo and handling
// packages since cargo.Delivery would use handling.HandlingEvent and
// handling.HandlingEvent would use cargo.TrackingID. Also,
// HandlingEventFactory depends on the cargo repository.
//
// It would make sense not having the cargo package depend on handling.
import (
"errors"
"time"
)
// HandlingActivity represents how and where a cargo can be handled, and can
// be used to express predictions about what is expected to happen to a cargo
// in the future.
type HandlingActivity struct {
Type HandlingEventType
Location UNLocode
VoyageNumber VoyageNumber
}
// HandlingEvent is used to register the event when, for instance, a cargo is
// unloaded from a carrier at a some location at a given time.
type HandlingEvent struct {
TrackingID TrackingID
Activity HandlingActivity
}
// HandlingEventType describes type of a handling event.
type HandlingEventType int
// Valid handling event types.
const (
NotHandled HandlingEventType = iota
Load
Unload
Receive
Claim
Customs
)
func (t HandlingEventType) String() string {
switch t {
case NotHandled:
return "Not Handled"
case Load:
return "Load"
case Unload:
return "Unload"
case Receive:
return "Receive"
case Claim:
return "Claim"
case Customs:
return "Customs"
}
return ""
}
// HandlingHistory is the handling history of a cargo.
type HandlingHistory struct {
HandlingEvents []HandlingEvent
}
// MostRecentlyCompletedEvent returns most recently completed handling event.
func (h HandlingHistory) MostRecentlyCompletedEvent() (HandlingEvent, error) {
if len(h.HandlingEvents) == 0 {
return HandlingEvent{}, errors.New("delivery history is empty")
}
return h.HandlingEvents[len(h.HandlingEvents)-1], nil
}
// HandlingEventRepository provides access a handling event store.
type HandlingEventRepository interface {
Store(e HandlingEvent)
QueryHandlingHistory(TrackingID) HandlingHistory
}
// HandlingEventFactory creates handling events.
type HandlingEventFactory struct {
CargoRepository CargoRepository
VoyageRepository VoyageRepository
LocationRepository LocationRepository
}
// CreateHandlingEvent creates a validated handling event.
func (f *HandlingEventFactory) CreateHandlingEvent(registered time.Time, completed time.Time, id TrackingID,
voyageNumber VoyageNumber, unLocode UNLocode, eventType HandlingEventType) (HandlingEvent, error) {
if _, err := f.CargoRepository.Find(id); err != nil {
return HandlingEvent{}, err
}
if _, err := f.VoyageRepository.Find(voyageNumber); err != nil {
// TODO: This is pretty ugly, but when creating a Receive event, the voyage number is not known.
if len(voyageNumber) > 0 {
return HandlingEvent{}, err
}
}
if _, err := f.LocationRepository.Find(unLocode); err != nil {
return HandlingEvent{}, err
}
return HandlingEvent{
TrackingID: id,
Activity: HandlingActivity{
Type: eventType,
Location: unLocode,
VoyageNumber: voyageNumber,
},
}, nil
}