Skip to content

Commit

Permalink
Option to force old headers
Browse files Browse the repository at this point in the history
  • Loading branch information
fonsecadeline committed Jun 9, 2021
1 parent 9ec9e6d commit dc3c88e
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 13 deletions.
1 change: 1 addition & 0 deletions api/v01/entities/vrp_input.rb
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ module VrpConfiguration
optional(:geometry_polyline, type: Boolean, documentation: { hidden: true }, desc: '[DEPRECATED] Use geometry instead, with :polylines or :encoded_polylines')
optional(:intermediate_solutions, type: Boolean, desc: 'Return intermediate solutions if available')
optional(:csv, type: Boolean, desc: 'The output is a CSV file if you do not specify api format')
optional(:use_deprecated_csv_headers, type: Boolean, desc: 'Forces API to ignore provided language to return old CSV headers')
optional(:allow_empty_result, type: Boolean, desc: 'Allow no solution from the solver used')
end

Expand Down
26 changes: 14 additions & 12 deletions lib/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,19 +65,21 @@ def self.euclidean_distance(loc_a, loc_b)

def self.merge_results(results, merge_unassigned = true)
results.flatten!
results.compact!
{
solvers: results.flat_map{ |r| r && r[:solvers] }.compact,
cost: results.map{ |r| r && r[:cost] }.compact.reduce(&:+),
cost_details: results.map{ |r| r && r[:cost_details] }.compact.sum,
iterations: (results.size != 1) ? nil : results[0] && results[0][:iterations],
heuristic_synthesis: (results.size != 1) ? nil : results[0] && results[0][:heuristic_synthesis],
routes: results.flat_map{ |r| r && r[:routes] }.compact.uniq,
unassigned: merge_unassigned ? results.flat_map{ |r| r && r[:unassigned] }.compact.uniq : results.map{ |r| r && r[:unassigned] }.compact.last,
elapsed: results.map{ |r| r && r[:elapsed] || 0 }.reduce(&:+),
total_time: results.map{ |r| r && r[:total_time] }.compact.reduce(&:+),
total_travel_time: results.map{ |r| r && r[:total_travel_time] }.compact.reduce(&:+),
total_value: results.map{ |r| r && r[:total_travel_value] }.compact.reduce(&:+),
total_distance: results.map{ |r| r && r[:total_distance] }.compact.reduce(&:+)
solvers: results.flat_map{ |r| r[:solvers] }.compact,
cost: results.map{ |r| r[:cost] }.compact.reduce(&:+),
cost_details: results.map{ |r| r[:cost_details] }.compact.sum,
iterations: results.size != 1 ? nil : results[0][:iterations],
heuristic_synthesis: results.size != 1 ? nil : results[0][:heuristic_synthesis],
routes: results.flat_map{ |r| r[:routes] }.compact.uniq,
unassigned: merge_unassigned ? results.flat_map{ |r| r[:unassigned] }.compact.uniq : results.map{ |r| r[:unassigned] }.compact.last,
elapsed: results.map{ |r| r[:elapsed] || 0 }.reduce(&:+),
total_time: results.map{ |r| r[:total_time] }.compact.reduce(&:+),
total_travel_time: results.map{ |r| r[:total_travel_time] }.compact.reduce(&:+),
total_value: results.map{ |r| r[:total_travel_value] }.compact.reduce(&:+),
total_distance: results.map{ |r| r[:total_distance] }.compact.reduce(&:+),
use_deprecated_csv_headers: results.any?{ |r| r[:use_deprecated_csv_headers] },
}
end

Expand Down
1 change: 1 addition & 0 deletions lib/output_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ def self.formatted_duration(duration)
def self.build_csv(solutions)
return unless solutions

I18n.locale = :legacy if solutions.any?{ |s| s[:use_deprecated_csv_headers] }
header, unit_ids, max_timewindows_size, scheduling, any_unassigned = generate_header(solutions)

CSV.generate{ |output_csv|
Expand Down
1 change: 1 addition & 0 deletions models/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ class Restitution < Base
field :geometry, default: []
field :intermediate_solutions, default: true
field :csv, default: false
field :use_deprecated_csv_headers, default: false
field :allow_empty_result, default: false
end

Expand Down
2 changes: 2 additions & 0 deletions models/vrp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ class Vrp < Base
field :restitution_geometry, default: []
field :restitution_intermediate_solutions, default: true
field :restitution_csv, default: false
field :restitution_use_deprecated_csv_headers, default: false
field :restitution_allow_empty_result, default: false

field :schedule_range_indices, default: nil # extends schedule_range_date within algorithm
Expand Down Expand Up @@ -459,6 +460,7 @@ def restitution=(restitution)
self.restitution_geometry = restitution[:geometry]
self.restitution_intermediate_solutions = restitution[:intermediate_solutions]
self.restitution_csv = restitution[:csv]
self.restitution_use_deprecated_csv_headers = restitution[:use_deprecated_csv_headers]
self.restitution_allow_empty_result = restitution[:allow_empty_result]
end

Expand Down
1 change: 1 addition & 0 deletions optimizer_wrapper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ def self.define_process(service_vrp, job = nil, &block)
check_result_consistency(expected_activity_count, result) if service_vrp[:service] != :demo # demo solver returns a fixed solution

log "<-- define_process levels (dicho: #{dicho_level}, split: #{split_level}) elapsed: #{(Time.now - tic).round(2)} sec", level: :info
result[:use_deprecated_csv_headers] = vrp.restitution_use_deprecated_csv_headers
result
end

Expand Down
36 changes: 35 additions & 1 deletion test/api/v01/output_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,18 @@ def test_provided_language
submit_csv api_key: 'demo', vrp: vrp, http_accept_language: provided
end
}

[true, false].each{ |parameter_value|
vrp[:configuration][:restitution][:use_deprecated_csv_headers] = parameter_value
OutputHelper::Result.stub(
:build_csv,
lambda { |solutions|
assert_equal parameter_value, solutions.first[:use_deprecated_csv_headers]
}
) do
submit_csv api_key: 'demo', vrp: vrp, http_accept_language: 'fr'
end
}
end

def test_returned_types
Expand Down Expand Up @@ -478,7 +490,7 @@ def test_csv_headers_compatible_with_import_according_to_language
'duration per destination', 'visit duration', 'tags visit', 'tags', 'quantity[kg]',
'time window start 1', 'time window end 1', 'vehicle', 'reference'],
es: [
'nombre del plan', 'referencia del plan', 'gira', 'nombre', 'tipo parada', 'lat', 'lng', 'hora', 'fin',
'plan', 'referencia del plan', 'gira', 'nombre', 'tipo parada', 'lat', 'lng', 'hora', 'fin',
'horario inicio 1', 'horario fin 1', 'duración de preparación', 'duración visita', 'cantidad[kg]',
'etiquetas visita', 'etiquetas', 'vehículo', 'referencia visita'],
fr: ['plan', 'référence plan', 'tournée', 'nom', 'lat', 'lng', 'type arrêt', 'heure',
Expand All @@ -497,4 +509,26 @@ def test_csv_headers_compatible_with_import_according_to_language
}
end
end

def test_use_deprecated_csv_headers_asynchronously
vrp = VRP.lat_lon
vrp[:configuration][:restitution] = { csv: true }

legacy_basic_headers = %w[vehicle_id id point_id type begin_time end_time setup_duration duration skills]
french_basic_headers = ['tournée', 'référence', 'heure', 'fin de la mission', 'durée client', 'durée visite', 'libellés']
[[true, legacy_basic_headers],
[false, french_basic_headers]].each{ |parameter, expected|

vrp[:configuration][:restitution][:use_deprecated_csv_headers] = parameter

asynchronously start_worker: true do
@job_id = submit_csv api_key: 'demo', vrp: vrp, http_accept_language: 'fr'
wait_status_csv @job_id, 200, api_key: 'demo', http_accept_language: 'fr'
current_headers = last_response.body.split("\n").first.split(',')
assert_empty expected - current_headers

delete_completed_job @job_id, api_key: 'ortools'
end
}
end
end

0 comments on commit dc3c88e

Please sign in to comment.