diff --git a/models/vrp.rb b/models/vrp.rb index b9de6afa9..974154193 100644 --- a/models/vrp.rb +++ b/models/vrp.rb @@ -141,6 +141,16 @@ def self.check_consistency(hash) hash[:services] ||= [] hash[:shipments] ||= [] + # shipment relation consistency + shipment_relations = hash[:relations]&.select{ |r| r[:type] == :shipment }&.flat_map{ |r| r[:linked_ids] }.to_a + unless shipment_relations.size == shipment_relations.uniq.size + raise OptimizerWrapper::UnsupportedProblemError.new( + 'Services can appear in at most one shipment relation. '\ + 'Following services appear in multiple shipment relations', + shipment_relations.detect{ |id| shipment_relations.count(id) > 1 } + ) + end + # vehicle time cost consistency if hash[:vehicles]&.any?{ |v| v[:cost_waiting_time_multiplier].to_f > (v[:cost_time_multiplier] || 1) } raise OptimizerWrapper::DiscordantProblemError, 'cost_waiting_time_multiplier cannot be greater than cost_time_multiplier' @@ -150,11 +160,9 @@ def self.check_consistency(hash) # TODO: Active Hash should be checking this [:matrices, :units, :points, :rests, :zones, :timewindows, :vehicles, :services, :shipments, :subtours].each{ |key| - next if hash[key].to_a.collect{ |v| v[:id] }.uniq!.nil? + next if hash[key]&.collect{ |v| v[:id] }&.uniq!.nil? - raise OptimizerWrapper::DiscordantProblemError.new( - "#{key} IDs should be unique" - ) + raise OptimizerWrapper::DiscordantProblemError.new("#{key} IDs should be unique") } # matrix_id consistency diff --git a/test/models/vrp_consistency_test.rb b/test/models/vrp_consistency_test.rb index e40588990..9de6a9fdd 100644 --- a/test/models/vrp_consistency_test.rb +++ b/test/models/vrp_consistency_test.rb @@ -344,5 +344,20 @@ def test_consistent_schedule Models::Vrp.check_consistency(vrp) end end + + def test_services_cannot_appear_in_more_than_one_shipment_relation + vrp = VRP.basic + vrp[:relations] = [ + { type: :shipment, linked_ids: %w[service_1 service_2] }, + { type: :shipment, linked_ids: %w[service_1 service_3] } + ] + error = assert_raises OptimizerWrapper::UnsupportedProblemError do + Models::Vrp.check_consistency(TestHelper.coerce(vrp)) + end + + assert_equal 'Services can appear in at most one shipment relation. '\ + 'Following services appear in multiple shipment relations', + error.message, 'Error message does not match' + end end end diff --git a/test/models/vrp_test.rb b/test/models/vrp_test.rb index cb7314158..26d5a04e3 100644 --- a/test/models/vrp_test.rb +++ b/test/models/vrp_test.rb @@ -281,7 +281,7 @@ def test_available_interval def test_no_lapse_in_relation vrp = VRP.basic vrp[:relations] = [{ - type: 'vehicle_group_duration_on_months', + type: :vehicle_group_duration_on_months, linked_vehicle_ids: ['vehicle_0'] }] @@ -289,7 +289,7 @@ def test_no_lapse_in_relation assert_empty vrp[:relations] # reject relation because lapse is mandatory vrp[:relations] = [{ - type: 'vehicle_group_duration_on_months', + type: :vehicle_group_duration_on_months, linked_vehicle_ids: ['vehicle_0'], lapse: 2 }] @@ -298,7 +298,7 @@ def test_no_lapse_in_relation vrp = VRP.lat_lon_two_vehicles vrp[:relations] = [{ - type: 'vehicle_trips', + type: :vehicle_trips, linked_vehicle_ids: vrp[:vehicles].collect{ |v| v[:id] } }] Models::Vrp.filter(vrp)