diff options
| author | Teddy Wing | 2017-06-14 18:37:50 +0200 |
|---|---|---|
| committer | Teddy Wing | 2017-06-14 18:37:50 +0200 |
| commit | 467f787eb36b68f809409ec3a01797af30fe5128 (patch) | |
| tree | c356ce51ba8990f86a3ecce737985442f9d1e602 | |
| parent | 8c9eb5e1108f4d7e182c9984d667ed7cf4adc006 (diff) | |
| parent | b7fac062e4a0fcaf485ff7c848f161f99f020a5f (diff) | |
| download | chouette-core-467f787eb36b68f809409ec3a01797af30fe5128.tar.bz2 | |
Merge remote-tracking branch 'origin/master' into 3479-refactor-table_builder-helper
| -rw-r--r-- | Gemfile.lock | 10 | ||||
| -rw-r--r-- | app/assets/javascripts/es6_browserified/itineraries/index.js | 2 | ||||
| -rw-r--r-- | app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/DuplicateVehicleJourney.js | 103 | ||||
| -rw-r--r-- | app/assets/javascripts/routing_constraint_zones.coffee | 86 | ||||
| -rw-r--r-- | app/controllers/route_stop_points_controller.rb | 3 | ||||
| -rw-r--r-- | app/controllers/routing_constraint_zones_controller.rb | 15 | ||||
| -rw-r--r-- | app/models/chouette/time_table.rb | 11 | ||||
| -rw-r--r-- | app/models/clean_up.rb | 12 | ||||
| -rw-r--r-- | app/views/routing_constraint_zones/_form.html.slim | 19 | ||||
| -rw-r--r-- | config/locales/routing_constraint_zones.en.yml | 1 | ||||
| -rw-r--r-- | config/locales/routing_constraint_zones.fr.yml | 1 | ||||
| -rw-r--r-- | spec/controllers/route_stop_points_controller_spec.rb | 4 | ||||
| -rw-r--r-- | spec/models/chouette/time_table_spec.rb | 11 | ||||
| -rw-r--r-- | spec/models/clean_up_spec.rb | 10 |
14 files changed, 176 insertions, 112 deletions
diff --git a/Gemfile.lock b/Gemfile.lock index 921f0f367..eea6f4ba5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -9,10 +9,10 @@ GIT GIT remote: git@github.com:af83/stif-codifline-api.git - revision: 02108a647514ca36e4377deecf3ffcce99359139 + revision: c0efb26bf202e0770348bdac060b14c28e575ac2 specs: codifligne (0.0.2) - nokogiri (~> 1.6) + nokogiri (>= 1.7.2) GIT remote: git@github.com:af83/stif-reflex-api.git @@ -309,7 +309,7 @@ GEM mime-types-data (~> 3.2015) mime-types-data (3.2016.0521) mimemagic (0.3.2) - mini_portile2 (2.1.0) + mini_portile2 (2.2.0) minitest (5.10.1) multi_json (1.12.1) multi_test (0.1.2) @@ -323,8 +323,8 @@ GEM net-ssh-gateway (2.0.0) net-ssh (>= 4.0.0) newrelic_rpm (4.0.0.332) - nokogiri (1.7.1) - mini_portile2 (~> 2.1.0) + nokogiri (1.8.0) + mini_portile2 (~> 2.2.0) open4 (1.3.4) orm_adapter (0.5.0) parser (2.4.0.0) diff --git a/app/assets/javascripts/es6_browserified/itineraries/index.js b/app/assets/javascripts/es6_browserified/itineraries/index.js index 504734801..2f1e9d180 100644 --- a/app/assets/javascripts/es6_browserified/itineraries/index.js +++ b/app/assets/javascripts/es6_browserified/itineraries/index.js @@ -38,7 +38,7 @@ const getInitialState = () => { for_alighting: v.for_alighting || "normal", longitude: v.longitude || 0, latitude: v.latitude || 0, - comment: v.comment.replace("'", "\'"), + comment: v.comment ? v.comment.replace("'", "\'") : '', olMap: { isOpened: false, json: {} diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/DuplicateVehicleJourney.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/DuplicateVehicleJourney.js index f4d1444cf..0cf102693 100644 --- a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/DuplicateVehicleJourney.js +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/DuplicateVehicleJourney.js @@ -53,74 +53,75 @@ class DuplicateVehicleJourney extends Component { <div className='modal-header'> <h4 className='modal-title'>Dupliquer une course</h4> {(this.props.modal.type == 'duplicate') && ( - <em>Dupliquer les horaires de la course {actions.getSelected(this.props.vehicleJourneys)[0].objectid}</em> + <em>Dupliquer les horaires de la course {actions.humanOID(actions.getSelected(this.props.vehicleJourneys)[0].objectid)}</em> )} </div> {(this.props.modal.type == 'duplicate') && ( - <form> + <form className='form-horizontal'> <div className='modal-body'> - <div className='row'> - <div className={'col-lg-3 col-lg-offset-1 col-md-3 col-md-offset-1 col-sm-3 col-sm-offset-1 col-xs-3 col-xs-offset-1 ' + (actions.getSelected(this.props.vehicleJourneys).length > 1 ? 'hidden' : '' )}> - <div className='form-group'> - <label className='control-label is-required'>Horaire de départ</label> - <span className={'input-group time' + (actions.getSelected(this.props.vehicleJourneys).length > 1 ? ' disabled' : '')}> - <input - type='number' - ref='duplicate_time_hh' - min='00' - max='23' - className='form-control' - defaultValue={this.getDefaultValue('hour')} - disabled={(actions.getSelected(this.props.vehicleJourneys).length > 1 ? 'disabled' : '')} - /> - <span>:</span> - <input - type='number' - ref='duplicate_time_mm' - min='00' - max='59' - className='form-control' - defaultValue={this.getDefaultValue('minute')} - disabled={(actions.getSelected(this.props.vehicleJourneys).length > 1 ? 'disabled' : '')} - /> - </span> - </div> - </div> - - <div className='col-lg-4 col-md-4 col-sm-4 col-xs-4'> - <div className='form-group'> - <label className='control-label is-required'>Nombre de courses à créer et dupliquer</label> + <div className={'form-group ' + (actions.getSelected(this.props.vehicleJourneys).length > 1 ? 'hidden' : '' )}> + <label className='control-label is-required col-sm-8'>Horaire de départ indicatif</label> + <span className="col-sm-4"> + <span className={'input-group time' + (actions.getSelected(this.props.vehicleJourneys).length > 1 ? ' disabled' : '')}> <input type='number' - ref='duplicate_number' - min='1' - max='20' - defaultValue='1' + ref='duplicate_time_hh' + min='00' + max='23' className='form-control' - onKeyDown={(e) => actions.resetValidation(e.currentTarget)} - required + defaultValue={this.getDefaultValue('hour')} + disabled={(actions.getSelected(this.props.vehicleJourneys).length > 1 ? 'disabled' : '')} /> - </div> - </div> - - <div className='col-lg-3 col-md-3 col-sm-3 col-xs-3'> - <div className='form-group'> - <label className='control-label is-required'>Avec un décalage de</label> + <span>:</span> <input type='number' - ref='additional_time' - min='-59' + ref='duplicate_time_mm' + min='00' max='59' - defaultValue='0' className='form-control' - onKeyDown={(e) => actions.resetValidation(e.currentTarget)} - required + defaultValue={this.getDefaultValue('minute')} + disabled={(actions.getSelected(this.props.vehicleJourneys).length > 1 ? 'disabled' : '')} /> - </div> + </span> + </span> + </div> + + <div className='form-group'> + <label className='control-label is-required col-sm-8'>Nombre de courses à créer et dupliquer</label> + <div className="col-sm-4"> + <input + type='number' + style={{'width': 104}} + ref='duplicate_number' + min='1' + max='20' + defaultValue='1' + className='form-control' + onKeyDown={(e) => actions.resetValidation(e.currentTarget)} + required + /> + </div> + </div> + + <div className='form-group'> + <label className='control-label is-required col-sm-8'>Décalage à partir duquel on créé les courses</label> + <div className="col-sm-4"> + <input + type='number' + style={{'width': 104}} + ref='additional_time' + min='-59' + max='59' + defaultValue='0' + className='form-control' + onKeyDown={(e) => actions.resetValidation(e.currentTarget)} + required + /> </div> </div> </div> + <div className='modal-footer'> <button className='btn btn-link' diff --git a/app/assets/javascripts/routing_constraint_zones.coffee b/app/assets/javascripts/routing_constraint_zones.coffee index e978cd29a..ceb9fb218 100644 --- a/app/assets/javascripts/routing_constraint_zones.coffee +++ b/app/assets/javascripts/routing_constraint_zones.coffee @@ -1,28 +1,62 @@ -fill_stop_points_options = -> - stop_point_select = $('#routing_constraint_zone_stop_point_ids') - stop_point_select.empty() - referential_id = document.location.pathname.match(/\d+/g)[0] - line_id = document.location.pathname.match(/\d+/g)[1] - route_id = $('#routing_constraint_zone_route_id').val() - - if errors_on_form() - stop_point_ids = eval($('#stop_point_ids').val()) - - $.ajax - url: "/referentials/#{referential_id}/lines/#{line_id}/routes/#{route_id}/stop_points" - dataType: 'json' - success: (data, textStatus, jqXHR) -> - for stop_point in data - selected = $.inArray(stop_point.id, stop_point_ids) != -1 - stop_point_select.append "<option value='#{stop_point.id}'" + "#{if selected then ' selected' else ''}" + ">#{stop_point.name}</option>" - error: (jqXHR, textStatus, errorThrown) -> - console.log textStatus - console.log errorThrown - -errors_on_form = -> - document.location.pathname.endsWith('routing_constraint_zones') && $('#new_routing_constraint_zone').length +@ITL_stoppoints = -> + routeID = $('#routing_constraint_zone_route_id').val() + + if (routeID) + origin = window.location.origin + path = window.location.pathname.split('/', 5).join('/') + reqURL = origin + path + '/routes/' + routeID + '/stop_points.json' + + $.ajax + url: reqURL + dataType: 'json' + error: (jqXHR, textStatus, errorThrown) -> + console.log(errorThrown) + success: (collection, textStatus, jqXHR) -> + html = '' + stopAreaBaseURL = origin + window.location.pathname.split('/', 3).join('/') + '/stop_areas/' + + collection.forEach (item, index) -> + html += "<div class='nested-fields'><div class='wrapper'> + <div><a href='" + stopAreaBaseURL + item.stop_area_id + "' class='navlink' title='Voir l'arrêt'><span>" + item.name + "</span></a></div> + <div><span>" + item.city_name + " (" + item.zip_code + ")</span></div> + <div> + <span class='has_radio'> + <input type='checkbox' name='routing_constraint_zone[stop_point_ids][" + index + "]' value='" + item.id + "'> + <span class='radio-label'></span> + </span> + </div> + </div></div>" + + $('#ITL_stoppoints').find('.nested-fields').remove() + $('#ITL_stoppoints').find('.nested-head').after(html) + + # VALIDATION + selection = [] + $('#ITL_stoppoints').on 'click', "input[type='checkbox']", (e) -> + v = $(e.target).val() + + if ( $.inArray(v, selection) != -1 ) + selection.splice(selection.indexOf(v), 1) + else + selection.push(v) + + alertMsg = "<div class='alert alert-danger' style='margin-bottom:15px;'> + <p class='small'>Un ITL doit comporter au moins deux arrêts</p> + </div>" + + $(document).on 'click', "input[type='submit']", (e)-> + inputName = $('#routing_constraint_zone_name').val() + + $('.alert-danger').remove() + + if ( selection.length < 2 && inputName != "") + e.preventDefault() + $('#routing_constraint_zone_name').closest('.form-group').removeClass('has-error').find('.help-block').remove() + $('#ITL_stoppoints').prepend(alertMsg) $ -> - if document.location.pathname.endsWith('routing_constraint_zones/new') || errors_on_form() - fill_stop_points_options() - $('#routing_constraint_zone_route_id').change(fill_stop_points_options) + ITL_stoppoints() + + $('#routing_constraint_zone_route_id').on 'change', -> + $('.alert-danger').remove() + ITL_stoppoints() diff --git a/app/controllers/route_stop_points_controller.rb b/app/controllers/route_stop_points_controller.rb index e12acb33b..730bd08a9 100644 --- a/app/controllers/route_stop_points_controller.rb +++ b/app/controllers/route_stop_points_controller.rb @@ -11,8 +11,7 @@ class RouteStopPointsController < ChouetteController def index respond_to do |format| - format.json { render json: referential.lines.find(params[:line_id]).routes.find(params[:route_id]).stop_points.map { |sp| { id: sp.id, name: sp.name } } } + format.json { render json: referential.lines.find(params[:line_id]).routes.find(params[:route_id]).stop_points.map { |sp| { id: sp.id, stop_area_id: sp.stop_area.id, name: sp.name, zip_code: sp.stop_area.zip_code, city_name: sp.stop_area.city_name } } } end end end - diff --git a/app/controllers/routing_constraint_zones_controller.rb b/app/controllers/routing_constraint_zones_controller.rb index b5072f401..7707427b0 100644 --- a/app/controllers/routing_constraint_zones_controller.rb +++ b/app/controllers/routing_constraint_zones_controller.rb @@ -4,7 +4,7 @@ class RoutingConstraintZonesController < ChouetteController defaults resource_class: Chouette::RoutingConstraintZone respond_to :html, :xml, :json - before_action :remove_empty_stop_point, only: [:create, :update] + before_action :check_stoppoint_param, only: [:create, :update] belongs_to :referential do belongs_to :line, parent_class: Chouette::Line @@ -56,7 +56,16 @@ class RoutingConstraintZonesController < ChouetteController ) end - def remove_empty_stop_point - params.require(:routing_constraint_zone)[:stop_point_ids].delete('') + def check_stoppoint_param + spArr = [] + if params.require(:routing_constraint_zone)[:stop_point_ids] and params.require(:routing_constraint_zone)[:stop_point_ids].length >= 2 + params.require(:routing_constraint_zone)[:stop_point_ids].each do |k,v| + spArr << v + end + params.require(:routing_constraint_zone)[:stop_point_ids] = spArr + else + Rails.logger.error("Error: An ITL must have at least two stop points") + end end + end diff --git a/app/models/chouette/time_table.rb b/app/models/chouette/time_table.rb index 151570f20..4186af6d2 100644 --- a/app/models/chouette/time_table.rb +++ b/app/models/chouette/time_table.rb @@ -477,17 +477,18 @@ class Chouette::TimeTable < Chouette::TridentActiveRecord # merge effective days from another timetable def merge!(another_tt) transaction do + # merge dates + self.dates ||= [] + another_tt.included_days.each do |d| + add_included_day d + end + # if one tt has no period, just merge lists if self.periods.empty? || another_tt.periods.empty? if !another_tt.periods.empty? # copy periods self.periods = another_tt.clone_periods end - # merge dates - self.dates ||= [] - another_tt.included_days.each do |d| - add_included_day d - end else # check if periods can be kept common_day_types = self.int_day_types & another_tt.int_day_types & 508 diff --git a/app/models/clean_up.rb b/app/models/clean_up.rb index a2b150ecc..978cc7ecb 100644 --- a/app/models/clean_up.rb +++ b/app/models/clean_up.rb @@ -31,21 +31,21 @@ class CleanUp < ActiveRecord::Base end def destroy_time_tables_before - time_tables = Chouette::TimeTable.where('end_date <= ?', self.begin_date) + time_tables = Chouette::TimeTable.where('end_date < ?', self.begin_date) self.destroy_time_tables(time_tables) end def destroy_time_tables_after - time_tables = Chouette::TimeTable.where('start_date >= ?', self.begin_date) + time_tables = Chouette::TimeTable.where('start_date > ?', self.begin_date) self.destroy_time_tables(time_tables) end def destroy_time_table_dates_before - Chouette::TimeTableDate.in_dates.where('date <= ?', self.begin_date).destroy_all + Chouette::TimeTableDate.in_dates.where('date < ?', self.begin_date).destroy_all end def destroy_time_tables_dates_after - Chouette::TimeTableDate.in_dates.where('date >= ?', self.begin_date).destroy_all + Chouette::TimeTableDate.in_dates.where('date > ?', self.begin_date).destroy_all end def destroy_time_tables_dates_between @@ -53,11 +53,11 @@ class CleanUp < ActiveRecord::Base end def destroy_time_tables_periods_before - Chouette::TimeTablePeriod.where('period_end <= ?', self.begin_date).destroy_all + Chouette::TimeTablePeriod.where('period_end < ?', self.begin_date).destroy_all end def destroy_time_tables_periods_after - Chouette::TimeTablePeriod.where('period_start >= ?', self.begin_date).destroy_all + Chouette::TimeTablePeriod.where('period_start > ?', self.begin_date).destroy_all end def destroy_time_tables_periods_between diff --git a/app/views/routing_constraint_zones/_form.html.slim b/app/views/routing_constraint_zones/_form.html.slim index 082e8f7f8..3d4764ef7 100644 --- a/app/views/routing_constraint_zones/_form.html.slim +++ b/app/views/routing_constraint_zones/_form.html.slim @@ -3,12 +3,23 @@ .row .col-lg-12 = form.input :name - = form.input :route_id, collection: @line.routes.select { |route| route.stop_points.count > 2 }, include_blank: false - - stop_points_collection = @routing_constraint_zone.persisted? ? @routing_constraint_zone.route.stop_points : [] - = form.input :stop_point_ids, as: :select, collection: stop_points_collection, selected: @routing_constraint_zone.stop_point_ids, label: Chouette::StopPoint.model_name.human.pluralize.capitalize, label_method: :name, input_html: { 'data-select2ed': 'true', 'data-select2ed-placeholder': 'Sélection des arrêts sur séquence d\'arrêts', 'multiple': 'multiple', style: 'width: 100%' } + .separator - = form.button :submit, t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'itl_form' + #ITL_stoppoints + .subform + .nested-head + .wrapper + div + .form-group + label.control-label Arrêt + div + .form-group + label.control-label Commune + div = hidden_field_tag 'stop_point_ids', @routing_constraint_zone.stop_point_ids.to_s, id: 'stop_point_ids' + + + = form.button :submit, t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'itl_form' diff --git a/config/locales/routing_constraint_zones.en.yml b/config/locales/routing_constraint_zones.en.yml index 8e9dbfb02..59d4484a8 100644 --- a/config/locales/routing_constraint_zones.en.yml +++ b/config/locales/routing_constraint_zones.en.yml @@ -12,6 +12,7 @@ en: objectid: Object ID stop_points_count: Number of stop points route: Associated route + route_id: Associated route errors: models: routing_constraint_zone: diff --git a/config/locales/routing_constraint_zones.fr.yml b/config/locales/routing_constraint_zones.fr.yml index 3e207fac0..4faff6606 100644 --- a/config/locales/routing_constraint_zones.fr.yml +++ b/config/locales/routing_constraint_zones.fr.yml @@ -12,6 +12,7 @@ fr: objectid: Object ID stop_points_count: Nombre d'arrêts route: Itinéraire associé + route_id: Itinéraire associé errors: models: routing_constraint_zone: diff --git a/spec/controllers/route_stop_points_controller_spec.rb b/spec/controllers/route_stop_points_controller_spec.rb index 2f5fa41c7..ac9e2f11b 100644 --- a/spec/controllers/route_stop_points_controller_spec.rb +++ b/spec/controllers/route_stop_points_controller_spec.rb @@ -15,9 +15,7 @@ RSpec.describe RouteStopPointsController, type: :controller do end it 'returns a JSON of stop areas' do - expect(response.body).to eq(route.stop_points.map { |sp| { id: sp.id, name: sp.name } }.to_json) + expect(response.body).to eq(route.stop_points.map { |sp| { id: sp.id, stop_area_id: sp.stop_area.id, name: sp.name, zip_code: sp.stop_area.zip_code, city_name: sp.stop_area.city_name } }.to_json) end end end - - diff --git a/spec/models/chouette/time_table_spec.rb b/spec/models/chouette/time_table_spec.rb index 1e5972c04..7a8863cb3 100644 --- a/spec/models/chouette/time_table_spec.rb +++ b/spec/models/chouette/time_table_spec.rb @@ -1,12 +1,21 @@ require 'spec_helper' describe Chouette::TimeTable, :type => :model do - subject { create(:time_table) } it { is_expected.to validate_presence_of :comment } it { is_expected.to validate_uniqueness_of :objectid } + context "merge with calendar" do + let(:calendar) { create(:calendar) } + + it 'should add calendar dates to time_table' do + subject.dates.clear + subject.merge!(calendar.convert_to_time_table) + expect(subject.dates.map(&:date)).to include(*calendar.dates) + end + end + describe "actualize" do let(:calendar) { create(:calendar) } let(:int_day_types) { 508 } diff --git a/spec/models/clean_up_spec.rb b/spec/models/clean_up_spec.rb index b4cf5e1af..4b1bf4da9 100644 --- a/spec/models/clean_up_spec.rb +++ b/spec/models/clean_up_spec.rb @@ -146,7 +146,7 @@ RSpec.describe CleanUp, :type => :model do let(:cleaner) { create(:clean_up, date_type: :after, begin_date: time_table_date.date) } it 'should destroy record' do - count = Chouette::TimeTableDate.where('date >= ?', cleaner.begin_date).count + count = Chouette::TimeTableDate.where('date > ?', cleaner.begin_date).count expect{ cleaner.destroy_time_tables_dates_after }.to change { Chouette::TimeTableDate.count }.by(-count) @@ -173,9 +173,9 @@ RSpec.describe CleanUp, :type => :model do context '#destroy_time_tables_after' do let!(:time_table) { create(:time_table ) } - let(:cleaner) { create(:clean_up, date_type: :after, begin_date: time_table.start_date) } + let(:cleaner) { create(:clean_up, date_type: :after, begin_date: time_table.start_date - 1.day) } - it 'should destroy time_tables with start_date >= purge begin_date' do + it 'should destroy time_tables with start_date > purge begin_date' do expect{ cleaner.destroy_time_tables_after }.to change { Chouette::TimeTable.count }.by(-1) @@ -209,9 +209,9 @@ RSpec.describe CleanUp, :type => :model do context '#destroy_time_tables_before' do let!(:time_table) { create(:time_table ) } - let(:cleaner) { create(:clean_up, date_type: :before, begin_date: time_table.end_date) } + let(:cleaner) { create(:clean_up, date_type: :before, begin_date: time_table.end_date + 1.day) } - it 'should destroy time_tables with end_date <= purge begin_date' do + it 'should destroy time_tables with end_date < purge begin_date' do expect{ cleaner.destroy_time_tables_before }.to change { Chouette::TimeTable.count }.by(-1) |
