| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 | 
							- package model
 
- // 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
 
- }
 
 
  |