3 // TODO: It would make sense to have this in its own package. Unfortunately,
4 // then there would be a circular dependency between the cargo and handling
5 // packages since cargo.Delivery would use handling.HandlingEvent and
6 // handling.HandlingEvent would use cargo.TrackingID. Also,
7 // HandlingEventFactory depends on the cargo repository.
9 // It would make sense not having the cargo package depend on handling.
15 "github.com/go-kit/kit/examples/shipping/location"
16 "github.com/go-kit/kit/examples/shipping/voyage"
19 // HandlingActivity represents how and where a cargo can be handled, and can
20 // be used to express predictions about what is expected to happen to a cargo
22 type HandlingActivity struct {
23 Type HandlingEventType
24 Location location.UNLocode
25 VoyageNumber voyage.Number
28 // HandlingEvent is used to register the event when, for instance, a cargo is
29 // unloaded from a carrier at a some location at a given time.
30 type HandlingEvent struct {
32 Activity HandlingActivity
35 // HandlingEventType describes type of a handling event.
36 type HandlingEventType int
38 // Valid handling event types.
40 NotHandled HandlingEventType = iota
48 func (t HandlingEventType) String() string {
67 // HandlingHistory is the handling history of a cargo.
68 type HandlingHistory struct {
69 HandlingEvents []HandlingEvent
72 // MostRecentlyCompletedEvent returns most recently completed handling event.
73 func (h HandlingHistory) MostRecentlyCompletedEvent() (HandlingEvent, error) {
74 if len(h.HandlingEvents) == 0 {
75 return HandlingEvent{}, errors.New("delivery history is empty")
78 return h.HandlingEvents[len(h.HandlingEvents)-1], nil
81 // HandlingEventRepository provides access a handling event store.
82 type HandlingEventRepository interface {
83 Store(e HandlingEvent)
84 QueryHandlingHistory(TrackingID) HandlingHistory
87 // HandlingEventFactory creates handling events.
88 type HandlingEventFactory struct {
89 CargoRepository Repository
90 VoyageRepository voyage.Repository
91 LocationRepository location.Repository
94 // CreateHandlingEvent creates a validated handling event.
95 func (f *HandlingEventFactory) CreateHandlingEvent(registered time.Time, completed time.Time, id TrackingID,
96 voyageNumber voyage.Number, unLocode location.UNLocode, eventType HandlingEventType) (HandlingEvent, error) {
98 if _, err := f.CargoRepository.Find(id); err != nil {
99 return HandlingEvent{}, err
102 if _, err := f.VoyageRepository.Find(voyageNumber); err != nil {
103 // TODO: This is pretty ugly, but when creating a Receive event, the voyage number is not known.
104 if len(voyageNumber) > 0 {
105 return HandlingEvent{}, err
109 if _, err := f.LocationRepository.Find(unLocode); err != nil {
110 return HandlingEvent{}, err
113 return HandlingEvent{
115 Activity: HandlingActivity{
118 VoyageNumber: voyageNumber,