diff options
| -rw-r--r-- | app/controllers/vehicle_journeys_controller.rb | 1 | ||||
| -rw-r--r-- | app/javascript/vehicle_journeys/actions/index.js | 4 | ||||
| -rw-r--r-- | app/javascript/vehicle_journeys/components/tools/CreateModal.js | 25 | ||||
| -rw-r--r-- | app/javascript/vehicle_journeys/reducers/vehicleJourneys.js | 30 | ||||
| -rw-r--r-- | app/models/chouette/journey_pattern.rb | 18 | ||||
| -rw-r--r-- | app/views/api/v1/journey_patterns/show.rabl | 10 | ||||
| -rw-r--r-- | spec/javascript/vehicle_journeys/reducers/vehicleJourneys_spec.js | 112 | ||||
| -rw-r--r-- | spec/models/chouette/journey_pattern_spec.rb | 38 | ||||
| -rw-r--r-- | spec/support/journey_pattern_helper.rb | 19 |
9 files changed, 245 insertions, 12 deletions
diff --git a/app/controllers/vehicle_journeys_controller.rb b/app/controllers/vehicle_journeys_controller.rb index 8a0c41cc2..565cccec8 100644 --- a/app/controllers/vehicle_journeys_controller.rb +++ b/app/controllers/vehicle_journeys_controller.rb @@ -63,6 +63,7 @@ class VehicleJourneysController < ChouetteController :city_name => sp.stop_area.try(:city_name), :comment => sp.stop_area.try(:comment), :area_type => sp.stop_area.try(:area_type), + :stop_area_id => sp.stop_area_id, :registration_number => sp.stop_area.try(:registration_number), :nearest_topic_name => sp.stop_area.try(:nearest_topic_name), :fare_code => sp.stop_area.try(:fare_code), diff --git a/app/javascript/vehicle_journeys/actions/index.js b/app/javascript/vehicle_journeys/actions/index.js index 9aa426237..2675328e3 100644 --- a/app/javascript/vehicle_journeys/actions/index.js +++ b/app/javascript/vehicle_journeys/actions/index.js @@ -60,7 +60,9 @@ const actions = { short_id: selectedJP.short_id, name: selectedJP.name, published_name: selectedJP.published_name, - stop_areas: selectedJP.stop_area_short_descriptions + stop_areas: selectedJP.stop_area_short_descriptions, + costs: selectedJP.costs, + full_schedule: selectedJP.full_schedule } }), openEditModal : (vehicleJourney) => ({ diff --git a/app/javascript/vehicle_journeys/components/tools/CreateModal.js b/app/javascript/vehicle_journeys/components/tools/CreateModal.js index 4601d1690..9ab87af3f 100644 --- a/app/javascript/vehicle_journeys/components/tools/CreateModal.js +++ b/app/javascript/vehicle_journeys/components/tools/CreateModal.js @@ -89,6 +89,31 @@ export default class CreateModal extends Component { /> </div> </div> + { this.props.modal.modalProps.selectedJPModal && this.props.modal.modalProps.selectedJPModal.full_schedule && <div className='col-lg-6 col-md-6 col-sm-6 col-xs-12'> + <div className='form-group'> + <label className='control-label'>Heure de départ</label> + <div className='input-group time'> + <input + type='number' + min='00' + max='23' + ref='start_time.hour' + className='form-control' + onKeyDown={(e) => actions.resetValidation(e.currentTarget)} + /> + <input + type='number' + min='00' + max='59' + ref='start_time.minute' + className='form-control' + onKeyDown={(e) => actions.resetValidation(e.currentTarget)} + /> + </div> + </div> + </div> + } + </div> </div> <div className='modal-footer'> diff --git a/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js b/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js index d057bf704..0549c7adc 100644 --- a/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js +++ b/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js @@ -9,16 +9,37 @@ const vehicleJourney= (state = {}, action, keep) => { return _.assign({}, state, {selected: false}) case 'ADD_VEHICLEJOURNEY': let pristineVjasList = [] + let prevSp = action.stopPointsList[0] + let current_time = { + hour: 0, + minute: 0 + } + if(action.data["start_time.hour"] && action.data["start_time.minute"] && action.selectedJourneyPattern.full_schedule){ + current_time.hour = parseInt(action.data["start_time.hour"].value) + current_time.minute = parseInt(action.data["start_time.minute"].value) + } _.each(action.stopPointsList, (sp) =>{ + if(action.selectedJourneyPattern.full_schedule && action.selectedJourneyPattern.costs && action.selectedJourneyPattern.costs[prevSp.stop_area_id + "-" + sp.stop_area_id]){ + let delta = parseInt(action.selectedJourneyPattern.costs[prevSp.stop_area_id + "-" + sp.stop_area_id].time) + let delta_hour = parseInt(delta/60) + let delta_minute = delta - 60*delta_hour + current_time.hour += delta_hour + current_time.minute += delta_minute + let extra_hours = parseInt(current_time.minute/60) + current_time.hour += extra_hours + current_time.minute -= extra_hours*60 + current_time.hour = current_time.hour % 24 + prevSp = sp + } let newVjas = { delta: 0, departure_time:{ - hour: '00', - minute: '00' + hour: current_time.hour, + minute: current_time.minute }, arrival_time:{ - hour: '00', - minute: '00' + hour: current_time.hour, + minute: current_time.minute }, stop_point_objectid: sp.object_id, stop_area_cityname: sp.city_name, @@ -31,6 +52,7 @@ const vehicleJourney= (state = {}, action, keep) => { } }) pristineVjasList.push(newVjas) + }) return { company: action.selectedCompany, diff --git a/app/models/chouette/journey_pattern.rb b/app/models/chouette/journey_pattern.rb index 1ddf7c9fb..d03eb6ad7 100644 --- a/app/models/chouette/journey_pattern.rb +++ b/app/models/chouette/journey_pattern.rb @@ -150,5 +150,23 @@ module Chouette def costs read_attribute(:costs) || {} end + + def costs_between start, finish + key = "#{start.stop_area_id}-#{finish.stop_area_id}" + costs[key]&.symbolize_keys || {} + end + + def full_schedule? + full = true + stop_points.inject(nil) do |start, finish| + next finish unless start.present? + costs = costs_between(start, finish) + full = false unless costs.present? + full = false unless costs[:distance] && costs[:distance] > 0 + full = false unless costs[:time] && costs[:time] > 0 + finish + end + full + end end end diff --git a/app/views/api/v1/journey_patterns/show.rabl b/app/views/api/v1/journey_patterns/show.rabl index 815b1cf0b..ba63a35c7 100644 --- a/app/views/api/v1/journey_patterns/show.rabl +++ b/app/views/api/v1/journey_patterns/show.rabl @@ -5,13 +5,17 @@ extends "api/v1/trident_objects/show" attributes attr, :unless => lambda { |m| m.send( attr).nil?} end +node :full_schedule do |journey_pattern| + journey_pattern.full_schedule? +end + if has_feature? :costs_in_journey_patterns attribute :costs + node(:route_short_description) do |journey_pattern| + partial("api/v1/routes/short_description", :object => journey_pattern.route) + end end -node(:route_short_description) do |journey_pattern| - partial("api/v1/routes/short_description", :object => journey_pattern.route) -end node(:vehicle_journey_object_ids) do |journey_pattern| journey_pattern.vehicle_journeys.pluck(:objectid) diff --git a/spec/javascript/vehicle_journeys/reducers/vehicleJourneys_spec.js b/spec/javascript/vehicle_journeys/reducers/vehicleJourneys_spec.js index 28de241ee..44e11aadf 100644 --- a/spec/javascript/vehicle_journeys/reducers/vehicleJourneys_spec.js +++ b/spec/javascript/vehicle_journeys/reducers/vehicleJourneys_spec.js @@ -76,12 +76,12 @@ describe('vehicleJourneys reducer', () => { let pristineVjasList = [{ delta : 0, arrival_time : { - hour: '00', - minute: '00' + hour: 0, + minute: 0 }, departure_time : { - hour: '00', - minute: '00' + hour: 0, + minute: 0 }, stop_point_objectid: 'test', stop_area_cityname: 'city', @@ -119,6 +119,110 @@ describe('vehicleJourneys reducer', () => { }, ...state]) }) + it('should handle ADD_VEHICLEJOURNEY with a start time and a fully timed JP', () => { + let pristineVjasList = [{ + delta : 0, + arrival_time : { + hour: 22, + minute: 59 + }, + departure_time : { + hour: 22, + minute: 59 + }, + stop_point_objectid: 'test-1', + stop_area_cityname: 'city', + dummy: true + }, + { + delta : 0, + arrival_time : { + hour: 0, + minute: 2 + }, + departure_time : { + hour: 0, + minute: 2 + }, + stop_point_objectid: 'test-2', + stop_area_cityname: 'city', + dummy: true + }, + { + delta : 0, + arrival_time : { + hour: 0, + minute: 2 + }, + departure_time : { + hour: 0, + minute: 2 + }, + stop_point_objectid: 'test-3', + stop_area_cityname: 'city', + dummy: true + }, + { + delta : 0, + arrival_time : { + hour: 0, + minute: 32 + }, + departure_time : { + hour: 0, + minute: 32 + }, + stop_point_objectid: 'test-4', + stop_area_cityname: 'city', + dummy: true + }] + let fakeData = { + published_journey_name: {value: 'test'}, + published_journey_identifier: {value : ''}, + "start_time.hour": {value : '22'}, + "start_time.minute": {value : '59'} + } + let fakeSelectedJourneyPattern = { + id: "1", + full_schedule: true, + costs: { + "1-2": { + distance: 10, + time: 63 + }, + "2-4": { + distance: 10, + time: 30 + } + } + } + let fakeSelectedCompany = {name: "ALBATRANS"} + expect( + vjReducer(state, { + type: 'ADD_VEHICLEJOURNEY', + data: fakeData, + selectedJourneyPattern: fakeSelectedJourneyPattern, + stopPointsList: [{object_id: 'test-1', city_name: 'city', stop_area_id: 1}, {object_id: 'test-2', city_name: 'city', stop_area_id: 2}, {object_id: 'test-3', city_name: 'city', stop_area_id: 3}, {object_id: 'test-4', city_name: 'city', stop_area_id: 4}], + selectedCompany: fakeSelectedCompany + }) + ).toEqual([{ + journey_pattern: fakeSelectedJourneyPattern, + company: fakeSelectedCompany, + published_journey_name: 'test', + published_journey_identifier: '', + short_id: '', + objectid: '', + footnotes: [], + time_tables: [], + purchase_windows: [], + vehicle_journey_at_stops: pristineVjasList, + selected: false, + deletable: false, + transport_mode: 'undefined', + transport_submode: 'undefined' + }, ...state]) + }) + it('should handle RECEIVE_VEHICLE_JOURNEYS', () => { expect( vjReducer(state, { diff --git a/spec/models/chouette/journey_pattern_spec.rb b/spec/models/chouette/journey_pattern_spec.rb index 077c85e85..b5eb9004c 100644 --- a/spec/models/chouette/journey_pattern_spec.rb +++ b/spec/models/chouette/journey_pattern_spec.rb @@ -32,6 +32,44 @@ describe Chouette::JourneyPattern, :type => :model do # end # end + describe "full_schedule?" do + let(:journey_pattern) { create :journey_pattern } + subject{ journey_pattern.full_schedule? } + context "when no time is set" do + it { should be_falsy } + end + + context "when the costs are incomplete" do + context "with a missing distance" do + before(:each){ + journey_pattern.costs = generate_journey_pattern_costs(->(i){i == 1 ? nil : 10}, 10) + } + it { should be_falsy } + end + + context "with a missing time" do + before(:each){ + journey_pattern.costs = generate_journey_pattern_costs(10, ->(i){i == 1 ? nil : 10}) + } + it { should be_falsy } + end + end + + context "with a zeroed cost" do + before(:each){ + journey_pattern.costs = generate_journey_pattern_costs(->(i){i == 1 ? 0 : 10}, 10) + } + it { should be_falsy } + end + + context "when all the times are set" do + before(:each){ + journey_pattern.costs = generate_journey_pattern_costs(10, 10) + } + it { should be_truthy } + end + end + describe "state_update" do def journey_pattern_to_state jp jp.attributes.slice('name', 'published_name', 'registration_number').tap do |item| diff --git a/spec/support/journey_pattern_helper.rb b/spec/support/journey_pattern_helper.rb new file mode 100644 index 000000000..3ba1c501b --- /dev/null +++ b/spec/support/journey_pattern_helper.rb @@ -0,0 +1,19 @@ +module Support + module JourneyPatternHelper + def generate_journey_pattern_costs distance, time + costs = {} + (journey_pattern.stop_points.size - 1).times do |i| + start, finish = journey_pattern.stop_points[i..i+1] + costs["#{start.stop_area_id}-#{finish.stop_area_id}"] = { + distance: (distance.respond_to?(:call) ? distance.call(i) : distance), + time: (time.respond_to?(:call) ? time.call(i) : time) + } + end + costs + end + end +end + +RSpec.configure do | config | + config.include Support::JourneyPatternHelper, type: :model +end |
