diff options
72 files changed, 348 insertions, 166 deletions
| diff --git a/app/assets/stylesheets/components/_pagination.sass b/app/assets/stylesheets/components/_pagination.sass index 88ba61c3c..b811a559c 100644 --- a/app/assets/stylesheets/components/_pagination.sass +++ b/app/assets/stylesheets/components/_pagination.sass @@ -7,6 +7,9 @@    border-radius: 0    line-height: 34px +  &:first-letter +    text-transform: capitalize +    .page_links      display: inline-block      vertical-align: top diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index c4961123d..9a83394e2 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -36,12 +36,6 @@ class ApplicationController < ActionController::Base    end    helper_method :current_organisation -  def current_functional_scope -    functional_scope = current_organisation.sso_attributes.try(:[], "functional_scope") if current_organisation -    JSON.parse(functional_scope) if functional_scope -  end -  helper_method :current_functional_scope -    def collection_name      self.class.name.split("::").last.gsub('Controller', '').underscore    end diff --git a/app/controllers/calendars_controller.rb b/app/controllers/calendars_controller.rb index 3d88e4910..adb3b4764 100644 --- a/app/controllers/calendars_controller.rb +++ b/app/controllers/calendars_controller.rb @@ -104,6 +104,10 @@ class CalendarsController < ChouetteController      end    end +   def begin_of_association_chain +    current_organisation +  end +    def ransack_contains_date      date =[]      if params[:q] && !params[:q]['contains_date(1i)'].empty? diff --git a/app/controllers/compliance_control_blocks_controller.rb b/app/controllers/compliance_control_blocks_controller.rb index 9eee8dfaf..b5ba2d65d 100644 --- a/app/controllers/compliance_control_blocks_controller.rb +++ b/app/controllers/compliance_control_blocks_controller.rb @@ -4,6 +4,14 @@ class ComplianceControlBlocksController < ChouetteController    belongs_to :compliance_control_set    actions :all, :except => [:show, :index] +  after_action :display_errors, only: [:create, :update] + +  def display_errors +    unless @compliance_control_block.errors[:condition_attributes].empty? +      flash[:error] = @compliance_control_block.errors[:condition_attributes].join(', ') +    end +  end +    private    def compliance_control_block_params diff --git a/app/controllers/compliance_controls_controller.rb b/app/controllers/compliance_controls_controller.rb index 73dc18f59..7df922d01 100644 --- a/app/controllers/compliance_controls_controller.rb +++ b/app/controllers/compliance_controls_controller.rb @@ -5,7 +5,7 @@ class ComplianceControlsController < ChouetteController    actions :all, :except => [:index]    def select_type -    @sti_subclasses = ComplianceControl.subclasses +    @sti_subclasses = ComplianceControl.subclasses.sort_by {|compliance_control| compliance_control.default_code}    end    def show diff --git a/app/controllers/referentials_controller.rb b/app/controllers/referentials_controller.rb index 6e3694547..fe661651e 100644 --- a/app/controllers/referentials_controller.rb +++ b/app/controllers/referentials_controller.rb @@ -143,7 +143,7 @@ class ReferentialsController < ChouetteController    def build_referential      if params[:from]        source_referential = Referential.find(params[:from]) -      @referential = Referential.new_from(source_referential, current_functional_scope) +      @referential = Referential.new_from(source_referential, current_organisation)      end      @referential.data_format = current_organisation.data_format diff --git a/app/javascript/journey_patterns/components/ConfirmModal.js b/app/javascript/journey_patterns/components/ConfirmModal.js index ccd0a9384..fdf32649f 100644 --- a/app/javascript/journey_patterns/components/ConfirmModal.js +++ b/app/javascript/journey_patterns/components/ConfirmModal.js @@ -9,11 +9,11 @@ export default function ConfirmModal({dispatch, modal, onModalAccept, onModalCan          <div className='modal-dialog'>            <div className='modal-content'>              <div className='modal-header'> -              <h4 className='modal-title'>Confirmation</h4> +              <h4 className='modal-title'>{I18n.t('journey_patterns.show.confirmation')}</h4>              </div>              <div className='modal-body'>                <div className='mt-md mb-md'> -                <p>Vous vous apprêtez à changer de page. Voulez-vous valider vos modifications avant cela ?</p> +                <p>{I18n.t('journey_patterns.show.confirm_page_change')}</p>                </div>              </div>              <div className='modal-footer'> @@ -23,7 +23,7 @@ export default function ConfirmModal({dispatch, modal, onModalAccept, onModalCan                  type='button'                  onClick={() => { onModalCancel(modal.confirmModal.callback) }}                > -                Ne pas valider +                {I18n.t('cancel')}              </button>                <button                  className='btn btn-primary' @@ -31,7 +31,7 @@ export default function ConfirmModal({dispatch, modal, onModalAccept, onModalCan                  type='button'                  onClick={() => { onModalAccept(modal.confirmModal.callback, journeyPatterns) }}                > -                Valider +                {I18n.t('actions.submit')}              </button>              </div>            </div> diff --git a/app/javascript/journey_patterns/components/CreateModal.js b/app/javascript/journey_patterns/components/CreateModal.js index a6c1b608a..36b5740dc 100644 --- a/app/javascript/journey_patterns/components/CreateModal.js +++ b/app/javascript/journey_patterns/components/CreateModal.js @@ -38,14 +38,14 @@ export default class CreateModal extends Component {                    <div className='modal-dialog'>                      <div className='modal-content'>                        <div className='modal-header'> -                        <h4 className='modal-title'>Ajouter une mission</h4> +                        <h4 className='modal-title'>{I18n.t('journey_patterns.actions.new')}</h4>                        </div>                        {(this.props.modal.type == 'create') && (                          <form>                            <div className='modal-body'>                              <div className='form-group'> -                              <label className='control-label is-required'>Nom</label> +                              <label className='control-label is-required'>{I18n.attribute_name('journey_pattern', 'name')}</label>                                <input                                  type='text'                                  ref='name' @@ -57,7 +57,7 @@ export default class CreateModal extends Component {                              <div className='row'>                                <div className='col-lg-6 col-md-6 col-sm-6 col-xs-6'>                                  <div className='form-group'> -                                  <label className='control-label is-required'>Nom public</label> +                                  <label className='control-label is-required'>{I18n.attribute_name('journey_pattern', 'published_name')}c</label>                                    <input                                      type='text'                                      ref='published_name' @@ -69,7 +69,7 @@ export default class CreateModal extends Component {                                </div>                                <div className='col-lg-6 col-md-6 col-sm-6 col-xs-6'>                                  <div className='form-group'> -                                  <label className='control-label'>Code mission</label> +                                  <label className='control-label'>{I18n.attribute_name('journey_pattern', 'registration_number')}</label>                                    <input                                      type='text'                                      ref='registration_number' @@ -87,14 +87,14 @@ export default class CreateModal extends Component {                                type='button'                                onClick={this.props.onModalClose}                                > -                              Annuler +                              {I18n.t('cancel')}                              </button>                              <button                                className='btn btn-primary'                                type='button'                                onClick={this.handleSubmit.bind(this)}                                > -                              Valider +                              {I18n.t('actions.submit')}                              </button>                            </div>                          </form> diff --git a/app/javascript/journey_patterns/components/EditModal.js b/app/javascript/journey_patterns/components/EditModal.js index c960cb41c..1960849fb 100644 --- a/app/javascript/journey_patterns/components/EditModal.js +++ b/app/javascript/journey_patterns/components/EditModal.js @@ -18,12 +18,12 @@ export default class EditModal extends Component {      if (this.props.editMode) {        return (          <h4 className='modal-title'> -          Editer la mission +          {I18n.t('journey_patterns.actions.edit')}            {this.props.modal.type == 'edit' && <em> "{this.props.modal.modalProps.journeyPattern.name}"</em>}          </h4>        )      } else { -      return <h4 className='modal-title'> Informations </h4> +      return <h4 className='modal-title'> {I18n.t('journey_patterns.show.informations')} </h4>      }    } @@ -41,7 +41,7 @@ export default class EditModal extends Component {                  <form>                    <div className='modal-body'>                      <div className='form-group'> -                      <label className='control-label is-required'>Nom</label> +                      <label className='control-label is-required'>{I18n.attribute_name('journey_pattern', 'name')}</label>                        <input                          type='text'                          ref='name' @@ -57,7 +57,7 @@ export default class EditModal extends Component {                      <div className='row'>                        <div className='col-lg-6 col-md-6 col-sm-6 col-xs-6'>                          <div className='form-group'> -                          <label className='control-label is-required'>Nom public</label> +                          <label className='control-label is-required'>{I18n.attribute_name('journey_pattern', 'published_name')}</label>                            <input                              type='text'                              ref='published_name' @@ -72,7 +72,7 @@ export default class EditModal extends Component {                        </div>                        <div className='col-lg-6 col-md-6 col-sm-6 col-xs-6'>                          <div className='form-group'> -                          <label className='control-label'>Code mission</label> +                          <label className='control-label'>{I18n.attribute_name('journey_pattern', 'registration_number')}</label>                            <input                              type='text'                              ref='registration_number' @@ -86,7 +86,7 @@ export default class EditModal extends Component {                        </div>                      </div>                      <div> -                      <label className='control-label'>Signature métier</label> +                      <label className='control-label'>{I18n.attribute_name('journey_pattern', 'checksum')}</label>                          <input                          type='text'                          ref='checksum' @@ -105,14 +105,14 @@ export default class EditModal extends Component {                          type='button'                          onClick={this.props.onModalClose}                        > -                        Annuler +                        {I18n.t('cancel')}                        </button>                        <button                          className='btn btn-primary'                          type='button'                          onClick={this.handleSubmit.bind(this)}                        > -                        Valider +                        {I18n.t('actions.submit')}                        </button>                      </div>                    } diff --git a/app/javascript/journey_patterns/components/JourneyPattern.js b/app/javascript/journey_patterns/components/JourneyPattern.js index 00b5497f7..d381b0d50 100644 --- a/app/javascript/journey_patterns/components/JourneyPattern.js +++ b/app/javascript/journey_patterns/components/JourneyPattern.js @@ -23,7 +23,7 @@ export default class JourneyPattern extends Component{      let vjURL = routeURL + '/vehicle_journeys?jp=' + jpOid      return ( -      <a href={vjURL}>Horaires des courses</a> +      <a href={vjURL}>{I18n.t('journey_patterns.journey_pattern.vehicle_journey_at_stops')}</a>      )    } @@ -139,7 +139,7 @@ export default class JourneyPattern extends Component{          <div className='th'>            <div className='strong mb-xs'>{this.props.value.object_id ? this.props.value.short_id : '-'}</div>            <div>{this.props.value.registration_number}</div> -          <div>{actions.getChecked(this.props.value.stop_points).length} arrêt(s)</div> +          <div>{I18n.t('journey_patterns.show.stop_points_count', {count: actions.getChecked(this.props.value.stop_points).length})}</div>            {this.hasFeature('costs_in_journey_patterns') &&              <div className="small row totals">                <span className="col-md-6"><i className="fa fa-arrows-h"></i>{totalDistance}</span> @@ -167,7 +167,7 @@ export default class JourneyPattern extends Component{                    data-toggle='modal'                    data-target='#JourneyPatternModal'                    > -                  {this.props.editMode ? 'Editer' : 'Consulter'} +                  {this.props.editMode ? I18n.t('actions.edit') : I18n.t('actions.show')}                  </button>                </li>                <li className={this.props.value.object_id ? '' : 'disabled'}> @@ -183,7 +183,7 @@ export default class JourneyPattern extends Component{                      this.props.onDeleteJourneyPattern(this.props.index)}                    }                    > -                    <span className='fa fa-trash'></span>Supprimer +                    <span className='fa fa-trash'></span>{I18n.t('actions.destroy')}                    </button>                  </li>                </ul> diff --git a/app/javascript/journey_patterns/components/JourneyPatterns.js b/app/javascript/journey_patterns/components/JourneyPatterns.js index 930acb390..91c783189 100644 --- a/app/javascript/journey_patterns/components/JourneyPatterns.js +++ b/app/javascript/journey_patterns/components/JourneyPatterns.js @@ -84,14 +84,14 @@ export default class JourneyPatterns extends Component {            <div className='col-lg-12'>              {(this.props.status.fetchSuccess == false) && (                <div className="alert alert-danger mt-sm"> -                <strong>Erreur : </strong> -                la récupération des missions a rencontré un problème. Rechargez la page pour tenter de corriger le problème +                <strong>{I18n.t('error')} : </strong> +                {I18n.t('journeys_patterns.journey_pattern.fetching_error')}                </div>              )}              { _.some(this.props.journeyPatterns, 'errors') && (                <div className="alert alert-danger mt-sm"> -                <strong>Erreur : </strong> +                <strong> {I18n.t('error')} : </strong>                  {this.props.journeyPatterns.map((jp, index) =>                    jp.errors && jp.errors.map((err, i) => {                      return ( @@ -107,9 +107,9 @@ export default class JourneyPatterns extends Component {              <div className={'table table-2entries mt-sm mb-sm' + ((this.props.journeyPatterns.length > 0) ? '' : ' no_result')}>                <div className='t2e-head w20'>                  <div className='th'> -                  <div className='strong mb-xs'>ID Mission</div> -                  <div>Code mission</div> -                  <div>Nb arrêts</div> +                  <div className='strong mb-xs'>{I18n.t('objectid')}</div> +                  <div>{I18n.attribute_name('journey_pattern', 'registration_number')}</div> +                  <div>{I18n.attribute_name('journey_pattern', 'stop_points')}</div>                    { this.hasFeature('costs_in_journey_patterns') &&                       <div>                         <div>{I18n.attribute_name('journey_pattern', 'full_journey_time')}</div> diff --git a/app/javascript/journey_patterns/components/Navigate.js b/app/javascript/journey_patterns/components/Navigate.js index 78f324a7d..9e454da5e 100644 --- a/app/javascript/journey_patterns/components/Navigate.js +++ b/app/javascript/journey_patterns/components/Navigate.js @@ -1,5 +1,6 @@  import React, { Component } from 'react'  import PropTypes from 'prop-types' +import capitalize from 'lodash/capitalize'  import actions from '../actions'  export default function Navigate({ dispatch, journeyPatterns, pagination, status }) { @@ -17,7 +18,7 @@ export default function Navigate({ dispatch, journeyPatterns, pagination, status        <div className='row'>          <div className='col-lg-12 text-right'>            <div className='pagination'> -            Liste des missions {firstItemOnPage} à {(lastItemOnPage < pagination.totalCount) ? lastItemOnPage : pagination.totalCount} sur {pagination.totalCount} +            {I18n.t('will_paginate.page_entries_info.multi_page', { model: capitalize(I18n.model_name('journey_pattern', { plural: true })), from: firstItemOnPage, to: lastItemOnPage, count: pagination.totalCount})}              <form className='page_links' onSubmit={e => {                  e.preventDefault()                }}> diff --git a/app/javascript/vehicle_journeys/components/ConfirmModal.js b/app/javascript/vehicle_journeys/components/ConfirmModal.js index 75e8a3932..330b4e02f 100644 --- a/app/javascript/vehicle_journeys/components/ConfirmModal.js +++ b/app/javascript/vehicle_journeys/components/ConfirmModal.js @@ -16,7 +16,7 @@ export default function ConfirmModal({dispatch, modal, onModalAccept, onModalCan                type='button'                onClick={() => { onModalCancel(modal.confirmModal.callback) }}              > -              Ne pas valider +              {I18n.t('cancel')}            </button>              <button                className='btn btn-danger' @@ -24,7 +24,7 @@ export default function ConfirmModal({dispatch, modal, onModalAccept, onModalCan                type='button'                onClick={() => { onModalAccept(modal.confirmModal.callback, vehicleJourneys) }}              > -              Valider +              {I18n.t('actions.submit')}            </button>            </div>          </div> diff --git a/app/javascript/vehicle_journeys/components/Navigate.js b/app/javascript/vehicle_journeys/components/Navigate.js index 24843babc..e79823e49 100644 --- a/app/javascript/vehicle_journeys/components/Navigate.js +++ b/app/javascript/vehicle_journeys/components/Navigate.js @@ -1,5 +1,6 @@  import React, { Component } from 'react'  import PropTypes from 'prop-types' +import capitalize from 'lodash/capitalize'  import actions from'../actions'  export default function Navigate({ dispatch, vehicleJourneys, pagination, status, filters}) { @@ -17,7 +18,7 @@ export default function Navigate({ dispatch, vehicleJourneys, pagination, status    if(status.fetchSuccess == true) {      return (        <div className="pagination"> -        {I18n.t("vehicle_journeys.vehicle_journeys_matrix.pagination", {minVJ, maxVJ, total:pagination.totalCount})} +        {I18n.t('will_paginate.page_entries_info.multi_page', { model: capitalize(I18n.model_name('vehicle_journey', { plural: true })), from: minVJ, to: maxVJ, count: pagination.totalCount })}          <form className='page_links' onSubmit={e => {e.preventDefault()}}>            <button              onClick={e => { diff --git a/app/javascript/vehicle_journeys/components/tools/CreateModal.js b/app/javascript/vehicle_journeys/components/tools/CreateModal.js index a60429765..f49b51f08 100644 --- a/app/javascript/vehicle_journeys/components/tools/CreateModal.js +++ b/app/javascript/vehicle_journeys/components/tools/CreateModal.js @@ -47,7 +47,7 @@ export default class CreateModal extends Component {                <div className='modal-dialog'>                  <div className='modal-content'>                    <div className='modal-header'> -                    <h4 className='modal-title'>Ajouter une course</h4> +                    <h4 className='modal-title'>{I18n.t('vehicle_journeys.actions.new')}</h4>                      <span type="button" className="close modal-close" data-dismiss="modal">×</span>                    </div> @@ -57,7 +57,7 @@ export default class CreateModal extends Component {                          <div className='row'>                            <div className='col-lg-6 col-md-6 col-sm-6 col-xs-12'>                              <div className='form-group'> -                              <label className='control-label'>Nom de la course</label> +                              <label className='control-label'>{I18n.attribute_name('vehicle_journey', 'journey_name')}</label>                                <input                                  type='text'                                  ref='published_journey_name' @@ -68,7 +68,7 @@ export default class CreateModal extends Component {                            </div>                            <div className='col-lg-6 col-md-6 col-sm-6 col-xs-12'>                              <div className='form-group'> -                              <label className='control-label'>Nom du transporteur</label> +                              <label className='control-label'>{I18n.attribute_name('vehicle_journey', 'company_name')}</label>                                <CompanySelect2                                  company = {this.props.modal.modalProps.vehicleJourney && this.props.modal.modalProps.vehicleJourney.company || undefined}                                  onSelect2Company = {(e) => this.props.onSelect2Company(e)} @@ -78,7 +78,7 @@ export default class CreateModal extends Component {                            </div>                            <div className='col-lg-6 col-md-6 col-sm-6 col-xs-12'>                              <div className='form-group'> -                              <label className='control-label is-required'>Nom public de la mission</label> +                              <label className='control-label is-required'>{I18n.attribute_name('vehicle_journey', 'journey_pattern_published_name')}</label>                                <MissionSelect2                                  selection={this.props.modal.modalProps}                                  onSelect2JourneyPattern={this.props.onSelect2JourneyPattern} @@ -89,7 +89,7 @@ export default class CreateModal extends Component {                            </div>                            <div className='col-lg-6 col-md-6 col-sm-6 col-xs-12'>                              <div className='form-group'> -                              <label className='control-label'>Numéro de train</label> +                              <label className='control-label'>{I18n.attribute_name('vehicle_journey', 'published_journey_identifier')}</label>                                <input                                  type='text'                                  ref='published_journey_identifier' @@ -105,7 +105,7 @@ export default class CreateModal extends Component {                            />                            { 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> +                              <label className='control-label'>{I18n.attribute_name('vehicle_journey', 'start_time')}</label>                                  <div className='input-group time'>                                    <input                                      type='number' @@ -142,14 +142,14 @@ export default class CreateModal extends Component {                            type='button'                            onClick={this.props.onModalClose}                            > -                          Annuler +                          {I18n.t('cancel')}                          </button>                          <button                            className='btn btn-primary'                            type='button'                            onClick={this.handleSubmit.bind(this)}                            > -                          Valider +                          {I18n.t('actions.submit')}                          </button>                        </div>                      </form> diff --git a/app/javascript/vehicle_journeys/components/tools/DeleteVehicleJourneys.js b/app/javascript/vehicle_journeys/components/tools/DeleteVehicleJourneys.js index 4815003d3..b1ce3786b 100644 --- a/app/javascript/vehicle_journeys/components/tools/DeleteVehicleJourneys.js +++ b/app/javascript/vehicle_journeys/components/tools/DeleteVehicleJourneys.js @@ -13,7 +13,7 @@ export default function DeleteVehicleJourneys({onDeleteVehicleJourneys, vehicleJ            e.preventDefault()            onDeleteVehicleJourneys()          }} -        title='Supprimer' +        title={ I18n.t('actions.delete') }        >          <span className='fa fa-trash'></span>        </button> diff --git a/app/javascript/vehicle_journeys/components/tools/DuplicateVehicleJourney.js b/app/javascript/vehicle_journeys/components/tools/DuplicateVehicleJourney.js index 102a87d85..d7e48bf08 100644 --- a/app/javascript/vehicle_journeys/components/tools/DuplicateVehicleJourney.js +++ b/app/javascript/vehicle_journeys/components/tools/DuplicateVehicleJourney.js @@ -93,7 +93,7 @@ export default class DuplicateVehicleJourney extends Component {                  <div className='modal-content'>                    <div className='modal-header'>                      <h4 className='modal-title'> -                      Dupliquer { actions.getSelected(this.props.vehicleJourneys).length > 1 ? 'plusieurs courses' : 'une course' } +                      {I18n.t('vehicle_journeys.vehicle_journeys_matrix.duplicate', { count: actions.getSelected(this.props.vehicleJourneys).length })}                      </h4>                      <span type="button" className="close modal-close" data-dismiss="modal">×</span>                    </div> @@ -102,7 +102,7 @@ export default class DuplicateVehicleJourney extends Component {                      <form className='form-horizontal'>                        <div className='modal-body'>                          <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> +                          <label className='control-label is-required col-sm-8'>{I18n.t('vehicle_journeys.vehicle_journeys_matrix.duplicate.start_time')}</label>                            <span className="col-sm-4">                              <span className={'input-group time' + (actions.getSelected(this.props.vehicleJourneys).length > 1 ? ' disabled' : '')}>                                <input @@ -133,7 +133,7 @@ export default class DuplicateVehicleJourney extends Component {                          </div>                          <div className='form-group'> -                          <label className='control-label is-required col-sm-8'>Nombre de courses à créer et dupliquer</label> +                          <label className='control-label is-required col-sm-8'>{I18n.t('vehicle_journeys.vehicle_journeys_matrix.duplicate.number')}</label>                            <div className="col-sm-4">                              <input                                type='number' @@ -152,7 +152,7 @@ export default class DuplicateVehicleJourney extends Component {                          </div>                          <div className='form-group'> -                          <label className='control-label is-required col-sm-8'>Décalage à partir duquel on créé les courses</label> +                          <label className='control-label is-required col-sm-8'>{I18n.t('vehicle_journeys.vehicle_journeys_matrix.duplicate.delta')}</label>                            <span className="col-sm-4">                              <input                                type='number' @@ -178,7 +178,7 @@ export default class DuplicateVehicleJourney extends Component {                            type='button'                            onClick={this.props.onModalClose}                            > -                          Annuler +                          {I18n.t('cancel')}                          </button>                          <button                            className={'btn btn-primary ' + (this.state.additional_time == 0 && this.state.originalDT.hour == this.state.duplicate_time_hh && this.state.originalDT.minute == this.state.duplicate_time_mm ? 'disabled' : '')} @@ -186,7 +186,7 @@ export default class DuplicateVehicleJourney extends Component {                            onClick={this.handleSubmit}                            disabled={this.disableValidateButton()}                            > -                          Valider +                          {I18n.t('actions.submit')}                          </button>                        </div>                      </form> diff --git a/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js b/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js index 795c2ecff..e4e266c79 100644 --- a/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js +++ b/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js @@ -173,14 +173,14 @@ export default class EditVehicleJourney extends Component {                              type='button'                              onClick={this.props.onModalClose}                            > -                            Annuler +                            {I18n.t('cancel')}                          </button>                            <button                              className='btn btn-primary'                              type='button'                              onClick={this.handleSubmit.bind(this)}                            > -                            Valider +                            {I18n.t('actions.submit')}                          </button>                          </div>                        } diff --git a/app/javascript/vehicle_journeys/components/tools/NotesEditVehicleJourney.js b/app/javascript/vehicle_journeys/components/tools/NotesEditVehicleJourney.js index 880542216..5d300f70c 100644 --- a/app/javascript/vehicle_journeys/components/tools/NotesEditVehicleJourney.js +++ b/app/javascript/vehicle_journeys/components/tools/NotesEditVehicleJourney.js @@ -43,11 +43,11 @@ export default class NotesEditVehicleJourney extends Component {    renderAssociatedFN() {      if (this.footnotes().associated.length == 0) { -      return <h3>Aucune note associée</h3> +      return <h3>{I18n.t('vehicle_journeys.vehicle_journeys_matrix.no_associated_footnotes')}</h3>      } else {        return (          <div> -          <h3>Notes associées :</h3> +          <h3>{I18n.t('vehicle_journeys.form.purchase_windows')} :</h3>            {this.footnotes().associated.map((lf, i) =>              <div                key={i} @@ -68,13 +68,13 @@ export default class NotesEditVehicleJourney extends Component {    }    renderToAssociateFN() { -    if (window.line_footnotes.length == 0) return <h3>La ligne ne possède pas de notes</h3> +    if (window.line_footnotes.length == 0) return <h3>{I18n.t('vehicle_journeys.vehicle_journeys_matrix.no_line_footnotes')}</h3>      if (this.footnotes().to_associate.length == 0) return false      return (        <div> -        <h3 className='mt-lg'>Sélectionnez les notes à associer à cette course :</h3> +        <h3 className='mt-lg'>{I18n.t('vehicle_journeys.vehicle_journeys_matrix.select_footnotes')} :</h3>          {this.footnotes().to_associate.map((lf, i) =>            <div key={i} className='panel panel-default'>              <div className='panel-heading'> @@ -111,7 +111,7 @@ export default class NotesEditVehicleJourney extends Component {                <div className='modal-dialog'>                  <div className='modal-content'>                    <div className='modal-header'> -                    <h4 className='modal-title'>Notes</h4> +                    <h4 className='modal-title'>{I18n.t('vehicle_journeys.form.footnotes')}</h4>                      <span type="button" className="close modal-close" data-dismiss="modal">×</span>                    </div> @@ -130,14 +130,14 @@ export default class NotesEditVehicleJourney extends Component {                              type='button'                              onClick={this.props.onModalClose}                            > -                            Annuler +                            {I18n.t('cancel')}                          </button>                            <button                              className='btn btn-primary'                              type='button'                              onClick={this.handleSubmit.bind(this)}                            > -                            Valider +                            {I18n.t('actions.submit')}                          </button>                          </div>                        } diff --git a/app/javascript/vehicle_journeys/components/tools/PurchaseWindowsEditVehicleJourney.js b/app/javascript/vehicle_journeys/components/tools/PurchaseWindowsEditVehicleJourney.js index ce9a4cde9..30c511302 100644 --- a/app/javascript/vehicle_journeys/components/tools/PurchaseWindowsEditVehicleJourney.js +++ b/app/javascript/vehicle_journeys/components/tools/PurchaseWindowsEditVehicleJourney.js @@ -44,7 +44,7 @@ export default class PurchaseWindowsEditVehicleJourney extends Component {                <div className='modal-dialog'>                  <div className='modal-content'>                    <div className='modal-header'> -                    <h4 className='modal-title'>Calendriers commerciaux associés</h4> +                    <h4 className='modal-title'>{I18n.t('vehicle_journeys.form.purchase_windows')}s</h4>                      <span type="button" className="close modal-close" data-dismiss="modal">×</span>                    </div> @@ -58,7 +58,7 @@ export default class PurchaseWindowsEditVehicleJourney extends Component {                                  <div className='wrapper'>                                    <div>                                      <div className='form-group'> -                                      <label className='control-label'>{this.props.modal.modalProps.purchase_windows.length == 0 ? "Aucun calendrier commercial associé" : "Calendriers commerciaux associés"}</label> +                                      <label className='control-label'>{this.props.modal.modalProps.purchase_windows.length == 0 ? I18n.t('vehicle_journeys.vehicle_journeys_matrix.no_associated_purchase_windows') : I18n.t('vehicle_journeys.form.purchase_windows')}</label>                                      </div>                                    </div>                                    <div></div> @@ -117,14 +117,14 @@ export default class PurchaseWindowsEditVehicleJourney extends Component {                              type='button'                              onClick={this.props.onModalClose}                            > -                            Annuler +                            {I18n.t('cancel')}                            </button>                            <button                              className='btn btn-primary'                              type='button'                              onClick={this.handleSubmit}                            > -                            Valider +                            {I18n.t('actions.submit')}                            </button>                          </div>                        } diff --git a/app/javascript/vehicle_journeys/components/tools/ShiftVehicleJourney.js b/app/javascript/vehicle_journeys/components/tools/ShiftVehicleJourney.js index 6574bfa2d..bc3d8db34 100644 --- a/app/javascript/vehicle_journeys/components/tools/ShiftVehicleJourney.js +++ b/app/javascript/vehicle_journeys/components/tools/ShiftVehicleJourney.js @@ -27,6 +27,7 @@ export default class ShiftVehicleJourney extends Component {    }    render() { +    let id = this.props.modal.type == 'shift' && actions.getSelected(this.props.vehicleJourneys)[0].short_id      if(this.props.status.isFetching == true) {        return false      } @@ -48,10 +49,7 @@ export default class ShiftVehicleJourney extends Component {                <div className='modal-dialog'>                  <div className='modal-content'>                    <div className='modal-header'> -                    <h4 className='modal-title'>Mettre à jour une course</h4> -                    {(this.props.modal.type == 'shift') && ( -                      <em>Mettre à jour les horaires de la course {actions.getSelected(this.props.vehicleJourneys)[0].short_id}</em> -                    )} +                    <h4 className='modal-title'>{I18n.t('vehicle_journeys.form.slide_title', {id: id})}</h4>                      <span type="button" className="close modal-close" data-dismiss="modal">×</span>                    </div> @@ -61,7 +59,7 @@ export default class ShiftVehicleJourney extends Component {                          <div className='row'>                            <div className='col-lg-4 col-lg-offset-4 col-md-4 col-md-offset-4 col-sm-4 col-sm-offset-4 col-xs-12'>                              <div className='form-group'> -                              <label className='control-label is-required'>Avec un décalage de</label> +                              <label className='control-label is-required'>{I18n.t('vehicle_journeys.form.slide_delta')}</label>                                <input                                  type='number'                                  style={{'width': 104}} @@ -85,14 +83,14 @@ export default class ShiftVehicleJourney extends Component {                            type='button'                            onClick={this.props.onModalClose}                            > -                          Annuler +                          {I18n.t('cancel')}                          </button>                          <button                            className={'btn btn-primary ' + (this.state.additional_time == 0 ? 'disabled' : '')}                            type='button'                            onClick={this.handleSubmit.bind(this)}                            > -                          Valider +                          {I18n.t('actions.submit')}                          </button>                        </div>                      </form> diff --git a/app/javascript/vehicle_journeys/components/tools/TimetablesEditVehicleJourney.js b/app/javascript/vehicle_journeys/components/tools/TimetablesEditVehicleJourney.js index f21480563..7a2686c13 100644 --- a/app/javascript/vehicle_journeys/components/tools/TimetablesEditVehicleJourney.js +++ b/app/javascript/vehicle_journeys/components/tools/TimetablesEditVehicleJourney.js @@ -44,7 +44,7 @@ export default class TimetablesEditVehicleJourney extends Component {                <div className='modal-dialog'>                  <div className='modal-content'>                    <div className='modal-header'> -                    <h4 className='modal-title'>Calendriers associés</h4> +                    <h4 className='modal-title'>{I18n.t('vehicle_journeys.form.time_tables')}</h4>                      <span type="button" className="close modal-close" data-dismiss="modal">×</span>                    </div> @@ -58,7 +58,7 @@ export default class TimetablesEditVehicleJourney extends Component {                                  <div className='wrapper'>                                    <div>                                      <div className='form-group'> -                                      <label className='control-label'>{this.props.modal.modalProps.timetables.length == 0 ? "Aucun calendrier associé" : "Calendriers associés"}</label> +                                      <label className='control-label'>{this.props.modal.modalProps.timetables.length == 0 ? I18n.t('vehicle_journeys.vehicle_journeys_matrix.no_associated_timetables'): I18n.t('vehicle_journeys.form.timetables')}</label>                                      </div>                                    </div>                                    <div></div> @@ -119,14 +119,14 @@ export default class TimetablesEditVehicleJourney extends Component {                              type='button'                              onClick={this.props.onModalClose}                            > -                            Annuler +                            {I18n.t('cancel')}                            </button>                            <button                              className='btn btn-primary'                              type='button'                              onClick={this.handleSubmit}                            > -                            Valider +                            {I18n.t('actions.submit')}                            </button>                          </div>                        } diff --git a/app/javascript/vehicle_journeys/components/tools/select2s/CompanySelect2.js b/app/javascript/vehicle_journeys/components/tools/select2s/CompanySelect2.js index 5c7f75d99..b7e9691c1 100644 --- a/app/javascript/vehicle_journeys/components/tools/select2s/CompanySelect2.js +++ b/app/javascript/vehicle_journeys/components/tools/select2s/CompanySelect2.js @@ -16,6 +16,7 @@ export default class BSelect4 extends Component {    }    render() { +    let placeHolder = I18n.t('')      return (        <Select2          data={(this.props.company) ? [this.props.company.name] : undefined} @@ -29,7 +30,7 @@ export default class BSelect4 extends Component {            allowClear: true,            theme: 'bootstrap',            width: '100%', -          placeholder: 'Filtrer par transporteur...', +          placeholder: I18n.t('vehicle_journeys.vehicle_journeys_matrix.affect_company'),            language: require('./fr'),            ajax: {              url: origin + path + '/companies.json' + '?line_id=' + line, diff --git a/app/javascript/vehicle_journeys/components/tools/select2s/MissionSelect2.js b/app/javascript/vehicle_journeys/components/tools/select2s/MissionSelect2.js index 72dbd0152..96b34125d 100644 --- a/app/javascript/vehicle_journeys/components/tools/select2s/MissionSelect2.js +++ b/app/javascript/vehicle_journeys/components/tools/select2s/MissionSelect2.js @@ -74,7 +74,7 @@ export default class BSelect4 extends Component {        width: '100%',        escapeMarkup: function (markup) { return markup; },        templateResult: formatRepo, -      placeholder: 'Filtrer par code, nom ou OID de mission...', +      placeholder: I18n.t('vehicle_journeys.vehicle_journeys_matrix.filters.journey_pattern'),        language: require('./fr'),        allowClear: false,        escapeMarkup: function (markup) { return markup; }, diff --git a/app/javascript/vehicle_journeys/components/tools/select2s/TimetableSelect2.js b/app/javascript/vehicle_journeys/components/tools/select2s/TimetableSelect2.js index 0339455ca..9a345b464 100644 --- a/app/javascript/vehicle_journeys/components/tools/select2s/TimetableSelect2.js +++ b/app/javascript/vehicle_journeys/components/tools/select2s/TimetableSelect2.js @@ -26,7 +26,7 @@ export default class BSelect4 extends Component {            allowClear: false,            theme: 'bootstrap',            width: '100%', -          placeholder: 'Filtrer par calendrier...', +          placeholder: I18n.t('vehicle_journeys.vehicle_journeys_matrix.filters.timetable'),            language: require('./fr'),            ajax: {              url: origin + path + this.props.chunkURL, diff --git a/app/javascript/vehicle_journeys/components/tools/select2s/VJSelect2.js b/app/javascript/vehicle_journeys/components/tools/select2s/VJSelect2.js index ccb4c9595..f5881cef7 100644 --- a/app/javascript/vehicle_journeys/components/tools/select2s/VJSelect2.js +++ b/app/javascript/vehicle_journeys/components/tools/select2s/VJSelect2.js @@ -25,7 +25,7 @@ export default class BSelect4b extends Component {          options={{            allowClear: false,            theme: 'bootstrap', -          placeholder: 'Filtrer par ID course...', +          placeholder: I18n.t('vehicle_journeys.vehicle_journeys_matrix.filters.id'),            width: '100%',            language: require('./fr'),            ajax: { diff --git a/app/models/chouette/line.rb b/app/models/chouette/line.rb index ae7c25377..c8a02da1f 100644 --- a/app/models/chouette/line.rb +++ b/app/models/chouette/line.rb @@ -51,6 +51,14 @@ module Chouette          )      } +    scope :for_organisation, ->(organisation){ +      if objectids = organisation&.lines_scope +        where(objectid: objectids) +      else +        all +      end +    } +      def self.nullable_attributes        [:published_name, :number, :comment, :url, :color, :text_color, :stable_id]      end diff --git a/app/models/compliance_control.rb b/app/models/compliance_control.rb index 537343005..1cc06f927 100644 --- a/app/models/compliance_control.rb +++ b/app/models/compliance_control.rb @@ -76,6 +76,7 @@ require_dependency 'generic_attribute_control/uniqueness'  require_dependency 'journey_pattern_control/duplicates'  require_dependency 'journey_pattern_control/vehicle_journey'  require_dependency 'line_control/route' +require_dependency 'line_control/lines_scope'  require_dependency 'route_control/duplicates'  require_dependency 'route_control/journey_pattern'  require_dependency 'route_control/minimum_length' diff --git a/app/models/compliance_control_block.rb b/app/models/compliance_control_block.rb index d7d84fd06..bc5d6fd4a 100644 --- a/app/models/compliance_control_block.rb +++ b/app/models/compliance_control_block.rb @@ -12,6 +12,8 @@ class ComplianceControlBlock < ActiveRecord::Base    validates :transport_mode, presence: true    validates :compliance_control_set, presence: true +  validates_uniqueness_of :condition_attributes, scope: :compliance_control_set_id +    def name      ApplicationController.helpers.transport_mode_text(self)    end diff --git a/app/models/line_control/lines_scope.rb b/app/models/line_control/lines_scope.rb new file mode 100644 index 000000000..4210a10dd --- /dev/null +++ b/app/models/line_control/lines_scope.rb @@ -0,0 +1,8 @@ +module LineControl +  class LinesScope < ComplianceControl + +    def self.default_code; "3-Line-2" end + +    def prerequisite; I18n.t("compliance_controls.#{self.class.name.underscore}.prerequisite") end +  end +end diff --git a/app/models/line_referential.rb b/app/models/line_referential.rb index 0d2ed39b1..89700c06f 100644 --- a/app/models/line_referential.rb +++ b/app/models/line_referential.rb @@ -1,7 +1,7 @@  class LineReferential < ActiveRecord::Base    include ObjectidFormatterSupport    extend StifTransportModeEnumerations -   +    has_many :line_referential_memberships    has_many :organisations, through: :line_referential_memberships    has_many :lines, class_name: 'Chouette::Line' @@ -14,7 +14,7 @@ class LineReferential < ActiveRecord::Base    def add_member(organisation, options = {})      attributes = options.merge organisation: organisation -    line_referential_memberships.build attributes +    line_referential_memberships.build attributes unless organisations.include?(organisation)    end    validates :name, presence: true diff --git a/app/models/line_referential_membership.rb b/app/models/line_referential_membership.rb index b49d1b5b1..dcada25bf 100644 --- a/app/models/line_referential_membership.rb +++ b/app/models/line_referential_membership.rb @@ -1,4 +1,6 @@  class LineReferentialMembership < ActiveRecord::Base    belongs_to :organisation    belongs_to :line_referential + +  validates :organisation_id, presence: true, uniqueness: { scope: :line_referential }  end diff --git a/app/models/organisation.rb b/app/models/organisation.rb index 745bc0d22..5bef67941 100644 --- a/app/models/organisation.rb +++ b/app/models/organisation.rb @@ -86,4 +86,8 @@ class Organisation < ActiveRecord::Base      workbenches.default    end +  def lines_scope +    functional_scope = sso_attributes.try(:[], "functional_scope") +    JSON.parse(functional_scope) if functional_scope +  end  end diff --git a/app/models/referential.rb b/app/models/referential.rb index 91a88d02d..0e48be43f 100644 --- a/app/models/referential.rb +++ b/app/models/referential.rb @@ -233,7 +233,7 @@ class Referential < ActiveRecord::Base      end    end -  def self.new_from(from, functional_scope) +  def self.new_from(from, organisation)      Referential.new(        name: I18n.t("activerecord.copy", name: from.name),        slug: "#{from.slug}_clone", @@ -244,7 +244,7 @@ class Referential < ActiveRecord::Base        stop_area_referential: from.stop_area_referential,        created_from: from,        objectid_format: from.objectid_format, -      metadatas: from.metadatas.map { |m| ReferentialMetadata.new_from(m, functional_scope) } +      metadatas: from.metadatas.map { |m| ReferentialMetadata.new_from(m, organisation) }      )    end diff --git a/app/models/referential_metadata.rb b/app/models/referential_metadata.rb index 393dc70d3..017eb1449 100644 --- a/app/models/referential_metadata.rb +++ b/app/models/referential_metadata.rb @@ -155,10 +155,10 @@ class ReferentialMetadata < ActiveRecord::Base    end    private :clear_periods -  def self.new_from(from, functional_scope) +  def self.new_from(from, organisation)      from.dup.tap do |metadata|        metadata.referential_source_id = from.referential_id -      metadata.line_ids = from.referential.lines.where(id: metadata.line_ids, objectid: functional_scope).collect(&:id) +      metadata.line_ids = from.referential.lines.where(id: metadata.line_ids).for_organisation(organisation).pluck(:id)        metadata.referential_id = nil      end    end diff --git a/app/models/simple_exporter.rb b/app/models/simple_exporter.rb index c267b5b8c..1fcb76a29 100644 --- a/app/models/simple_exporter.rb +++ b/app/models/simple_exporter.rb @@ -64,7 +64,7 @@ class SimpleExporter < SimpleInterface    def map_item_to_rows item      return [item] unless configuration.item_to_rows_mapping -    configuration.item_to_rows_mapping.call(item).map {|row| row.is_a?(ActiveRecord::Base) ? row : CustomRow.new(row) } +    instance_exec(item, &configuration.item_to_rows_mapping).map {|row| row.is_a?(ActiveRecord::Base) ? row : CustomRow.new(row) }    end    def resolve_value item, col diff --git a/app/models/stop_area_referential.rb b/app/models/stop_area_referential.rb index a9d3cc9b1..4706cdd77 100644 --- a/app/models/stop_area_referential.rb +++ b/app/models/stop_area_referential.rb @@ -12,7 +12,7 @@ class StopAreaReferential < ActiveRecord::Base    def add_member(organisation, options = {})      attributes = options.merge organisation: organisation -    stop_area_referential_memberships.build attributes +    stop_area_referential_memberships.build attributes unless organisations.include?(organisation)    end    def last_sync diff --git a/app/models/stop_area_referential_membership.rb b/app/models/stop_area_referential_membership.rb index 435970961..fbed1c004 100644 --- a/app/models/stop_area_referential_membership.rb +++ b/app/models/stop_area_referential_membership.rb @@ -1,4 +1,6 @@  class StopAreaReferentialMembership < ActiveRecord::Base    belongs_to :organisation    belongs_to :stop_area_referential + +  validates :organisation_id, presence: true, uniqueness: { scope: :stop_area_referential }  end diff --git a/app/views/dashboards/_dashboard.html.slim b/app/views/dashboards/_dashboard.html.slim index 2f0791f50..e1be3df4a 100644 --- a/app/views/dashboards/_dashboard.html.slim +++ b/app/views/dashboards/_dashboard.html.slim @@ -5,7 +5,7 @@          .panel-heading            h3.panel-title.with_actions              div -              = link_to workbench.name, workbench_path(workbench) +              = link_to t('dashboards.workbench.title', organisation: workbench.organisation.name), workbench_path(workbench)                span.badge.ml-xs = workbench.referentials.count if workbench.referentials.present?              div @@ -23,6 +23,7 @@          .panel-heading            h3.panel-title.with_actions              = link_to I18n.t("activerecord.models.calendar", count: workbench.calendars.size), workgroup_calendars_path(workbench.workgroup) +            span.badge.ml-xs = workbench.calendars.count if workbench.calendars.present?              div                = link_to '', workgroup_calendars_path(workbench.workgroup), class: ' fa fa-chevron-right pull-right'          - if workbench.calendars.present? @@ -39,7 +40,7 @@        - @dashboard.current_organisation.stop_area_referentials.each do |referential|          .panel-heading            h3.panel-title -            = referential.name +            = t('dashboards.stop_area_referentials.title')          .list-group            = link_to Chouette::StopArea.model_name.human.pluralize.capitalize, stop_area_referential_stop_areas_path(referential), class: 'list-group-item' @@ -47,7 +48,7 @@        - @dashboard.current_organisation.line_referentials.all.each do |referential|          .panel-heading            h3.panel-title -            = referential.name +            = t('dashboards.line_referentials.title')          .list-group              = link_to Chouette::Line.model_name.human.pluralize.capitalize, line_referential_lines_path(referential), class: 'list-group-item'              = link_to Chouette::Company.model_name.human.pluralize.capitalize, line_referential_companies_path(referential), class: 'list-group-item' diff --git a/app/views/layouts/navigation/_nav_panel_operations.html.slim b/app/views/layouts/navigation/_nav_panel_operations.html.slim index 8dce829cd..1c5a1f14b 100644 --- a/app/views/layouts/navigation/_nav_panel_operations.html.slim +++ b/app/views/layouts/navigation/_nav_panel_operations.html.slim @@ -1,5 +1,5 @@  #operations_panel.nav_panel    .panel-title -    h2 Opérations +    h2 = t('layouts.operations')    .panel-body      p = "Lorem ipsum dolor sit amet..." diff --git a/app/views/layouts/navigation/_nav_panel_profile.html.slim b/app/views/layouts/navigation/_nav_panel_profile.html.slim index bcbf89e67..b0dee5d53 100644 --- a/app/views/layouts/navigation/_nav_panel_profile.html.slim +++ b/app/views/layouts/navigation/_nav_panel_profile.html.slim @@ -1,6 +1,6 @@  #profile_panel.nav_panel    .panel-title -    h2 Mon Profil +    h2 = t('layouts.user.profile')    .panel-body      p = current_user.name      p = current_organisation.name diff --git a/app/views/referentials/_form.html.slim b/app/views/referentials/_form.html.slim index 96d847ec1..c378f871e 100644 --- a/app/views/referentials/_form.html.slim +++ b/app/views/referentials/_form.html.slim @@ -49,7 +49,7 @@      .separator      .row        .col-lg-11 -        = subform.input :lines, as: :select, collection: Chouette::Line.includes(:company).order(:name).where(objectid: current_functional_scope), selected: subform.object.line_ids, label_method: :display_name, input_html: { 'data-select2ed': 'true', 'data-select2ed-placeholder': t('simple_form.labels.referential.placeholders.select_lines'), 'multiple': 'multiple', style: 'width: 100%' } +        = subform.input :lines, as: :select, collection: Chouette::Line.includes(:company).order(:name).for_organisation(current_organisation), selected: subform.object.line_ids, label_method: :display_name, input_html: { 'data-select2ed': 'true', 'data-select2ed-placeholder': t('simple_form.labels.referential.placeholders.select_lines'), 'multiple': 'multiple', style: 'width: 100%' }        .col-lg-1          a.clear-lines.btn.btn-default href='#'            .fa.fa-trash diff --git a/app/views/referentials/select_compliance_control_set.html.slim b/app/views/referentials/select_compliance_control_set.html.slim index 69c87aab2..3550bb202 100644 --- a/app/views/referentials/select_compliance_control_set.html.slim +++ b/app/views/referentials/select_compliance_control_set.html.slim @@ -1,3 +1,5 @@ +- breadcrumb @referential +  .page_content    .container-fluid      .row diff --git a/app/views/stif/dashboards/_dashboard.html.slim b/app/views/stif/dashboards/_dashboard.html.slim index e0f754fd4..7538c7fc7 100644 --- a/app/views/stif/dashboards/_dashboard.html.slim +++ b/app/views/stif/dashboards/_dashboard.html.slim @@ -1,8 +1,4 @@  .row -  .col-lg-12 -    h2.content_header = t('.subtitle') - -.row    .col-lg-6.col-md-6.col-sm-6.col-xs-12      .panel.panel-default        .panel-heading diff --git a/config/locales/compliance_check_messages.en.yml b/config/locales/compliance_check_messages.en.yml index 216a363a3..88841f308 100644 --- a/config/locales/compliance_check_messages.en.yml +++ b/config/locales/compliance_check_messages.en.yml @@ -22,10 +22,11 @@ en:      3_routingconstraint_2: "The Routing Constraint Zone %{source_objectid} covers all the stop points of its related route : %{target_0_objectid}."      3_routingconstraint_3: "The Routing Constraint Zone %{source_objectid} has less than 2 stop points"      3_line_1: "On line :%{source_label} (%{source_objectid}), no route has an opposite route" +    3_line_2: "The line %{source_label} (%{source_objectid}) is not in the lines scope of the organization %{reference_value}"      3_generic_1: "%{source_objectid} : the %{source_attribute} attribute value (%{error_value}) does not respect the following pattern : %{reference_value}"      3_generic_2_1: "%{source_objectid}  : the %{source_attribute} attributes's value (%{error_value}) is greater than the authorized maximum value : %{reference_value}"      3_generic_2_2: "%{source_objectid}  : the %{source_attribute} attributes's value (%{error_value}) is smaller than the authorized minimum value %{reference_value}"      3_generic_3: "%{source_objectid}  : the %{source_attribute} attribute (%{error_value}) has a value shared with : %{target_0_objectid}"      3_shape_1: "Tracé %{source_objectid} : le tracé passe trop loin de l'arrêt %{target_0_label} (%{target_0_objectid}) : %{error_value} > %{reference_value}"      3_shape_2: "Tracé %{source_objectid} : le tracé n'est pas défini entre les arrêts %{target_0_label} (%{target_0_objectid}) et %{target_1_label} (%{target_1_objectid})" -    3_shape_3: "Le tracé de l'itinéraire %{source_objectid} est en écart avec la voirie sur %{error_value} sections"
\ No newline at end of file +    3_shape_3: "Le tracé de l'itinéraire %{source_objectid} est en écart avec la voirie sur %{error_value} sections" diff --git a/config/locales/compliance_check_messages.fr.yml b/config/locales/compliance_check_messages.fr.yml index db127d236..167ef411a 100644 --- a/config/locales/compliance_check_messages.fr.yml +++ b/config/locales/compliance_check_messages.fr.yml @@ -22,10 +22,11 @@ fr:      3_routingconstraint_2: "L'ITL %{source_objectid} couvre tous les arrêts de l'itinéraire %{target_0_objectid}."      3_routingconstraint_3: "L'ITL %{source_objectid} n'a pas suffisament d'arrêts (minimum 2 arrêts requis)"      3_line_1: "Sur la ligne %{source_label} (%{source_objectid}), aucun itinéraire n'a d'itinéraire inverse" +    3_line_2: "La ligne %{source_label} (%{source_objectid}) ne fait pas partie du périmètre de lignes de l'organisation %{reference_value}"      3_generic_1: "%{source_objectid} : l'attribut %{source_attribute} a une valeur %{error_value} qui ne respecte pas le motif %{reference_value}"      3_generic_2_1: "%{source_objectid} : l'attribut %{source_attribute} a une valeur %{error_value} supérieure à la valeur maximale autorisée %{reference_value}"      3_generic_2_2: "%{source_objectid} : l'attribut %{source_attribute} a une valeur %{error_value} inférieure à la valeur minimale autorisée %{reference_value}"      3_generic_3: "%{source_objectid} : l'attribut %{source_attribute} a une valeur %{error_value} partagée avec %{target_0_objectid}"      3_shape_1: "Tracé %{source_objectid} : le tracé passe trop loin de l'arrêt %{target_0_label} (%{target_0_objectid}) : %{error_value} > %{reference_value}"      3_shape_2: "Tracé %{source_objectid} : le tracé n'est pas défini entre les arrêts %{target_0_label} (%{target_0_objectid}) et %{target_1_label} (%{target_1_objectid})" -    3_shape_3: "Le tracé de l'itinéraire %{source_objectid} est en écart avec la voirie sur %{error_value} sections"
\ No newline at end of file +    3_shape_3: "Le tracé de l'itinéraire %{source_objectid} est en écart avec la voirie sur %{error_value} sections" diff --git a/config/locales/compliance_control_blocks.en.yml b/config/locales/compliance_control_blocks.en.yml index 275f05106..0ec979549 100644 --- a/config/locales/compliance_control_blocks.en.yml +++ b/config/locales/compliance_control_blocks.en.yml @@ -9,6 +9,12 @@ en:        compliance_control_blocks:          transport_mode: Transport mode          sub_transport_mode: Transport submode +    errors: +      models: +        compliance_control_block: +          attributes: +            condition_attributes: +              taken: The same compliance control block already exists in this compliance control set    compliance_control_blocks:      clone:        prefix: 'Copy of' @@ -16,8 +22,12 @@ en:        destroy_confirm: Are you sure you want to destroy this block ?      new:        title: Create a control block +    create: +      title: Create a control block      edit:        title: "Edit the control block : %{name}" +    update: +      title: "Edit the control block : %{name}"      metas:        control:          zero: "No controls" diff --git a/config/locales/compliance_control_blocks.fr.yml b/config/locales/compliance_control_blocks.fr.yml index a6720881f..5ce5b4729 100644 --- a/config/locales/compliance_control_blocks.fr.yml +++ b/config/locales/compliance_control_blocks.fr.yml @@ -9,6 +9,12 @@ fr:        compliance_control_blocks:          transport_mode: Mode de transport          transport_submode: Sous-mode de transport +    errors: +      models: +        compliance_control_block: +          attributes: +            condition_attributes: +              taken: Un groupe de contrôle identique existe déjà au sein de ce jeu de contrôles    compliance_control_blocks:      clone:        prefix: 'Copie de' @@ -16,8 +22,12 @@ fr:        destroy_confirm: Etes vous sûr de supprimer ce bloc ?      new:        title: Créer un groupe de contrôle(s) +    create: +      title: Créer un groupe de contrôle(s)      edit:        title: "Editer le groupe de contrôle : %{name}" +    update: +      title: "Editer le groupe de contrôle : %{name}"      metas:        control:          zero: "Aucun contrôle" diff --git a/config/locales/compliance_controls.en.yml b/config/locales/compliance_controls.en.yml index d8dc44ecc..18069f2f7 100644 --- a/config/locales/compliance_controls.en.yml +++ b/config/locales/compliance_controls.en.yml @@ -142,6 +142,11 @@ en:          3_line_1: "On line :%{source_label} (%{source_objectid}), no route has an opposite route"        description: "The routes of a line must have an opposite route"        prerequisite: Line has multiple routes +    line_control/lines_scope: +      messages: +        3_line_2: "The line %{source_label} (%{source_objectid}) is not in the lines scope of the organization %{reference_value}" +      description: "The line must be included in the lines scope of the organization" +      prerequisite: "None"      generic_attribute_control/pattern:        messages:          3_generic_1: "%{source_objectid} : the %{source_attribute} attribute value (%{error_value}) does not respect the following pattern : %{reference_value}" @@ -209,6 +214,8 @@ en:          one: "Unactivated stop points"        line_control/route:          one: "The routes of a line must have an opposite route" +      line_control/lines_scope: +        one: "Lines must be included in the lines scope of the organization"        generic_attribute_control/pattern:          one: "Attribute pattern of an object in a line"        generic_attribute_control/min_max: diff --git a/config/locales/compliance_controls.fr.yml b/config/locales/compliance_controls.fr.yml index 78b92451f..7dc6eeeb3 100644 --- a/config/locales/compliance_controls.fr.yml +++ b/config/locales/compliance_controls.fr.yml @@ -139,6 +139,11 @@ fr:          3_line_1: "Sur la ligne %{source_label} (%{source_objectid}), aucun itinéraire n'a d'itinéraire inverse"        description: "Les itinéraires d'une ligne doivent être associés en aller/retour"        prerequisite: Ligne disposant de plusieurs itinéraires +    line_control/lines_scope: +      messages: +        3_line_2: "La ligne %{source_label} (%{source_objectid}) ne fait pas partie du périmètre de lignes de l'organisation %{reference_value}" +      description: "Les lignes doivent appartenir au périmètre de lignes de l'organisation" +      prerequisite: "Aucun"      generic_attribute_control/pattern:        messages:          3_generic_1: "%{source_objectid} : l'attribut %{source_attribute} a une valeur %{error_value} qui ne respecte pas le motif %{reference_value}" @@ -206,6 +211,8 @@ fr:          one: "ITL & arret désactivé"        line_control/route:          one: "Appariement des itinéraires" +      line_control/lines_scope: +        one: "Les lignes doivent appartenir au périmètre de lignes de l'organisation"        generic_attribute_control/pattern:          one: "Contrôle du contenu selon un pattern"        generic_attribute_control/min_max: diff --git a/config/locales/dashboard.en.yml b/config/locales/dashboard.en.yml index 8d46ff7aa..361a3cf2b 100644 --- a/config/locales/dashboard.en.yml +++ b/config/locales/dashboard.en.yml @@ -2,6 +2,8 @@ en:    dashboards:      show:        title: "Dashboard %{organisation}" +    workbench: +      title: Transport offer %{organisation}      calendars:        title: Calendars        none: No calendar created diff --git a/config/locales/dashboard.fr.yml b/config/locales/dashboard.fr.yml index d0aa36d61..1e1c095b1 100644 --- a/config/locales/dashboard.fr.yml +++ b/config/locales/dashboard.fr.yml @@ -2,6 +2,8 @@ fr:    dashboards:      show:        title: "Tableau de bord %{organisation}" +    workbench: +      title: Offre de transport %{organisation}      calendars:        title: Modèles de calendrier        none: Aucun calendrier défini diff --git a/config/locales/journey_patterns.en.yml b/config/locales/journey_patterns.en.yml index d480e144d..70ae94dd9 100644 --- a/config/locales/journey_patterns.en.yml +++ b/config/locales/journey_patterns.en.yml @@ -1,6 +1,7 @@  en:    journey_patterns:      journey_pattern: +      fetching_error: "There has been a problem fetching the data. Please reload the page to try again."        from_to: "From '%{departure}' to '%{arrival}'"        stop_count: "%{count}/%{route_count} stops"        vehicle_journeys_count: "Vehicle journeys: %{count}" @@ -19,6 +20,13 @@ en:      show:        title: "Journey Pattern %{journey_pattern}"        stop_points: "Stop point on journey pattern list" +      stop_points_count:  +        none: '%{count} stop areas' +        one: '%{count} stop area' +        other: '%{count} stop areas' +      informations: Informations +      confirmation: Confimation +      confirm_page_change: You are about to change page. Would you like to save your work before that ?      index:        title: "Journey Patterns of %{route}"      form: @@ -50,7 +58,8 @@ en:          creator_id: "Created by"          full_journey_time: Full journey          commercial_journey_time: Commercial journey - +        stop_points: Nb stop areas +        checksum: Checksum    formtastic:      titles:        journey_pattern: diff --git a/config/locales/journey_patterns.fr.yml b/config/locales/journey_patterns.fr.yml index 32c1f3f97..10653a02d 100644 --- a/config/locales/journey_patterns.fr.yml +++ b/config/locales/journey_patterns.fr.yml @@ -1,6 +1,7 @@  fr:    journey_patterns:      journey_pattern: +      fetching_error: "La récupération des courses a rencontré un problème. Rechargez la page pour tenter de corriger le problème."        from_to: "De '%{departure}' à '%{arrival}'"        stop_count: "%{count}/%{route_count} arrêts"        vehicle_journeys_count: "Courses: %{count}" @@ -19,6 +20,13 @@ fr:      show:        title: "Mission %{journey_pattern}"        stop_points: "Liste des arrêts de la mission" +      stop_points_count:  +        none: '%{count} arrêt' +        one: '%{count} arrêt' +        other: '%{count} arrêts' +      informations: Informations +      confirmation: Confimation +      confirm_page_change: Vous vous apprêtez à changer de page. Voulez-vous valider vos modifications avant cela ?      index:        title: "Missions de %{route}"      form: @@ -50,6 +58,8 @@ fr:          creator_id: "Créé par"          full_journey_time: Parcours complet          commercial_journey_time: Parcours commercial +        stop_points: Nb arrêts +        checksum: Signature métier    formtastic:      titles:        journey_pattern: diff --git a/config/locales/layouts.en.yml b/config/locales/layouts.en.yml index debff05e5..d5717b400 100644 --- a/config/locales/layouts.en.yml +++ b/config/locales/layouts.en.yml @@ -3,6 +3,7 @@ en:      back_to_dashboard: "Back to Dashboard"      help: "Help"      home: "Home" +    operations: Operations      user:        profile: "My Profile"        sign_out: "Sign out" diff --git a/config/locales/layouts.fr.yml b/config/locales/layouts.fr.yml index 5e835bcf7..17d23c756 100644 --- a/config/locales/layouts.fr.yml +++ b/config/locales/layouts.fr.yml @@ -3,6 +3,7 @@ fr:      back_to_dashboard: "Retour au Tableau de Bord"      help: "Aide"      home: "Accueil" +    operations: Opérations      user:        profile: "Mon Profil"        sign_out: "Déconnexion" diff --git a/config/locales/vehicle_journey_exports.en.yml b/config/locales/vehicle_journey_exports.en.yml index 93a782026..4e658353e 100644 --- a/config/locales/vehicle_journey_exports.en.yml +++ b/config/locales/vehicle_journey_exports.en.yml @@ -1,7 +1,7 @@  en:    vehicle_journey_exports:      new: -      title: "Export existing vehicle journey at stops" +      title: Vehicle journeys export        basename: "vehicle_journeys"      label:        vehicle_journey_id: "vj id (empty for new vj)" diff --git a/config/locales/vehicle_journeys.en.yml b/config/locales/vehicle_journeys.en.yml index f1ba96dc5..79e805ee8 100644 --- a/config/locales/vehicle_journeys.en.yml +++ b/config/locales/vehicle_journeys.en.yml @@ -1,14 +1,29 @@  en:    vehicle_journeys:      vehicle_journeys_matrix: +      filters: +        id: Filter by ID... +        timetable: Filter by journey pattern... +        timetable: Filter by timetable...        cancel_selection: "Cancel Selection"        fetching_error: "There has been a problem fetching the data. Please reload the page to try again."        line_routes: "Line's routes"        modal_confirm: 'Do you want to save mofications before moving on to the next page ?' -      pagination: "Schedules %{minVJ} to %{maxVJ} over %{total}"        selected_journeys: "%{count} selected journeys"        show_purchase_window: 'Show the purchase window'        show_timetable: 'Show calendar' +      no_associated_timetables: No associated timetables +      no_associated_purchase_windows: No associated purchase windows +      no_associated_footnotes: No associated footnotes +      duplicate: +        one: Clone %{count} vehicle journey +        other: Clone %{count} vehicle journeys +        start_time: Indicative start time +        number: Number of vehicle journeys to create and clone +        delta: Delta from which vehicle journeys are created +      affect_company: Affect company +      no_line_footnotes: The line doesn't have any footnotes +      select_footnotes: Select footnotes to associate with the vehicle journey      vehicle_journey:        title_stopless: "Vehicle journey %{name}"        title: "Vehicle journey leaving from %{stop} at %{time}" @@ -17,10 +32,10 @@ en:        title: "Vehicle journey frequency leaving from %{stop} at %{time}"        title_frequency: "Vehicle journey frequency with %{interval}min leaving from %{stop} at %{time_first} to %{time_last}"      actions: -      index: "Vehicle time's board" -      new: "Add a new timed vehicle journey" +      index: "Vehicle journeys" +      new: "Add a new vehicle journey"        new_frequency: "Add a new frequency vehicle journey" -      edit: "Edit this timed vehicle journey" +      edit: "Edit this vehicle journey"        edit_frequency: "Edit this frequency vehicle journey"        destroy: "Remove this vehicle journey"        destroy_confirm: "Are you sure you want destroy this vehicle journey?" @@ -48,15 +63,18 @@ en:        show_journeys_without_schedule: "Show journeys without schedule"        slide_arrival: "arrival time at first stop"        slide_departure: "departure time at first stop" -      slide_title: "Shift all vehicle passing times" +      slide_title: "Shift all the vehicle journey passing times : %{id}"        slide: "Shift" +      slide_delta: "Shift of"        starting_stop: "Departure"        stop_title: "Stop"        submit_frequency_edit: "Edit frequency vehicle journey"        submit_frequency: "Create frequency vehicle journey"        submit_timed_edit: "Edit vehicle journey"        submit_timed: "Create vehicle journey" -      time_tables: "Associated calendars to vehicle journey" +      time_tables: "Associated timetables" +      purchase_windows: Associated purchase windows +      footnotes: Associated footnotes        to_arrivals: "Copy departures to arrivals"        to_departures: "Copy arrivals to departures"        to: "at" @@ -102,6 +120,7 @@ en:          checksum: "Checksum"          comment: "Comments"          company: "Company" +        company_name: "Company name"          created_at: Created at          creator_id: "Created by"          departure_time: "Departure" @@ -110,9 +129,10 @@ en:          footnote_ids: "Footnotes"          id: "Journey ID"          journey_frequency_ids: "Timeband" -        journey_name: "Name of the journey" +        journey_name: "Name of the vehicle journey"          journey_pattern_id: "Pattern ID"          journey_pattern: "Journey Pattern" +        journey_pattern_published_name: "Journey Pattern published name"          line: "Line"          mobility_restricted_suitability: "PRM accessibility"          name: "Journey Name" @@ -137,6 +157,7 @@ en:          updated_at: Updated at          vehicle_journey_at_stop_ids: "Time list"          vehicle_type_identifier: "Vehicle Type Identifier" +        start_time: Start time      errors:        models:          vehicle_journey: diff --git a/config/locales/vehicle_journeys.fr.yml b/config/locales/vehicle_journeys.fr.yml index d144e580f..4336bc6dc 100644 --- a/config/locales/vehicle_journeys.fr.yml +++ b/config/locales/vehicle_journeys.fr.yml @@ -1,14 +1,29 @@  fr:    vehicle_journeys:      vehicle_journeys_matrix: +      filters: +        id: Filtrer par ID course... +        journey_pattern: 'Filtrer par code, nom ou OID de mission...' +        timetable: Filter by timetable...        cancel_selection: "Annuler la sélection"        fetching_error: "La récupération des missions a rencontré un problème. Rechargez la page pour tenter de corriger le problème."        line_routes: "Séquences d'arrêts de la ligne"        modal_confirm: 'Voulez-vous valider vos modifications avant de changer de page?' -      pagination: "Liste des horaires %{minVJ} à %{maxVJ} sur %{total}"        selected_journeys: "%{count} course(s) sélectionnée(s)"        show_purchase_window: 'Voir le calendrier commercial'        show_timetable: 'Voir le calendrier' +      no_associated_timetables: Aucun calendrier associé +      no_associated_purchase_windows: Aucun calendrier commercial associé +      no_associated_footnotes: Aucune note associée +      duplicate: +        one: Dupliquer %{count} course +        other: Dupliquer %{count} courses +        start_time: Horaire de départ indicatif +        number: Nombre de courses à créer et dupliquer +        delta: Décalage à partir duquel on créé les courses +      affect_company: Indiquez un nom de transporteur... +      no_line_footnotes: La ligne ne possède pas de notes +      select_footnotes: Sélectionnez les notes à associer à cette course      vehicle_journey:        title_stopless: "Course %{name}"        title: "Course partant de %{stop} à %{time}" @@ -48,8 +63,9 @@ fr:        show_journeys_without_schedule: "Afficher les courses sans horaires"        slide_arrival: "horaire d'arrivée au 1° arrêt à"        slide_departure: "horaire de départ au 1° arrêt à" -      slide_title: "Décaler l'ensemble des horaires de course" +      slide_title: "Décaler l'ensemble des horaires de la course : %{id}"        slide: "Décaler" +      slide_delta: "Avec un décalage de"        starting_stop: "Origine"        stop_title: "Arrêt"        submit_frequency_edit: "Editer course en fréquence" @@ -57,6 +73,8 @@ fr:        submit_timed_edit: "Editer course"        submit_timed: "Créer course"        time_tables: "Calendriers associés à la course" +      purchase_windows: "Calendriers commerciaux associés à la course" +      footnotes: "Notes associés à la course"        to_arrivals: "Copie départs vers arrivées"        to_arrivals: "Copie départs vers arrivées"        to_departures: "Copie arrivées vers départs" @@ -103,6 +121,7 @@ fr:          checksum: "Signature métier"          comment: "Commentaires"          company: "Transporteur" +        company|_name: "Nom du transporteur"          created_at: "Créé le"          creator_id: "Créé par"          departure_time: "Départ" @@ -114,6 +133,7 @@ fr:          journey_name: "Nom de la course"          journey_pattern_id: "ID Mission"          journey_pattern: "Mission" +        journey_pattern_published_name: "Nom public de la mission"          line: "Ligne"          mobility_restricted_suitability: "Accessibilité PMR"          name: "Nom Course" @@ -129,7 +149,7 @@ fr:          route: "Itinéraire"          time_slot: "Fréquence"          time_table_ids: "Liste des calendriers" -        time_tables: "Calendriers" +        time_tables: "Calendriers associés"          train_number: "Numéro de train"          transport_mode: "Mode de transport"          transport_submode: "Sous-mode de transport" @@ -138,6 +158,7 @@ fr:          updated_at: "Edité le"          vehicle_journey_at_stop_ids: "Liste des horaires"          vehicle_type_identifier: "Type d'identifiant du véhicule" +        start_time: Heure de départ      errors:        models:          vehicle_journey: diff --git a/config/locales/will_paginate.en.yml b/config/locales/will_paginate.en.yml index 29b8fe2bf..8f3189675 100644 --- a/config/locales/will_paginate.en.yml +++ b/config/locales/will_paginate.en.yml @@ -32,11 +32,11 @@ en:        single_page:          zero:  "No item found"          one:   "1 %{model} shown" -        other: "%{model} 1 to %{count} of %{count}" +        other: "%{model} 1 to %{count} out of %{count}"        single_page_html:          zero:  "No item found"          one:   "1 %{model} shown" -        other: "%{model} 1 to %{count} of %{count}" +        other: "%{model} 1 to %{count} out of %{count}" -      multi_page: "%{model} %{from} to %{to} of %{count}" -      multi_page_html: "%{model} %{from} to %{to} of %{count}" +      multi_page: "%{model} list %{from} to %{to} out of %{count}" +      multi_page_html: "%{model} list %{from} to %{to} out of %{count}" diff --git a/db/schema.rb b/db/schema.rb index d90bf7b6c..77e35f449 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -18,7 +18,6 @@ ActiveRecord::Schema.define(version: 20180319043333) do    enable_extension "hstore"    enable_extension "postgis"    enable_extension "unaccent" -  enable_extension "objectid"    create_table "access_links", id: :bigserial, force: :cascade do |t|      t.integer  "access_point_id",                        limit: 8 diff --git a/db/seeds/seed_helpers.rb b/db/seeds/seed_helpers.rb new file mode 100644 index 000000000..8e47e10bd --- /dev/null +++ b/db/seeds/seed_helpers.rb @@ -0,0 +1,12 @@ +class ActiveRecord::Base +  def self.seed_by(key_attribute, &block) +    model = find_or_create_by! key_attribute +    print "Seed #{name} #{key_attribute.inspect} " +    yield model + +    puts "[#{(model.changed? ? 'updated' : 'no change')}]" +    model.save! + +    model +  end +end diff --git a/db/seeds/stif.seeds.rb b/db/seeds/stif.seeds.rb index aa87b6f6c..bb73b0b9c 100644 --- a/db/seeds/stif.seeds.rb +++ b/db/seeds/stif.seeds.rb @@ -1,46 +1,25 @@  # coding: utf-8 -# This file should contain all the record creation needed to seed the database with its default values. -# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). -stop_area_referential = StopAreaReferential.find_or_create_by!(name: "Reflex", objectid_format: "stif_netex") -line_referential = LineReferential.find_or_create_by!(name: "CodifLigne", objectid_format: "stif_netex") +require_relative 'seed_helpers' -workgroup = Workgroup.find_or_create_by!(name: "Gestion de l'offre théorique IDFm") do |w| -  w.line_referential      = line_referential -  w.stop_area_referential = stop_area_referential -  w.export_types = ["Export::Netex"] +stif = Organisation.seed_by(code: "STIF") do |o| +  o.name = 'STIF'  end -Workbench.update_all workgroup_id: workgroup - -# Organisations -stif = Organisation.find_or_create_by!(code: "STIF") do |org| -  org.name = 'STIF' +stop_area_referential = StopAreaReferential.seed_by(name: "Reflex") do |r| +  r.objectid_format = "stif_netex" +  r.add_member stif, owner: true  end -# operator = Organisation.find_or_create_by!(code: 'transporteur-a') do |organisation| -#   organisation.name = "Transporteur A" -# end - -# Member -line_referential.add_member stif, owner: true -# line_referential.add_member operator -stop_area_referential.add_member stif, owner: true -# stop_area_referential.add_member operator +line_referential = LineReferential.seed_by(name: "CodifLigne") do |r| +  r.objectid_format = "stif_netex" +  r.add_member stif, owner: true +end -# Users -# stif.users.find_or_create_by!(username: "admin") do |user| -#   user.email = 'stif-boiv@af83.com' -#   user.password = "secret" -#   user.name = "STIF Administrateur" -# end -# -# operator.users.find_or_create_by!(username: "transporteur") do |user| -#   user.email = 'stif-boiv+transporteur@af83.com' -#   user.password = "secret" -#   user.name = "Martin Lejeune" -# end +workgroup = Workgroup.seed_by(name: "Gestion de l'offre théorique IDFm") do |w| +  w.line_referential      = line_referential +  w.stop_area_referential = stop_area_referential +  w.export_types          = ["Export::Netex"] +end -# Include all Lines in organisation functional_scope -stif.update sso_attributes: { functional_scope: line_referential.lines.pluck(:objectid) } -#operator.update sso_attributes: { functional_scope: line_referential.lines.limit(3).pluck(:objectid) } +Workbench.update_all workgroup_id: workgroup diff --git a/spec/features/calendars_permissions_spec.rb b/spec/features/calendars_permissions_spec.rb index 4857592d5..656c0dd78 100644 --- a/spec/features/calendars_permissions_spec.rb +++ b/spec/features/calendars_permissions_spec.rb @@ -1,8 +1,8 @@  RSpec.describe 'Calendars', type: :feature do    login_user -  let(:calendar) { create :calendar, organisation_id: 1 } -  let(:workgroup) { calendar.workgroup } +  let(:calendar) { create :calendar, organisation: first_organisation, workgroup: first_workgroup } +  let(:workgroup) { first_workgroup }    describe 'permissions' do      before do diff --git a/spec/features/calendars_spec.rb b/spec/features/calendars_spec.rb new file mode 100644 index 000000000..26220746b --- /dev/null +++ b/spec/features/calendars_spec.rb @@ -0,0 +1,16 @@ +RSpec.describe 'Calendars', type: :feature do +  login_user + +  let(:calendar1)        { create(:calendar, workgroup: @user.organisation.workgroups.first, organisation: @user.organisation) } +  let(:calendar2)        { create(:calendar) } + +  describe "index" do +    before(:each) do +      visit workgroup_calendars_path(calendar1.workgroup) +    end +    it "should only display calendars from same workgroup" do +      expect(page).to have_content calendar1.name +      expect(page).to_not have_content calendar2.name +    end +  end +end
\ No newline at end of file diff --git a/spec/features/compliance_control_sets_spec.rb b/spec/features/compliance_control_sets_spec.rb index 0f4597db3..306f363a5 100644 --- a/spec/features/compliance_control_sets_spec.rb +++ b/spec/features/compliance_control_sets_spec.rb @@ -12,7 +12,7 @@ RSpec.describe "ComplianceControlSets", type: :feature do    let(:other_control_cset) { create :compliance_control_set, organisation: other_orga }    let(:blox){ -    2.times.map{ | _ | create :compliance_control_block, compliance_control_set: control_set } +    2.times.map{ |n| create :compliance_control_block, compliance_control_set: control_set, transport_mode: StifTransportModeEnumerations.transport_modes[n], transport_submode: StifTransportSubmodeEnumerations.transport_submodes[n] }    }    before do diff --git a/spec/lib/compliance_control_set_cloner_spec.rb b/spec/lib/compliance_control_set_cloner_spec.rb index 7efe27659..0d3561e0e 100644 --- a/spec/lib/compliance_control_set_cloner_spec.rb +++ b/spec/lib/compliance_control_set_cloner_spec.rb @@ -49,7 +49,7 @@ RSpec.describe ComplianceControlSetCloner do        context 'Directed Acyclic Graph is copied correctly' do          let(:source_blox){ -          3.times.map{ |_| create :compliance_control_block, compliance_control_set: source_set } +          3.times.map{ |n| create :compliance_control_block, compliance_control_set: source_set, transport_mode: StifTransportModeEnumerations.transport_modes[n], transport_submode: StifTransportSubmodeEnumerations.transport_submodes[n]   }          }          let(:direct_ccs){            3.times.map{ |n| create :generic_attribute_control_min_max, compliance_control_set: source_set, name: "direct #{n.succ}", code: "direct-#{n.succ}" } diff --git a/spec/lib/compliance_control_set_copier_spec.rb b/spec/lib/compliance_control_set_copier_spec.rb index 0f15d86d0..d1a56cd7f 100644 --- a/spec/lib/compliance_control_set_copier_spec.rb +++ b/spec/lib/compliance_control_set_copier_spec.rb @@ -23,7 +23,7 @@ RSpec.describe ComplianceControlSetCopier do        context 'Directed Acyclic Graph is copied correctly' do          let(:cc_blox){ -          3.times.map{ |_| create :compliance_control_block, compliance_control_set: cc_set } +          3.times.map{ |n| create :compliance_control_block, compliance_control_set: cc_set, transport_mode: StifTransportModeEnumerations.transport_modes[n], transport_submode: StifTransportSubmodeEnumerations.transport_submodes[n] }          }          let!(:direct_ccs){            3.times.map{ |n| create :compliance_control, compliance_control_set: cc_set, name: "direct #{n.succ}", code: "direct-#{n.succ}" } diff --git a/spec/models/compliance_control_block_spec.rb b/spec/models/compliance_control_block_spec.rb index 4abe0ed9c..089d78434 100644 --- a/spec/models/compliance_control_block_spec.rb +++ b/spec/models/compliance_control_block_spec.rb @@ -17,4 +17,16 @@ RSpec.describe ComplianceControlBlock, type: :model do    it { should_not allow_values( *%w{ demandResponseBus nightus irportLinkBus highrequencyBus expressBUs                                       Shuttle suburban regioalRail interregion4lRail })          .for(:transport_submode) } + +  context "transport mode & submode uniqueness" do +    let(:cc_block) {create :compliance_control_block, transport_mode: 'bus', transport_submode: 'nightBus'} +    let(:cc_set1) { cc_block.compliance_control_set } +    let(:cc_set2) { create :compliance_control_set }      + +  it "sould be unique in a compliance control set" do +    expect( ComplianceControlBlock.new(transport_mode: 'bus', transport_submode: 'nightBus', compliance_control_set: cc_set1) ).not_to be_valid +    expect( ComplianceControlBlock.new(transport_mode: 'bus', transport_submode: 'nightBus', compliance_control_set: cc_set2) ).to be_valid +  end + +end  end diff --git a/spec/models/referential_metadata_spec.rb b/spec/models/referential_metadata_spec.rb index 291ed974a..88a12b2bb 100644 --- a/spec/models/referential_metadata_spec.rb +++ b/spec/models/referential_metadata_spec.rb @@ -12,14 +12,19 @@ RSpec.describe ReferentialMetadata, :type => :model do    describe ".new_from" do      let(:referential_metadata) { create :referential_metadata, referential_source: create(:referential) } -    let(:new_referential_metadata) { ReferentialMetadata.new_from(referential_metadata, []) } +    let(:new_referential_metadata) { ReferentialMetadata.new_from(referential_metadata, nil) } +    before do +      referential_metadata.line_ids.each do |id| +        Chouette::Line.find(id).update_attribute :line_referential_id, referential_metadata.referential.line_referential_id +      end +    end      it "should not have an associated referential" do        expect(new_referential_metadata).to be_a_new(ReferentialMetadata)      end -    xit "should have the same lines" do -      expect(new_referential_metadata.lines).to eq(referential_metadata.lines) +    it "should have the same lines" do +      expect(new_referential_metadata.line_ids.sort).to eq(referential_metadata.line_ids.sort)      end      it "should have the same periods" do @@ -34,6 +39,14 @@ RSpec.describe ReferentialMetadata, :type => :model do        expect(new_referential_metadata.referential_source).to eq(referential_metadata.referential)      end +    context "with a functional scope" do +      let(:organisation){ create :organisation, sso_attributes: {"functional_scope" => [referential_metadata.referential.lines.first.objectid]} } +      let(:new_referential_metadata) { ReferentialMetadata.new_from(referential_metadata, organisation) } + +      it "should scope the lines" do +        expect(new_referential_metadata.line_ids).to eq [referential_metadata.referential.lines.first.id] +      end +    end    end    describe "Period" do diff --git a/spec/models/referential_spec.rb b/spec/models/referential_spec.rb index 1d9b3d78a..ca2caf57f 100644 --- a/spec/models/referential_spec.rb +++ b/spec/models/referential_spec.rb @@ -55,7 +55,7 @@ describe Referential, :type => :model do    context "Cloning referential" do      let(:clone) do -      Referential.new_from(ref, []) +      Referential.new_from(ref, nil)      end      let!(:workbench){ create :workbench } diff --git a/spec/support/referential.rb b/spec/support/referential.rb index 9acdce73a..b50844ae4 100644 --- a/spec/support/referential.rb +++ b/spec/support/referential.rb @@ -8,6 +8,10 @@ module ReferentialHelper      Organisation.find_by!(code: "first")    end +  def first_workgroup +    Workgroup.find_by_name('IDFM') +  end +    def self.included(base)      base.class_eval do        extend ClassMethods @@ -53,10 +57,18 @@ RSpec.configure do |config|        referential.add_member organisation, owner: true      end +    workgroup = FactoryGirl.create( +      :workgroup, +      name: "IDFM", +      line_referential: line_referential, +      stop_area_referential: stop_area_referential +    ) +      workbench = FactoryGirl.create(        :workbench,        name: "Gestion de l'offre",        organisation: organisation, +      workgroup: workgroup,        line_referential: line_referential,        stop_area_referential: stop_area_referential      ) | 
