Skip to content
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
122 lines (102 sloc) 3.18 KB
package cargo
// 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 (
// 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 location.UNLocode
VoyageNumber voyage.Number
// 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
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 Repository
VoyageRepository voyage.Repository
LocationRepository location.Repository
// CreateHandlingEvent creates a validated handling event.
func (f *HandlingEventFactory) CreateHandlingEvent(registered time.Time, completed time.Time, id TrackingID,
voyageNumber voyage.Number, unLocode location.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
You can’t perform that action at this time.