Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
124 lines (107 sloc) 4.33 KB
require 'date'
require 'ice_nine'
require 'value_object'
class Delivery < ValueObject
attr_reader :transport_status
attr_reader :last_known_location
attr_reader :is_misdirected
attr_reader :eta
attr_reader :is_unloaded_at_destination
attr_reader :routing_status
attr_reader :calculated_at
attr_reader :last_handling_event
attr_reader :next_expected_activity
class InitializationError < RuntimeError; end
def initialize(route_specification, itinerary, last_handling_event)
raise InitializationError unless route_specification
@last_handling_event = last_handling_event
@routing_status = calculate_routing_status(itinerary, route_specification)
@transport_status = calculate_transport_status(last_handling_event)
@last_known_location = calculate_last_known_location(last_handling_event)
@is_misdirected = calculate_misdirection_status(last_handling_event, itinerary)
@is_unloaded_at_destination = calculate_unloaded_at_destination(last_handling_event, route_specification)
@eta = calculate_eta(itinerary)
@next_expected_activity = calculate_next_expected_activity(last_handling_event, route_specification, itinerary)
@calculated_at = DateTime.now
IceNine.deep_freeze(self)
end
def self.derived_from(route_specification, itinerary, last_handling_event)
Delivery.new(route_specification, itinerary, last_handling_event)
end
def on_track?
@routing_status == RoutingStatus::Routed && is_misdirected == false
end
private
def calculate_last_known_location(last_handling_event)
if last_handling_event.nil?
return nil
end
last_handling_event.location
end
def calculate_unloaded_at_destination(last_handling_event, route_specification)
if last_handling_event.nil?
return false
end
last_handling_event.event_type == HandlingEventType::Unload &&
last_handling_event.location == route_specification.destination
end
def calculate_misdirection_status(last_handling_event, itinerary)
if itinerary.nil?
return false
end
if last_handling_event.nil?
return false
end
!itinerary.is_expected(last_handling_event)
end
def calculate_routing_status(itinerary, route_specification)
if itinerary.nil?
return RoutingStatus::NotRouted
end
route_specification.is_satisfied_by(itinerary) ? RoutingStatus::Routed : RoutingStatus::Misrouted
end
def calculate_transport_status(last_handling_event)
if last_handling_event.nil?
return TransportStatus::NotReceived
end
case last_handling_event.event_type
when HandlingEventType::Load
TransportStatus::OnboardCarrier
when HandlingEventType::Unload, HandlingEventType::Receive
TransportStatus::InPort
when HandlingEventType::Claim
TransportStatus::Claimed
else
TransportStatus::Unknown
end
end
def calculate_eta(itinerary)
on_track? ? itinerary.final_arrival_date : nil
end
def calculate_next_expected_activity(last_handling_event, route_specification, itinerary)
unless on_track?
return nil
end
if (last_handling_event.nil?)
return HandlingActivity.new(HandlingEventType::Receive, route_specification.origin)
end
case last_handling_event.event_type
when HandlingEventType::Load
last_leg_index = itinerary.legs.index { |x| x.load_location == last_handling_event.location }
return last_leg_index.nil? == false ? HandlingActivity.new(HandlingEventType::Unload, itinerary.legs[last_leg_index].unload_location) : nil
when HandlingEventType::Unload
itinerary.legs.each_cons(2) do |leg, next_leg|
if (leg.unload_location == last_handling_event.location)
return HandlingActivity.new(HandlingEventType::Load, next_leg.load_location) if next_leg
end
return HandlingActivity.new(HandlingEventType::Claim, next_leg.unload_location)
end
when HandlingEventType::Receive
return HandlingActivity.new(HandlingEventType::Load, itinerary.legs.first.load_location)
when HandlingEventType::Claim
nil # TODO What to do here? .NET doesn't handle this case at all
else
nil # TODO What to do here? .NET returns null
end
end
end