aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/controllers/vehicle_journeys_controller.rb1
-rw-r--r--app/javascript/vehicle_journeys/actions/index.js4
-rw-r--r--app/javascript/vehicle_journeys/components/tools/CreateModal.js25
-rw-r--r--app/javascript/vehicle_journeys/reducers/vehicleJourneys.js30
-rw-r--r--app/models/chouette/journey_pattern.rb18
-rw-r--r--app/views/api/v1/journey_patterns/show.rabl10
-rw-r--r--spec/javascript/vehicle_journeys/reducers/vehicleJourneys_spec.js112
-rw-r--r--spec/models/chouette/journey_pattern_spec.rb38
-rw-r--r--spec/support/journey_pattern_helper.rb19
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