diff options
| author | Xinhui Xu | 2017-09-12 15:52:49 +0200 | 
|---|---|---|
| committer | GitHub | 2017-09-12 15:52:49 +0200 | 
| commit | 095dd5151d40d25c9abb015808834b32e575c750 (patch) | |
| tree | 3aacd609bfbd277a5e33e8ee2208a3293f85a3ba | |
| parent | e2270acdfcec57a8be2ada201a668d9d610953ab (diff) | |
| parent | 4aa19d931f8585c061dd3da49e31b2ddbbb1bf6b (diff) | |
| download | chouette-core-095dd5151d40d25c9abb015808834b32e575c750.tar.bz2 | |
Merge branch 'master' into compliance_control
156 files changed, 1317 insertions, 2369 deletions
| diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/actions/index.js b/app/assets/javascripts/es6_browserified/journey_patterns/actions/index.js index 3577df2b6..34689070d 100644 --- a/app/assets/javascripts/es6_browserified/journey_patterns/actions/index.js +++ b/app/assets/javascripts/es6_browserified/journey_patterns/actions/index.js @@ -90,10 +90,7 @@ const actions = {    resetValidation: (target) => {      $(target).parent().removeClass('has-error').children('.help-block').remove()    }, -  humanOID : (oid) => { -    var a = oid.split(':') -    return a[a.length - 1] -  }, +  humanOID : (oid) => oid.split(':')[2],    validateFields : (fields) => {      const test = [] diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/actions/index.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/actions/index.js index 2fde0d76f..de87c14af 100644 --- a/app/assets/javascripts/es6_browserified/vehicle_journeys/actions/index.js +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/actions/index.js @@ -269,10 +269,7 @@ const actions = {      type: 'RECEIVE_TOTAL_COUNT',      total    }), -  humanOID : (oid) => { -    var a = oid.split(':') -    return a[a.length - 1] -  }, +  humanOID: (oid) => oid.split(':')[2],    fetchVehicleJourneys : (dispatch, currentPage, nextPage, queryString) => {      if(currentPage == undefined){        currentPage = 1 diff --git a/app/assets/javascripts/filters/calendar.js b/app/assets/javascripts/filters/calendar.js new file mode 100644 index 000000000..a4e84777c --- /dev/null +++ b/app/assets/javascripts/filters/calendar.js @@ -0,0 +1,6 @@ +const DateFilter = require('../helpers/date_filters') + +$(document).ready(function(){ +  const calendarDF = new DateFilter("#calendar_filter_btn", "Tous les champs du filtre de date doivent ĂȘtre remplis", "#q_contains_date_NUMi") +  calendarDF() +}) diff --git a/app/assets/javascripts/filters/import.js b/app/assets/javascripts/filters/import.js new file mode 100644 index 000000000..bb665d5ad --- /dev/null +++ b/app/assets/javascripts/filters/import.js @@ -0,0 +1,6 @@ +const DateFilter = require('../helpers/date_filters') + +$(document).ready(function(){ +  const importDF = new DateFilter("#import_filter_btn", "Tous les champs du filtre de date doivent ĂȘtre remplis", "#q_started_at_begin_NUMi", "#q_started_at_end_NUMi") +  importDF() +}) diff --git a/app/assets/javascripts/filters/time_table.js b/app/assets/javascripts/filters/time_table.js new file mode 100644 index 000000000..9e24d03fe --- /dev/null +++ b/app/assets/javascripts/filters/time_table.js @@ -0,0 +1,7 @@ +$(document).ready(function(){ +  const DateFilter = require('../helpers/date_filters') + +  const timetableDF = new DateFilter("#time_table_filter_btn", window.I18n.fr.time_tables.error_period_filter, "#q_start_date_gteq_NUMi", "#q_end_date_lteq_NUMi") + +  timetableDF() +}) diff --git a/app/assets/javascripts/filters/workbench.js b/app/assets/javascripts/filters/workbench.js new file mode 100644 index 000000000..af3e13c59 --- /dev/null +++ b/app/assets/javascripts/filters/workbench.js @@ -0,0 +1,6 @@ +const DateFilter = require('../helpers/date_filters') + +$(document).ready(function(){ +  const workbenchDF = new DateFilter("#referential_filter_btn", window.I18n.fr.referentials.error_period_filter, "#q_validity_period_begin_gteq_NUMi", "#q_validity_period_end_lteq_NUMi") +  workbenchDF() +}) diff --git a/app/assets/javascripts/helpers/date_filters.js b/app/assets/javascripts/helpers/date_filters.js new file mode 100644 index 000000000..1f48bb28f --- /dev/null +++ b/app/assets/javascripts/helpers/date_filters.js @@ -0,0 +1,38 @@ +const DateFilter = function(buttonId, message, ...inputIds) { +  this.buttonId = buttonId +  this.inputIds = inputIds +  this.message = message + +  const getVal = (str, key) => { +    let newStr = str.replace(/NUM/, key) +    return $(newStr).val() +  } + +  const getDates = () => { +    return this.inputIds.reduce((arr, id) => { +      let newIds = [1, 2, 3].map(key => getVal(id, key)) +      arr.push(...newIds) +      return arr +    },[]) +  } + +  const allInputFilled = () => { +    return getDates().every(date => !!date) +  } + +  const noInputFilled = () => { +    return getDates().every(date => !date) +  } + +  const execute = () => { +    $(this.buttonId).on("click", (e) => { +      if (allInputFilled() == false && noInputFilled() == false) { +        e.preventDefault() +        alert(this.message) +      } +    }) +  } +  return execute +} + +module.exports = DateFilter diff --git a/app/assets/javascripts/time_table.coffee b/app/assets/javascripts/time_table.coffee deleted file mode 100644 index 8789cb226..000000000 --- a/app/assets/javascripts/time_table.coffee +++ /dev/null @@ -1,14 +0,0 @@ - $(document).on("click", "#time_table_filter_btn", (e) -> -   dates = [1, 2, 3].reduce (arr, key) -> -     arr.push $("#q_start_date_gteq_#{key}i").val(), $("#q_end_date_lteq_#{key}i").val() -     arr -   , [] - -   validDate = dates.every (date) -> !!date - -   noDate = dates.every (date) -> !date - -   unless (validDate || noDate) -     e.preventDefault() -     alert(window.I18n.fr.time_tables.error_period_filter) - ) diff --git a/app/assets/javascripts/workbench.coffee b/app/assets/javascripts/workbench.coffee deleted file mode 100644 index 0e9fe62a3..000000000 --- a/app/assets/javascripts/workbench.coffee +++ /dev/null @@ -1,18 +0,0 @@ - $(document).on("click", "#referential_filter_btn", (e) -> -   dates = [1, 2, 3].reduce (arr, key) -> -     arr.push $("#q_validity_period_begin_gteq_#{key}i").val(), $("#q_validity_period_end_lteq_#{key}i").val() -     arr -   , [] - -   validDate = dates.every (date) -> !!date - -   noDate = dates.every (date) -> !date - -   console.log("valid dates :", validDate) -   console.log("no dates :", noDate) -   console.log(dates) - -   unless (validDate || noDate) -     e.preventDefault() -     alert(window.I18n.fr.referentials.error_period_filter) - ) diff --git a/app/assets/stylesheets/application.sass b/app/assets/stylesheets/application.sass index e3f776640..50f8b64cb 100644 --- a/app/assets/stylesheets/application.sass +++ b/app/assets/stylesheets/application.sass @@ -18,3 +18,4 @@  @import 'modules/jp_collection'  @import 'modules/vj_collection'  @import 'modules/timetables' +@import 'modules/import_messages' diff --git a/app/assets/stylesheets/main/access_links.sass b/app/assets/stylesheets/main/access_links.sass deleted file mode 100644 index 65a81a2f8..000000000 --- a/app/assets/stylesheets/main/access_links.sass +++ /dev/null @@ -1,18 +0,0 @@ -// Place all the styles related to the lines controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ - -#workspace.access_links.show -  .summary p label -    font-weight: bold - -  .duration -    padding-left: 10px        - -#workspace.access_links.edit, -#workspace.access_links.new, -#workspace.access_links.create, -#workspace.access_links.update -  .time_select ol -    padding: 0 0 0 40% -    width: 100%
\ No newline at end of file diff --git a/app/assets/stylesheets/main/access_points.sass b/app/assets/stylesheets/main/access_points.sass deleted file mode 100644 index 11e41967b..000000000 --- a/app/assets/stylesheets/main/access_points.sass +++ /dev/null @@ -1,78 +0,0 @@ -// Place all the styles related to the lines controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ - -// #workspace.access_points.index - -#workspace.access_points.edit, -#workspace.access_points.new, -#workspace.access_points.create, -#workspace.access_points.update -  .time_select ol -    padding: 0 0 0 40% -    width: 100% - -#workspace.access_points.edit -  legend -    padding-bottom: 20px - -#workspace.access_points.show -  .geo_data -    padding-left: 15px - -  .summary -    p label -      font-weight: bold -   -  .access_link_pairs -    table -      border: 0px -      border-collapse: separate -      border-spacing: 3px -     -    .link -      border: 2px solid black -     -    .access_point -      padding: 3px 15px 0px 3px -      height: 25px - -      * -        vertical-align: middle - -      span -        margin-left: 7px - -      img -        margin: 0px 5px 0px 5px -     -    .stop_area -      padding: 3px 15px 0px 3px -      height: 25px - -      * -        vertical-align: middle - -      span -        margin-left: 7px - -      img -        margin: 0px 5px 0px 5px -     -    .info -      font-size: 10px -      color: #777 -      font-weight: normal -      padding-top: 10px -      padding-left: 45px -      padding-right: 3px -      padding-bottom: 3px - -#sidebar ul.selection li     -  a -    line-height: 27px -     -    img -      height: 25px -      width: 25px -      vertical-align: middle
\ No newline at end of file diff --git a/app/assets/stylesheets/main/api_keys.sass b/app/assets/stylesheets/main/api_keys.sass deleted file mode 100644 index 28bf171b9..000000000 --- a/app/assets/stylesheets/main/api_keys.sass +++ /dev/null @@ -1,7 +0,0 @@ -// Place all the styles related to the routes controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ - -#workspace.api_keys.show -  .summary p label -    font-weight: bold
\ No newline at end of file diff --git a/app/assets/stylesheets/main/calendar.sass b/app/assets/stylesheets/main/calendar.sass deleted file mode 100644 index f24f2b212..000000000 --- a/app/assets/stylesheets/main/calendar.sass +++ /dev/null @@ -1,98 +0,0 @@ -// A grey based theme, inspired by Blinksale and their ColorBurn widget. http://firewheeldesign.com - -// AUTHOR: Geoffrey Grosenbach http://nubyonrails.com - -// Colors:  -//   dk: 787888 -//   lt: 4f4f5b -//   lter: a8a8a8 -//   white: ffffff - -$selected_period_color: #ffbd2b -$selected_date_color: #8fc861 -$excluded_date_color: #ff8f85 -$overlap_date_color: #c082f4 - -.year_choice -  font-size: 16px -  font-weight: bold -  margin: 10px 0 0 0 -  text-align: center - -  .year -    text-align: center - -.calendar_helper -  padding: auto - -.calendar -  font-size: 10px -  color: white -  text-align: center -  margin-left: 15px -  display: inline-table - -thead tr -  color: black - -th.monthName -  font-size: 12px -  font-weight: bold -  text-align: center -  padding-top: 1em -  padding-bottom: 0.7em -  color: black - -.dayName th -  text-align: center -  padding-top: 0.6em -  padding-bottom: 0.3em -  background-color: #303030 -  color: white -  border-bottom: 1px solid white - -.otherMonth -  color: #999999 -  background-color: #4f4f5b -  padding: 0.7em -  border-right: 1px solid #111111 -  border-bottom: 1px solid #111111 - -.day -  background-color: #333333 - -.day, .specialDay -  border-bottom: 1px solid #111111 -  padding: 0.7em -  border-right: 1px solid #111111 -  border-bottom: 1px solid #111111 - -.specialDay -  background-color: #a8a8a8 !important - -.selected_period -  background-color: $selected_period_color !important - -.selected_date -  background-color: $selected_date_color !important - -.excluded_date -  background-color: $excluded_date_color !important - -.overlaped_date -  background-color: $overlap_date_color !important - -.specialDay, .selected_period, .selected_date, .overlaped_date, .excluded_date -  a, a:visited, a:hover -    color: white -    text-decoration: none - -.specialDay a:hover, .selected_period a:hover, .selected_date a:hover, .excluded_date a:hover, .overlaped_date a:hover -  color: black - -.weekendDay -  background-color: #787888 - -.today -  background-color: white -  color: black
\ No newline at end of file diff --git a/app/assets/stylesheets/main/calendars.sass b/app/assets/stylesheets/main/calendars.sass deleted file mode 100644 index 298ce2a62..000000000 --- a/app/assets/stylesheets/main/calendars.sass +++ /dev/null @@ -1,11 +0,0 @@ -#calendar_form -  .btn -    margin: 5px -  #delete-btn -    margin-top: 23px -  .well -    padding-left: 50px - -#calendar_search_form -  button -    margin-top: 24px diff --git a/app/assets/stylesheets/main/companies.sass b/app/assets/stylesheets/main/companies.sass deleted file mode 100644 index 2cf1f596c..000000000 --- a/app/assets/stylesheets/main/companies.sass +++ /dev/null @@ -1,9 +0,0 @@ -// Place all the styles related to the lines controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ - -// #workspace.companies.index - -#workspace.companies.show -  .summary p label -    font-weight: bold
\ No newline at end of file diff --git a/app/assets/stylesheets/main/compliance_checks.sass b/app/assets/stylesheets/main/compliance_checks.sass deleted file mode 100644 index 451972fd5..000000000 --- a/app/assets/stylesheets/main/compliance_checks.sass +++ /dev/null @@ -1,157 +0,0 @@ -// #workspace.compliance_checks.index - -#workspace.compliance_checks.show -  @import '../modules/job_status_colors' -  @import '../modules/job_status_title' -  @import '../partials/ie_report' -  @import '../modules/links' - -#validation_success -  margin-top: 15px - -#workspace.compliance_checks.report, #workspace.imports.compliance_check -  @import '../modules/job_status_colors' -  @import '../modules/job_status_title' -  @import '../modules/links' - -  .status -    margin-left: 10px - -  .order -    margin-bottom: 10px -    padding: 5px -    border-top: 1px solid #e4e4e4 -    border-bottom: 1px solid #e4e4e4 - -  .status_ok_error -    color: #8fc861 -  .status_nok_error -    color: #e22b1b -  .status_uncheck_error -    color: #898e7f - -  .status_ok_warning -    color: #8fc861 -  .status_nok_warning -    color: #ffbd2b -  .status_uncheck_warning -    color: #898e7f - -  .resume -    &:after -      content: " " -      display: block -      height: 0 -      clear: both -      visibility: hidden - -    .col1 -      float: left -      width: 45% - -    .col2 -      margin-left: 10px -      float: left -      width: 45% - -    .graph -      height: 200px - -    .caption -      text-align: center -      font-weight: bold - -  .report -    .table -      margin-top: 20px - -    dl.inline -      width: 100% -      overflow: hidden - -      dt -        float: left -        clear: left -        width: 35% -        padding-top: 5px -        border-top: 1px solid #eee -        -ms-word-break: break-all -        word-break: break-all -        word-break: break-word -        -webkit-hyphens: auto -        -moz-hyphens: auto -        -ms-hyphens: auto -        hyphens: auto - -      dd -        float: left -        width: 65% -        padding-top: 10px -        border-top: 1px solid #eee - -  .severity__improvment, -  .severity_warning, -  .severity_error -    border: 1px solid -    margin: 10px 0px -    padding: 10px 10px 10px 10px -    background-repeat: no-repeat -    background-position: 10px center -    -moz-border-radius: 0.5em -    -webkit-border-radius: 0.5em -    border-radius: 0.5em -    height: 100% - -    &:after -      content: " " -      display: block -      height: 0 -      clear: both -      visibility: hidden - -    .status_icon -      float: left -      width: 20% -      height: auto - -      img -        vertical-align: middle -        width: 48px -        height: 48px - -    .status_text -      float: left -      width: 70% - -      .code -        font-size: 12px -        font-weight: bold - -      .severity -        font-size: 10px - -      .explanation -        display: none -        font-size: 12px -        margin: 5px 0 0 0 - -      .attributes -        font-size: 10px -        font-weight: bold -        margin: 5px 0 0px 0 - -  .severity_improvment -    color: black -    background-color: #c5cf4c - -  .severity_warning -    color: black -    background-color: #f1dd30 - -  .severity_error -    color: black -    background-color: #ff9a0c - -  .file_error -    font-size: 14px -    color: #898e7f
\ No newline at end of file diff --git a/app/assets/stylesheets/main/connection_links.sass b/app/assets/stylesheets/main/connection_links.sass deleted file mode 100644 index a23fbcdff..000000000 --- a/app/assets/stylesheets/main/connection_links.sass +++ /dev/null @@ -1,30 +0,0 @@ -// Place all the styles related to the lines controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ - -// #workspace.connection_links.index - -#workspace.connection_links.show -  .summary p label -    font-weight: bold - -  .duration -    padding-left: 10px - -#workspace.connection_links.select_departure -  .token-input-list -    display: inline-block - -#workspace.connection_links.select_arrival -  .token-input-list -    display: inline-block - -#workspace.connection_links.edit, -#workspace.connection_links.new, -#workspace.connection_links.create, -#workspace.connection_links.update -  legend -    border: 0px - -  .panel -    margin-left: 25%
\ No newline at end of file diff --git a/app/assets/stylesheets/main/errors.sass b/app/assets/stylesheets/main/errors.sass deleted file mode 100644 index ee603e459..000000000 --- a/app/assets/stylesheets/main/errors.sass +++ /dev/null @@ -1,21 +0,0 @@ -#workspace.errors -  body -    text-align: center -     -  div.error -    width: 45em -    padding: 1em -    margin: 2em auto 0 auto -    border: 1px solid #ccc -    border-right-color: #999 -    border-bottom-color: #999 - -  h2 -    font-size: 100% -    color: #f00 -    line-height: 1.5em -    font-weight: bold - -  a, a:visited -    text-decoration: underline -    color: blue
\ No newline at end of file diff --git a/app/assets/stylesheets/main/export_tasks.sass b/app/assets/stylesheets/main/export_tasks.sass deleted file mode 100644 index 799b5a13f..000000000 --- a/app/assets/stylesheets/main/export_tasks.sass +++ /dev/null @@ -1,10 +0,0 @@ -#workspace.export_tasks.new, #workspace.export_tasks.create -  .nav -    margin: 30px 0 10px 0 - -  .highlight -    padding: 9px 14px -    margin-bottom: 14px -    background-color: #f7f7f9 -    border: 1px solid #e1e1e8 -    border-radius: 4px
\ No newline at end of file diff --git a/app/assets/stylesheets/main/exports.sass b/app/assets/stylesheets/main/exports.sass deleted file mode 100644 index 875dc13f5..000000000 --- a/app/assets/stylesheets/main/exports.sass +++ /dev/null @@ -1,19 +0,0 @@ -// Place all the styles related to the Exports controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ - -#workspace.exports.index -  .panel.export -    .panel-footer -      .history -        margin-top: 5px - -#workspace.exports.show -  @import '../partials/ie_report' -  @import '../modules/job_status_colors' -  @import '../modules/job_status_title' -  @import '../modules/links' - -  .export-attributes -    font-size: 1.7em -    margin-top: 20px
\ No newline at end of file diff --git a/app/assets/stylesheets/main/group_of_lines.sass b/app/assets/stylesheets/main/group_of_lines.sass deleted file mode 100644 index d63eeb607..000000000 --- a/app/assets/stylesheets/main/group_of_lines.sass +++ /dev/null @@ -1,15 +0,0 @@ -// Place all the styles related to the lines controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ - -// #workspace.group_of_lines.index - -#workspace.group_of_lines.show -  .summary p label -    font-weight: bold - -  .lines_detail div.page_info -    margin-top: 0px   - -  .lines -    margin-top: 10px
\ No newline at end of file diff --git a/app/assets/stylesheets/main/help.sass b/app/assets/stylesheets/main/help.sass deleted file mode 100644 index 87f21c3c3..000000000 --- a/app/assets/stylesheets/main/help.sass +++ /dev/null @@ -1,121 +0,0 @@ -#workspace.help -  ul li -    list-style: circle -    margin: 7px 0 7px 20px - -  ol ul li -    list-style: circle -    margin: 7px 0 7px 20px - -  ol -    list-style: none -    margin: 7px 0 7px 20px -    padding: 0 -    counter-reset: num - -    li:before -      content: counter(num) '. ' -      counter-increment: num - -    ol li:before -      content: counters(num, '.') ' ' - -  em, cite -    font-style: italic - -  strong -    font-weight: bold - -  p.attr_data -    font-style: italic -    text-decoration: underline - -  p.olnext -    margin: -7px 0 0 40px !important - -  p.ddnext -    margin: 0 0 0 30px !important - -  p.note -    margin-left: 20px !important -    font-weight: bold - -  p.border_image -    text-align: center - -    img -      border-style: solid -      border-width: 1px -      border-color: rgb(187,187,187) - -  table -    width: 100% - -    td -      padding: 3px 5px -      width: 30% - -    &.meta -      width: 50% - -      th, td -        border: 1px solid black - -  dt -    font-style: italic -    margin: 5px 0 - -  dd -    padding-left: 10px - -#sidebarhelp.help -  h2 -    font-size: 17px - -  h3 -    font-size: 15px - -  h4 -    font-weight: bold -    padding: 7px 0 - -  ul li -    list-style: circle -    margin: 7px 0 7px 20px - -  ol -    list-style: none -    margin: 7px 0 7px 20px -    padding: 0 -    counter-reset: num - -    li:before -      content: counter(num) '. ' -      counter-increment: num - -    ol li:before -      content: counters(num, '.') ' ' - -  em, cite -    font-style: italic - -  strong -    font-weight: bold - -  p.attr_data -    font-style: italic -    text-decoration: underline - -  table -    width: 100% - -    td -      padding: 3px 5px -      width: 30% - -  dt -    font-style: italic -    margin: 5px 0 - -  dd -    padding-left: 10px
\ No newline at end of file diff --git a/app/assets/stylesheets/main/import_tasks.sass b/app/assets/stylesheets/main/import_tasks.sass deleted file mode 100644 index 810582cf2..000000000 --- a/app/assets/stylesheets/main/import_tasks.sass +++ /dev/null @@ -1,11 +0,0 @@ -#workspace.import_tasks.new, -#workspace.import_tasks.create -  .nav -    margin: 30px 0 10px 0 - -  .highlight -    padding: 9px 14px -    margin-bottom: 14px -    background-color: #f7f7f9 -    border: 1px solid #e1e1e8 -    border-radius: 4px
\ No newline at end of file diff --git a/app/assets/stylesheets/main/imports.sass b/app/assets/stylesheets/main/imports.sass deleted file mode 100644 index af5e88218..000000000 --- a/app/assets/stylesheets/main/imports.sass +++ /dev/null @@ -1,40 +0,0 @@ -#workspace.imports.index -  .panel.import -    .panel-footer -      min-height: 5.5em - -      .save-mode -        color: $brand-info - -        .fa-lg -          font-size: 1em -        .fa-ban -          opacity: 0.6 - -      .history -        margin-top: 5px - -#workspace.imports.index, -#workspace.imports.show -  .import-attributes -    .save-mode, .format -      display: inline-block - -    .save-mode -      color: $brand-info -      margin-left: 0.3em - -      .fa-ban -        opacity: 0.6 -      .fa-stack -        font-size: 0.9em - -#workspace.imports.show -  @import '../partials/ie_report' -  @import '../modules/job_status_colors' -  @import '../modules/job_status_title' -  @import '../modules/links' - -  .import-attributes -    font-size: 1.7em -    margin-top: 20px
\ No newline at end of file diff --git a/app/assets/stylesheets/main/journey_patterns.sass b/app/assets/stylesheets/main/journey_patterns.sass deleted file mode 100644 index 07c3260d4..000000000 --- a/app/assets/stylesheets/main/journey_patterns.sass +++ /dev/null @@ -1,49 +0,0 @@ -// Place all the styles related to the routes controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ - -#workspace.journey_patterns.edit, -#workspace.journey_patterns.new, -#workspace.journey_patterns.create, -#workspace.journey_patterns.update -  #route_color -    width: 100px -    color: white -    font-weight: bold - -  #journey_pattern_stop_point_ids_input fieldset .choices-group -    margin-top: 25px - -#workspace.journey_patterns.show -  .journey_pattern_color -    color: white -    font-weight: bold -    padding: 0 5px 0 5px - -    .summary p label -      font-weight: bold - -    .stop_points_detail div.page_info -      margin-top: 0px - -    .stop_points -      margin-top: 20px -     -    .journey_pattern_stop_points -      clear: both -      margin: 0px -      padding: 0px - -    .stop_point -      .position -        width: 25px -        height: 20px -        float: left -        background-color: #61970B -        font-weight: bold -        color: white -        margin-right: 10px -        padding-left: 4px - -  #middle #sidebar a.control-shape -    color: orange
\ No newline at end of file diff --git a/app/assets/stylesheets/main/layout.sass b/app/assets/stylesheets/main/layout.sass deleted file mode 100644 index d75c359ae..000000000 --- a/app/assets/stylesheets/main/layout.sass +++ /dev/null @@ -1,133 +0,0 @@ -body -  padding-top: 50px - -h1 -  color: white - -h1, .h1, h2, .h2, h3, .h3 -  margin-bottom: 20px - -label.label -  color: black -  font-size: 100% - -ol.breadcrumb -  margin-top: 10px - -.ce-hide -  display: none - -#middle -  position: relative -  min-height: 500px -  -webkit-box-shadow: 0 0 5px 2px rgba(0, 0, 0, .2) -  box-shadow: 0 0 5px 2px rgba(0, 0, 0, .2) -  padding-top: 10px -  padding-bottom: 10px -  margin-top: 20px -  margin-bottom: 20px -  background: white - -  .main_actions -    text-align: right - -  .alert -    margin-top: 15px - -  #sidebar -    height: 100% -    padding-top: 20px -    border-left: 1px solid $gray-lighter - -    &.ce-SidebarFloatBlock -      position: absolute -      height: auto -      right: 0 -      background-color: #fff -      top: 45px - -    label -      color: #555555 -      font-weight: normal -      font-size: 12px - -    a -      color: #666 - -    .actions -      margin-bottom: 20px - -      li -        margin-bottom: 5px - -    p -      font-size: 12px - -    fieldset.history_tag -      font-size: 12px -      color: $gray-light - -      legend -        font-size: 14px -        margin-bottom: 10px - -    fieldset -      border-color: white - -      p -        margin-top: 5px - -        label -          font-size: 12px -        span -          font-style: oblique -          font-size: 12px - -    ol -      padding: 0px - -      li -        list-style: none - -    ul -      padding: 0px - -      li -        list-style: none - -    ul.selection li -      a -        padding-left: 20px - -        &.current -          text-decoration: none -          color: black !important -          background: url(image-path('icons/accept.png')) no-repeat - -        &.all -          background-image: none - -    div#compact_form -      form -        border-bottom: 1px solid #BBB - -        fieldset -          padding: 0 -          border: 0 - -          li -            padding: 0 - -            label -              padding-left: 20px -              width: 70% - -              input -                width: 20px - -          fieldset.actions -            margin-bottom: 0 -            padding-left: 20px - -          fieldset.inputs -            padding-top: 16px
\ No newline at end of file diff --git a/app/assets/stylesheets/main/lines.sass b/app/assets/stylesheets/main/lines.sass deleted file mode 100644 index b9bdfae8f..000000000 --- a/app/assets/stylesheets/main/lines.sass +++ /dev/null @@ -1,87 +0,0 @@ -// Place all the styles related to the lines controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ - -#workspace.lines.index -  input[type='checkbox'].multiple_selection -    vertical-align: middle - -  #search -    label -      margin-bottom: 0px - -    input[type='checkbox'] -      margin-left: 3px - -#workspace.lines.edit, -#workspace.lines.new, -#workspace.lines.create, -#workspace.lines.update -  #line_color_old -    width: 100px -    color: white -    font-weight: bold - -  .nested-fields.footnote, .add_footnote -    @extend .col-md-offset-3 - -  .footnotes_block -    margin-bottom: 30px - -#workspace.lines.show -  .summary p -    label -      font-weight: bold - -    .color -      padding: 3px 15px 3px 15px - -  .group_of_line -    .position -      width: 25px -      height: 20px -      float: left -      background-color: #61970B -      font-weight: bold -      color: white -      margin-right: 10px -      padding-left: 4px - -    .color -      background-color: white -      width: 64px -      height: 64px -      float: left -      margin-right: 10px -      border: 1px solid #999 - -      a -        text-decoration: none - -    .name a -      display: inline - -.ce-LineBlock-header-list -  display: table -  width: 100% -  margin: 0 -  padding: 0 - -  > li -    display: table-cell -    vertical-align: middle - -    > input -      margin-top: 0 - -    &:first-child -      width: 37px - -    &:last-child -      text-align: right -      width: 73px - -.ce-LineBlock-header-title -  padding: 0 !important -  line-height: 12px -  font-size: 13px
\ No newline at end of file diff --git a/app/assets/stylesheets/main/multiple_selection.sass b/app/assets/stylesheets/main/multiple_selection.sass deleted file mode 100644 index b46dded01..000000000 --- a/app/assets/stylesheets/main/multiple_selection.sass +++ /dev/null @@ -1,17 +0,0 @@ -input[type='checkbox'].multiple_selection -  margin-left: 0px -  position: absolute -  top: 0px - -#multiple_selection_menu -  h3 -    margin-top: 20px - -  div -    padding: 6px 8px - -  .actions -    margin-top: 20px - -  .select_all, .deselect_all -    font-size: 0.8em
\ No newline at end of file diff --git a/app/assets/stylesheets/main/networks.sass b/app/assets/stylesheets/main/networks.sass deleted file mode 100644 index 4d3717f26..000000000 --- a/app/assets/stylesheets/main/networks.sass +++ /dev/null @@ -1,9 +0,0 @@ -// Place all the styles related to the lines controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ - -// #workspace.networks.index - -#workspace.networks.show -  .summary p label -    font-weight: bold
\ No newline at end of file diff --git a/app/assets/stylesheets/main/organisations.sass b/app/assets/stylesheets/main/organisations.sass deleted file mode 100644 index 4bfee860a..000000000 --- a/app/assets/stylesheets/main/organisations.sass +++ /dev/null @@ -1,5 +0,0 @@ -// Place all the styles related to the lines controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ - -// #workspace.organisations.show
\ No newline at end of file diff --git a/app/assets/stylesheets/main/referentials.sass b/app/assets/stylesheets/main/referentials.sass deleted file mode 100644 index 293807560..000000000 --- a/app/assets/stylesheets/main/referentials.sass +++ /dev/null @@ -1,34 +0,0 @@ -// Place all the styles related to the referentials controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ - -// #workspace.referentials.index - -#workspace.referentials.show -  .summary p label -    font-weight: bold - -  .panel -    font-size: 12px -    width: 75% - -    .panel-heading -      font-weight: bold - -    li.list-group-item -      padding: 5px 15px - -#sidebar div#clean_up -  form -    fieldset -      li -        margin-bottom: 0px - -        &.date -          input -            width: 125px -            font-size: 12px -            height: 25px - -          label -            width: 35%
\ No newline at end of file diff --git a/app/assets/stylesheets/main/route_sections.sass b/app/assets/stylesheets/main/route_sections.sass deleted file mode 100644 index fe3c98c10..000000000 --- a/app/assets/stylesheets/main/route_sections.sass +++ /dev/null @@ -1,54 +0,0 @@ -#workspace.route_sections_selectors.edit -  td.route_section -    .input -      padding: 0 -      margin: 0 - -      select -        width: 100% - -  a.edit-route-section -    background: url(image-path('icons/edit.png')) no-repeat 0% 50% -    text-indent: -9999px -    display: inline-block -    width: 16px -    height: 16px -    margin-right: 8px - -    &.disabled -      background-image: url(image-path('icons/edit-disabled.png')) - -  #map-selection -    position: relative - -    span -      display: inline-block - -    .departure, .arrival -      width: 25% - -    .actions -      width: 25% -      overflow: visible -      padding-left: 0 -      position: absolute -      right: 0 - -#workspace.route_sections.index -  th.distance, th.points -    text-align: center - -  td.distance, td.points, td.actions -    text-align: center - -#workspace.route_sections.edit -  .formtastic -    .input .label -      width: 40% - -    .actions -      padding-left: 19% - -  #map -    width: 600px -    heigth: 600px
\ No newline at end of file diff --git a/app/assets/stylesheets/main/routes.sass b/app/assets/stylesheets/main/routes.sass deleted file mode 100644 index 977d2f4b3..000000000 --- a/app/assets/stylesheets/main/routes.sass +++ /dev/null @@ -1,46 +0,0 @@ -// Place all the styles related to the routes controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ - -// #workspace.lines.show - -#workspace.routes.edit, -#workspace.routes.new, -#workspace.routes.create, -#workspace.routes.update -  #route_color -    width: 100px -    color: white -    font-weight: bold - -  #stop_points .nested-fields -    ol -      margin-left: 25% - -      .handle -        margin-left: 5px - -      .search_stop_area -        margin-bottom: 0px !important - -      div.resize -        height: 40px -        line-height: 40px -        font-size: 16px - -  #stop_points .links -    margin: 10px 0 15px 25% - -#workspace.routes.edit_boarding_alighting -  .stop_area -    padding-top: 7px - -// #workspace.routes.show - -.large-map -  width: 100% -  height: 600px - -  #map -    width: 100% -    height: 100%
\ No newline at end of file diff --git a/app/assets/stylesheets/main/rule_parameter_sets.sass b/app/assets/stylesheets/main/rule_parameter_sets.sass deleted file mode 100644 index ab58b7bf9..000000000 --- a/app/assets/stylesheets/main/rule_parameter_sets.sass +++ /dev/null @@ -1,45 +0,0 @@ -// Place all the styles related to the rule_parameter_sets controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ - -// #workspace.rule_parameter_sets.index - -#workspace.rule_parameter_sets.show, -#workspace.compliance_check_tasks.rule_parameter_set -  .summary label -    font-weight: bold - -  div.attributes_group -    margin: 15px 0 15px 0 - -    .title -      font-weight: bold - -    .columns -      margin-left: 10px - -      div -        display: inline-block - -        &.two_columns -          width: 45% -        &.three_columns -          width: 30% -        &.four_columns -          width: 23% - -        label -          color: #616161 - -        .value -          margin-left: 5px - -  div.rule_parameter_by_mode -    margin: 20px 0 0 0 !important - -    .mode_specific -      display: none -      margin: 0 0 0 10px - -      p label -        color: #616161
\ No newline at end of file diff --git a/app/assets/stylesheets/main/simple_form.sass b/app/assets/stylesheets/main/simple_form.sass deleted file mode 100644 index 143ea692c..000000000 --- a/app/assets/stylesheets/main/simple_form.sass +++ /dev/null @@ -1,3 +0,0 @@ -#workspace -  .submit -    @extend .col-md-offset-3
\ No newline at end of file diff --git a/app/assets/stylesheets/main/stop_areas.sass b/app/assets/stylesheets/main/stop_areas.sass deleted file mode 100644 index f8e1e148a..000000000 --- a/app/assets/stylesheets/main/stop_areas.sass +++ /dev/null @@ -1,165 +0,0 @@ -// Place all the styles related to the lines controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ - -#workspace.stop_areas.index -  #country_codes -    display: none - -#workspace.stop_areas.edit, -#workspace.stop_areas.new, -#workspace.stop_areas.update, -#workspace.stop_areas.create -  legend -    padding-bottom: 20px - -  #prefetch -    padding: 10px 10px 20px 10px - -    label -      font-size: 16px -      margin-right: 25px - -    input -      width: 330px - -  #map -    width: 50% - -#workspace.stop_areas.show -  .geo_data -    padding-left: 15px - -  .summary -    p label -      font-weight: bold - -.genealogical -  .parent -    border: 2px solid black -    float: left -    padding: 3px 15px 3px 3px - -    * -      vertical-align: middle - -    span -      margin-left: 7px -    img -      margin: 0px 5px 0px 5px - -  .lines -    float: left - -    .line -      border: 2px solid black -      padding: 3px 15px 3px 3px -      height: 25px -      margin-bottom: 5px - -      * -        vertical-align: middle - -      span -        margin-left: 7px -      img -        margin: 0px 5px 0px 5px - -  .no_parent -    float: left -    padding: 3px 15px 3px 3px -    width: 150px - -  .target -    border: 2px solid #86b41d -    float: left -    padding: 3px 15px 3px 3px -    font-weight: bold - -    * -      vertical-align: middle - -    span -      margin-left: 7px -    img -      margin: 0px 5px 0px 5px - -  .children -    float: left - -    .child -      border: 2px solid black -      padding: 3px 15px 3px 3px -      margin-bottom: 5px - -      * -        vertical-align: middle - -      span -        margin-left: 7px -      img -        margin: 0px 5px 0px 5px - -  .link -    float: left -    padding: 7px -    margin-right: 10px -    margin-left: 10px -    height: 25px - -#workspace.stop_areas.select_parent -  .token-input-list -    display: inline-block - -#workspace.stop_areas.add_children -  .token-input-list -    display: inline-block - -#workspace.stop_areas.access_links -  .access_link_pairs -    .link -      border: 2px solid black - -    .access_point -      float: left -      padding: 3px 15px 0px 3px -      height: 25px - -      * -        vertical-align: middle - -      span -        margin-left: 7px -      img -        margin: 0px 5px 0px 5px - -    .stop_area -      float: left -      padding: 3px 15px 0px 3px -      height: 25px - -      * -        vertical-align: middle - -      span -        margin-left: 7px -      img -        margin: 0px 5px 0px 5px - -    .info -      font-size: 10px -      color: #777 -      font-weight: normal -      padding-top: 0px -      padding-left: 45px -      padding-right: 3px -      padding-bottom: 3px - -#sidebar ul.selection li -  a -    line-height: 27px - -    img -      height: 25px -      width: 25px -      vertical-align: middle
\ No newline at end of file diff --git a/app/assets/stylesheets/main/stop_points.sass b/app/assets/stylesheets/main/stop_points.sass deleted file mode 100644 index a17814d3b..000000000 --- a/app/assets/stylesheets/main/stop_points.sass +++ /dev/null @@ -1,26 +0,0 @@ -// Place all the styles related to the lines controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ - -#workspace.stop_points.index -  // .stop_points -   -  #sortable_stop_points .stop_point -    /* to create multi-column index */ -    width: 350px -    padding-right: 10px - -    .handle -      cursor: move -      margin-right: 7px -      margin-bottom: 20px - -    a.link -      background: url(image-path('icons/link-small.png')) no-repeat 0% 50% -     -    .position -      background-color: #61970B -      font-weight: bold -      color: white -      margin-right: 10px -      padding-left: 4px
\ No newline at end of file diff --git a/app/assets/stylesheets/main/time_table_combinations.sass b/app/assets/stylesheets/main/time_table_combinations.sass deleted file mode 100644 index 9de2c2235..000000000 --- a/app/assets/stylesheets/main/time_table_combinations.sass +++ /dev/null @@ -1,7 +0,0 @@ -#modal_combine -  .time_table_combination -    .radio input[type='radio'] -      position: inherit !important -     -    .inputs -      overflow: visible !important
\ No newline at end of file diff --git a/app/assets/stylesheets/main/time_tables.sass b/app/assets/stylesheets/main/time_tables.sass deleted file mode 100644 index 6918bec1e..000000000 --- a/app/assets/stylesheets/main/time_tables.sass +++ /dev/null @@ -1,135 +0,0 @@ -// Place all the styles related to the lines controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ - -// #workspace.time_tables.index - -#workspace.time_tables.show -  .modal-body -    overflow-y: visible - -  .summary -    margin-top: 20px - -    p label -      font-weight: bold - -  .legend -    margin-top: 20px - -    .title -      font-weight: bold - -    .excluded_date, .overlaped_date, .selected_date, .selected_period -      margin-left: 20px -      margin-right: 5px - -  .typeahead.dropdown-menu -    z-index: 100001 - -  .validity_out -    color: red - -  .validity_out_soon -    color: orange - -  .validity_regular -    color: green - -  span.included_day_type -    font-weight: bolder -    margin-right: 3px - -  span.excluded_day_type -    margin-right: 3px - -  .period -    padding-left: 50px -    padding-right: 450px - -  .date -    padding-left: 50px - -  .odd -    padding-left: 50px -    padding-right: 450px - -  .even -    padding-left: 50px -    padding-right: 450px - -  .actions -    float: right - -  #associated_calendars -    padding-top: 15px - -#workspace.time_tables.edit, -#workspace.time_tables.new, -#workspace.time_tables.create, -#workspace.time_tables.update, -#workspace.time_tables.duplicate -  fieldset.inputs -    overflow: visible !important - -    .tags -      overflow: visible !important - -  h3 -    .dates -      cursor: pointer - -    .periods -      cursor: pointer - -    .excluded_dates -      cursor: pointer - -  #dates, -  #excluded_dates, -  #periods -    margin-left: 25% - -    .nested-fields -      margin: 5px - -      ol li -        display: inline - -  .day_type ol -    float: left -    margin: 0 -    padding: 0 0 0 0 -    width: 100% -    list_style: none outside none -    margin-top: 1em -    margin-bottom: 1em - -    li -      float: left -      margin: 0 0 0 0 -      width: auto -      padding: 0 - -      label -        padding-left: 10% -        margin-top: 0 - -  .day_type_label -    float: left -    margin-top: 0 -    width: 25% - -  a.add_fields -    margin-left: 25% -    margin-top: 20px -    padding-left: 18px -    background: url(image-path('icons/add.png')) no-repeat 0% 50% - -  a.remove_fields -    margin-left: 10px -    padding-left: 18px -    background: url(image-path('icons/remove.png')) no-repeat 0% 50% - -  .actions -    margin-top: 20px diff --git a/app/assets/stylesheets/main/vehicle_journey_frequencies.sass b/app/assets/stylesheets/main/vehicle_journey_frequencies.sass deleted file mode 100644 index a827cc4d2..000000000 --- a/app/assets/stylesheets/main/vehicle_journey_frequencies.sass +++ /dev/null @@ -1,155 +0,0 @@ -#workspace -  .ce-TimeBandFormTable -    .btn -      white-space: normal -      width: 130px -      font-size: 11px -      padding: 2px 0 - -  .ce-TimeBandFormTable -    th -      text-align: left -      padding: 6px 20px - -    td -      padding: 6px 20px - -  .ce-TimeBandFormTable td -    vertical-align: middle - -  .ce-TimeBandFormTable-circleLine -    position: relative - -  .ce-TimeBandFormTable-line:after -    content: '' -    position: absolute -    top: 0 -    bottom: 0 -    left: 50% -    width: 2px -    margin-left: -1px -    background-color: #61970b - -  tr:first-child td .ce-TimeBandFormTable-line:after -    top: 50% - -  tr:last-child td .ce-TimeBandFormTable-line:after -    bottom: 50% - -  .ce-TimeBandFormTable-circle -    position: relative -    z-index: 999 -    display: block -    width: 16px -    height: 16px -    border-radius: 8px -    background-color: #4d7809 - -  tr:hover .ce-TimeBandFormTable-circle -    background-color: #fff -    border: 2px solid #61970b - -  .ce-FrequencyFormFields -    display: table -    width: 100% -    padding-left: 25% - -    .token-input-list -      width: 80% - -    .inline-errors -      margin: 0 - -    > li -      display: table-cell -      width: 21% -      vertical-align: top -      padding: 0 -      margin: 0 - -      &:first-child select -        width: 160px - -      &:nth-last-child(2), &:last-child -        width: 8% - -      label -        font-size: 13px -        padding-left: 0 - -      legend -        position: relative -        width: auto -        float: none -        border: 0 -         -        label -          position: relative - -      .fragments-group -        float: none -        width: auto -        padding: 0 - -        > li -          display: inline-block -          vertical-align: top - -  &.vehicle_journey_frequencies -    .actions-add-fields -      clear: both -      padding-left: 25% -      margin-top: 10px - -  td.ce-VehicleJourneyBlock-frequency -    background-color: rgba(95, 95, 95, 0.2) - -  .ce-VehicleJourneyFrequencyTableBlock -    margin: 0 !important - -  .ce-VehicleJourneyFrequenciesMatrix -    margin: 0 -    padding: 0 - -    > li -      background-color: #eee -      height: 22px -      margin-bottom: 20px -      position: relative - -      > ul -        margin: 0 -        padding: 0 - -        > li -          cursor: pointer -          position: absolute -          padding: 0 2px -          top: 0 -          bottom: 0 -          background-color: $brand-primary -          border-left: 1px solid #000 -          border-right: 1px solid #000 - -          &:hover -            z-index: 9999 -            background-color: #4d7809 -            top: -2px -            bottom: -2px - -            > span -              display: block - -  .ce-VehicleJourneyFrequenciesMatrix-firstDepartureTime, -  .ce-VehicleJourneyFrequenciesMatrix-lastDepartureTime -    display: none -    position: absolute -    top: -13px -    font-size: 11px -    color: #262626 - -  .ce-VehicleJourneyFrequenciesMatrix-firstDepartureTime -    left: -32px - -  .ce-VehicleJourneyFrequenciesMatrix-lastDepartureTime -    right: -32px
\ No newline at end of file diff --git a/app/assets/stylesheets/main/vehicle_journeys.sass b/app/assets/stylesheets/main/vehicle_journeys.sass deleted file mode 100644 index ec0b25dbc..000000000 --- a/app/assets/stylesheets/main/vehicle_journeys.sass +++ /dev/null @@ -1,118 +0,0 @@ -#workspace.vehicle_journeys.edit, -#workspace.vehicle_journeys.update, -#workspace.vehicle_journeys.create, -#workspace.vehicle_journeys.new, -#workspace.vehicle_journey_frequencies.edit, -#workspace.vehicle_journey_frequencies.update, -#workspace.vehicle_journey_frequencies.create, -#workspace.vehicle_journey_frequencies.new -  #route_color -    width: 100px -    color: white -    font-weight: bold - -  .btn -    padding: 6px 12px - -  .time_table_list -    padding-left: 25% - -  #vehicle_journey_footnote_ids_input, -  #vehicle_journey_frequency_footnote_ids_input -    min-height: 3em - -  .vehicle_journey_at_stops, -  .vehicle_journey_frequency_at_stops -    margin-left: 25% - -    thead, tbody, tfoot -      th, td -        text-align: center - -    .journey_pattern_dependent_list -      tr.no_stop -        display: none - -      td.departure_time, td.arrival_time -        &.missing -          background-color: $brand-warning - -        &.invalid_position -          background-color: $brand-danger - -    .title -      font-weight: bold -      margin-bottom: 20px - -    span -      margin-left: 10px -      margin-right: 10px - -    .slide -      margin-left: 30px - -#workspace.vehicle_journeys.index, -#workspace.vehicle_journey_frequencies.index -  #search -    ul.token-input-list -      display: inline-block -      vertical-align: middle -      margin-left: 15px - -    .advanced_search -      margin-left: 40px - -    .time_tables_id_eq -      margin-left: 20px - -    .vehicle_journey_at_stops_departure_time_gt -      margin-left: 20px - -  table -    margin: 20px 0 0 0 - -    .calendars -      font-size: 12px - -    .stop_area -      width: 200px - -    td.hours -      text-align: center - -    tr th.vehicle_journey -      text-align: center - -#workspace.vehicle_journeys.show, -#workspace.vehicle_journeys.edit, -#workspace.vehicle_journeys.update, -#workspace.vehicle_journeys.create, -#workspace.vehicle_journeys.new, -#workspace.vehicle_journey_journey.show, -#workspace.vehicle_journey_journey.edit, -#workspace.vehicle_journey_journey.update, -#workspace.vehicle_journey_journey.create, -#workspace.vehicle_journey_journey.new -  .slide -    cursor: pointer - -#workspace.vehicle_journeys.show, -#workspace.vehicle_journey_frequencies.show -  .summary p label -    font-weight: bold - -#workspace.vehicle_journeys.timeless, -#workspace.vehicle_journey_frequencies.timeless -  .summary p label -    font-weight: bold - -  .vehicle_journeys, -  .vehicle_journey_frequencies -    margin-top: 20px - -  .vehicle_journey, -  .vehicle_journey_frequency -    span.included_day_type -      font-weight: bolder - -    // span.excluded_day_type
\ No newline at end of file diff --git a/app/assets/stylesheets/main/vehicle_translation.sass b/app/assets/stylesheets/main/vehicle_translation.sass deleted file mode 100644 index f1fd12e14..000000000 --- a/app/assets/stylesheets/main/vehicle_translation.sass +++ /dev/null @@ -1,10 +0,0 @@ -#translate_form -  .repeat_cloning -    margin-top: 30px - -  .modal-footer -    .actions -      padding-left: 75% - -      li -        margin: 0
\ No newline at end of file diff --git a/app/assets/stylesheets/modules/import_messages.sass b/app/assets/stylesheets/modules/import_messages.sass new file mode 100644 index 000000000..e5666cbcd --- /dev/null +++ b/app/assets/stylesheets/modules/import_messages.sass @@ -0,0 +1,5 @@ +.import_messages +  .status_icon +    padding-right: 20px +  h1 +    padding-bottom: 20px  diff --git a/app/controllers/api/v1/netex_imports_controller.rb b/app/controllers/api/v1/netex_imports_controller.rb index 046802ff9..fc85e35dd 100644 --- a/app/controllers/api/v1/netex_imports_controller.rb +++ b/app/controllers/api/v1/netex_imports_controller.rb @@ -41,7 +41,7 @@ module Api          unless @netex_import.referential            Rails.logger.info "Can't create referential for import #{@netex_import.id}: #{@new_referential.inspect} #{@new_referential.metadatas.inspect} #{@new_referential.errors.full_messages}" -          @netex_import.messages.create criticity: :error, message_key: "cant_create_referential" +          @netex_import.messages.create criticity: :error, message_key: "referential_creation"          end        rescue ActiveRecord::RecordInvalid          render json: {errors: @netex_import.errors}, status: 406 diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 47b54039c..853c2f715 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -33,8 +33,14 @@ class ApplicationController < ActionController::Base    end    helper_method :current_organisation +  def current_offer_workbench +    current_organisation.workbenches.find_by_name("Gestion de l'offre") +  end +  helper_method :current_offer_workbench +    def current_functional_scope -    JSON.parse(current_organisation.sso_attributes["functional_scope"]) if current_organisation +    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 diff --git a/app/controllers/autocomplete_time_tables_controller.rb b/app/controllers/autocomplete_time_tables_controller.rb index 375928aeb..f65f5b9f6 100644 --- a/app/controllers/autocomplete_time_tables_controller.rb +++ b/app/controllers/autocomplete_time_tables_controller.rb @@ -9,7 +9,7 @@ class AutocompleteTimeTablesController < InheritedResources::Base    end    def referential -    @referential ||= current_organisation.referentials.find params[:referential_id] +    @referential ||= Referential.find params[:referential_id]    end    protected @@ -22,7 +22,12 @@ class AutocompleteTimeTablesController < InheritedResources::Base      scope.distinct    end +  def split_params! search +    params[:q][search] = params[:q][search].split(" ") if params[:q][search] +  end +    def collection +    split_params! :comment_or_objectid_cont_any      @time_tables = select_time_tables.search(params[:q]).result.paginate(page: params[:page])    end  end diff --git a/app/controllers/import_messages_controller.rb b/app/controllers/import_messages_controller.rb index 64eec92dd..4ad398cbb 100644 --- a/app/controllers/import_messages_controller.rb +++ b/app/controllers/import_messages_controller.rb @@ -9,7 +9,7 @@ class ImportMessagesController < BreadcrumbController    def index      index! do |format|        format.csv { -        send_data ImportMessageExport.new(:import_messages => @import_messages).to_csv(:col_sep => ";") , :filename => "test.csv" +        send_data ImportMessageExport.new(:import_messages => @import_messages).to_csv(:col_sep => ";") , :filename => "#{File.basename(@import_resource.name)}_#{Time.now.to_i}.csv"        }      end    end diff --git a/app/controllers/imports_controller.rb b/app/controllers/imports_controller.rb index b1b34731b..2bd8cc6f4 100644 --- a/app/controllers/imports_controller.rb +++ b/app/controllers/imports_controller.rb @@ -1,6 +1,7 @@  class ImportsController < BreadcrumbController    skip_before_action :authenticate_user!, only: [:download]    defaults resource_class: Import, collection_name: 'imports', instance_name: 'import' +  before_action :ransack_started_at_params, only: [:index]    respond_to :html    belongs_to :workbench @@ -44,7 +45,11 @@ class ImportsController < BreadcrumbController    protected    def collection -    @q = parent.imports.where(type: "WorkbenchImport").search(params[:q]) + +    scope = parent.imports.where(type: "WorkbenchImport") +    scope = ransack_period scope + +    @q = scope.search(params[:q].try(:except, :started_at))      if sort_column && sort_direction        @imports ||= @q.result(distinct: true).order(sort_column + ' ' + sort_direction).paginate(page: params[:page], per_page: 10) @@ -55,6 +60,33 @@ class ImportsController < BreadcrumbController    private +  def ransack_started_at_params +    start_date = [] +    end_date = [] + +    if params[:q] && params[:q][:started_at] && !params[:q][:started_at].has_value?(nil) +      [1, 2, 3].each do |key| +        start_date <<  params[:q][:started_at]["begin(#{key}i)"].to_i +        end_date <<  params[:q][:started_at]["end(#{key}i)"].to_i +      end +      params[:q].delete([:started_at]) +      @begin_range = DateTime.new(*start_date,0,0,0) rescue nil +      @end_range = DateTime.new(*end_date,23,59,59) rescue nil +    end +  end + +  # Fake ransack filter +  def ransack_period scope +    return scope unless !!@begin_range && !!@end_range + +    if @begin_range > @end_range +      flash.now[:error] = t('imports.filters.error_period_filter') +    else +      scope = scope.where_started_at_between(@begin_range, @end_range) +    end +    scope +  end +    def build_resource      @import ||= WorkbenchImport.new(*resource_params) do |import|        import.workbench = parent diff --git a/app/controllers/referentials_controller.rb b/app/controllers/referentials_controller.rb index a6dfaf2b6..c8984076a 100644 --- a/app/controllers/referentials_controller.rb +++ b/app/controllers/referentials_controller.rb @@ -7,18 +7,19 @@ class ReferentialsController < BreadcrumbController    respond_to :js, :only => :show    def new -    if params[:from] -      source_referential = Referential.find(params[:from]) -      @referential = Referential.new_from(source_referential, current_functional_scope) -      @referential.workbench_id = current_organisation.workbenches.first.id +    new! do +      build_referenial      end +  end -    new! do -      @referential.data_format = current_organisation.data_format -      @referential.workbench_id ||= params[:workbench_id] +  def create +    create! do |format| +      build_referenial -      if @referential.in_workbench? -        @referential.init_metadatas default_date_range: Range.new(Date.today, Date.today.advance(months: 1)) +      if !!@referential.created_from_id +        format.html { redirect_to workbench_path(@referential.workbench) } +      else +        build_breadcrumb :new        end      end    end @@ -26,7 +27,7 @@ class ReferentialsController < BreadcrumbController    def show      resource.switch      show! do |format| -      @referential = @referential.decorate +      @referential = @referential.decorate(context: { current_workbench_id: params[:current_workbench_id] } )        @reflines = lines_collection.paginate(page: params[:page], per_page: 10)        @reflines = ModelDecorator.decorate(          @reflines, @@ -124,6 +125,21 @@ class ReferentialsController < BreadcrumbController      super    end +  def build_referenial +    if params[:from] +      source_referential = Referential.find(params[:from]) +      @referential = Referential.new_from(source_referential, current_functional_scope) +      @referential.workbench_id = params[:current_workbench_id] +    end + +    @referential.data_format = current_organisation.data_format +    @referential.workbench_id ||= params[:workbench_id] + +    if @referential.in_workbench? +      @referential.init_metadatas default_date_range: Range.new(Date.today, Date.today.advance(months: 1)) +    end +  end +    private    def sort_column      sortable_columns = Chouette::Line.column_names + ['networks.name', 'companies.name'] diff --git a/app/controllers/routes_controller.rb b/app/controllers/routes_controller.rb index 7ba2c1a58..04f63c112 100644 --- a/app/controllers/routes_controller.rb +++ b/app/controllers/routes_controller.rb @@ -69,11 +69,11 @@ class RoutesController < ChouetteController      end    end - # def update -   # update! do |success, failure| -   #   success.html { redirect_to referential_line_path(@referential,@line) } -   # end - # end +  def duplicate +    route = Chouette::Route.find(params[:id]).duplicate +    redirect_to edit_referential_line_route_path(@referential, route.line, route) +  end +    protected    alias_method :route, :resource diff --git a/app/controllers/workbenches_controller.rb b/app/controllers/workbenches_controller.rb index 19af28a98..54ddb8be1 100644 --- a/app/controllers/workbenches_controller.rb +++ b/app/controllers/workbenches_controller.rb @@ -20,8 +20,13 @@ class WorkbenchesController < BreadcrumbController      @q_for_form   = scope.ransack(params[:q])      @q_for_result = scope.ransack(ransack_params)      @wbench_refs  = sort_result(@q_for_result.result).paginate(page: params[:page], per_page: 30) -    @wbench_refs  = ModelDecorator.decorate(@wbench_refs, with: ReferentialDecorator) - +    @wbench_refs  = ModelDecorator.decorate( +      @wbench_refs, +      with: ReferentialDecorator, +      context: { +        current_workbench_id: params[:id] +      } +    )      show! do        build_breadcrumb :show      end diff --git a/app/decorators/referential_decorator.rb b/app/decorators/referential_decorator.rb index ccb47a654..dccf0052c 100644 --- a/app/decorators/referential_decorator.rb +++ b/app/decorators/referential_decorator.rb @@ -13,7 +13,7 @@ class ReferentialDecorator < Draper::Decorator      if policy.clone?        links << Link.new(          content: h.t('actions.clone'), -        href: h.new_referential_path(from: object.id) +        href: h.new_referential_path(from: object.id, current_workbench_id: context[:current_workbench_id])        )      end      if policy.archive? diff --git a/app/decorators/route_decorator.rb b/app/decorators/route_decorator.rb index 484c3db04..46cb6cd5f 100644 --- a/app/decorators/route_decorator.rb +++ b/app/decorators/route_decorator.rb @@ -58,6 +58,18 @@ class RouteDecorator < Draper::Decorator        )      end +    if h.policy(object).duplicate? +      links << Link.new( +        content: h.t('routes.duplicate.title'), +        href: h.duplicate_referential_line_route_path( +          context[:referential], +          context[:line], +          object +        ), +        method: :post +      ) +    end +      links    end  end diff --git a/app/models/chouette/access_point.rb b/app/models/chouette/access_point.rb index 476f13c08..4a1ae8a0e 100644 --- a/app/models/chouette/access_point.rb +++ b/app/models/chouette/access_point.rb @@ -4,6 +4,7 @@ require 'geo_ruby'  class Chouette::AccessPoint < Chouette::ActiveRecord    # FIXME http://jira.codehaus.org/browse/JRUBY-6358    self.primary_key = "id" +    include StifReflexAttributesSupport    include Geokit::Mappable    include ProjectionFields @@ -23,12 +24,15 @@ class Chouette::AccessPoint < Chouette::ActiveRecord    validates_numericality_of :longitude, :less_than_or_equal_to => 180, :greater_than_or_equal_to => -180, :allow_nil => true    validates_format_of :coordinates, :with => %r{\A *-?(0?[0-9](\.[0-9]*)?|[0-8][0-9](\.[0-9]*)?|90(\.[0]*)?) *\, *-?(0?[0-9]?[0-9](\.[0-9]*)?|1[0-7][0-9](\.[0-9]*)?|180(\.[0]*)?) *\Z}, :allow_nil => true, :allow_blank => true - +  before_save :coordinates_to_lat_lng    def self.nullable_attributes      [:street_name, :country_code, :comment, :long_lat_type, :zip_code, :city_name]    end -  before_save :coordinates_to_lat_lng + +  def referential +    @referential ||= Referential.where(:slug => Apartment::Tenant.current).first! +  end    def referential      @referential ||= Referential.where(:slug => Apartment::Tenant.current).first! diff --git a/app/models/chouette/active_record.rb b/app/models/chouette/active_record.rb index 1862319af..e12f30266 100644 --- a/app/models/chouette/active_record.rb +++ b/app/models/chouette/active_record.rb @@ -2,10 +2,8 @@  require 'deep_cloneable'  module Chouette    class ActiveRecord < ::ActiveRecord::Base -      self.abstract_class = true - -    before_save :nil_if_blank +    before_save :nil_if_blank, :set_data_source_ref      # to be overridden to set nullable attrs when empty      def self.nullable_attributes @@ -16,17 +14,22 @@ module Chouette        self.class.nullable_attributes.each { |attr| self[attr] = nil if self[attr].blank? }      end -      def human_attribute_name(*args)        self.class.human_attribute_name(*args)      end +    def set_data_source_ref +      if self.respond_to?(:data_source_ref) +        self.data_source_ref ||= 'DATASOURCEREF_EDITION_BOIV' +      end +    end +      # TODO: Can we remove this?      # class << self      #   alias_method :create_reflection_without_chouette_naming, :create_reflection      #   def create_reflection(macro, name, options, active_record) -    #     options =  +    #     options =      #       Reflection.new(macro, name, options, active_record).options_with_default      #     create_reflection_without_chouette_naming(macro, name, options, active_record) diff --git a/app/models/chouette/company.rb b/app/models/chouette/company.rb index 7b96e875e..a472020e1 100644 --- a/app/models/chouette/company.rb +++ b/app/models/chouette/company.rb @@ -1,6 +1,6 @@  class Chouette::Company < Chouette::ActiveRecord    include CompanyRestrictions -  include DefaultNetexAttributesSupport +  include StifCodifligneAttributesSupport    include LineReferentialSupport    has_many :lines diff --git a/app/models/chouette/group_of_line.rb b/app/models/chouette/group_of_line.rb index d954c6699..a987d6311 100644 --- a/app/models/chouette/group_of_line.rb +++ b/app/models/chouette/group_of_line.rb @@ -1,5 +1,5 @@  class Chouette::GroupOfLine < Chouette::ActiveRecord -  include DefaultNetexAttributesSupport +  include StifCodifligneAttributesSupport    include GroupOfLineRestrictions    include LineReferentialSupport diff --git a/app/models/chouette/journey_pattern.rb b/app/models/chouette/journey_pattern.rb index fa5fba26d..fa2a9c8bb 100644 --- a/app/models/chouette/journey_pattern.rb +++ b/app/models/chouette/journey_pattern.rb @@ -21,6 +21,11 @@ class Chouette::JourneyPattern < Chouette::TridentActiveRecord    attr_accessor  :control_checked    after_update :control_route_sections, :unless => "control_checked" + +  def local_id +    "IBOO-#{self.referential.id}-#{self.try(:route).try(:line).try(:objectid).try(:local_id)}-#{self.id}" +  end +    def checksum_attributes      values = self.slice(*['name', 'published_name', 'registration_number']).values      values << self.stop_points.map(&:stop_area).map(&:user_objectid) diff --git a/app/models/chouette/network.rb b/app/models/chouette/network.rb index 690c39344..8df205789 100644 --- a/app/models/chouette/network.rb +++ b/app/models/chouette/network.rb @@ -1,5 +1,5 @@  class Chouette::Network < Chouette::ActiveRecord -  include DefaultNetexAttributesSupport +  include StifCodifligneAttributesSupport    include NetworkRestrictions    include LineReferentialSupport    # FIXME http://jira.codehaus.org/browse/JRUBY-6358 diff --git a/app/models/chouette/route.rb b/app/models/chouette/route.rb index 6774e8a86..49493d5b5 100644 --- a/app/models/chouette/route.rb +++ b/app/models/chouette/route.rb @@ -16,6 +16,7 @@ class Chouette::Route < Chouette::TridentActiveRecord    end    belongs_to :line +  belongs_to :opposite_route, :class_name => 'Chouette::Route', :foreign_key => :opposite_route_id    has_many :routing_constraint_zones    has_many :journey_patterns, :dependent => :destroy @@ -30,7 +31,6 @@ class Chouette::Route < Chouette::TridentActiveRecord        Chouette::Route.vehicle_journeys_timeless(proxy_association.owner.journey_patterns.pluck( :departure_stop_point_id))      end    end -  belongs_to :opposite_route, :class_name => 'Chouette::Route', :foreign_key => :opposite_route_id    has_many :stop_points, -> { order("position") }, :dependent => :destroy do      def find_by_stop_area(stop_area)        stop_area_ids = Integer === stop_area ? [stop_area] : (stop_area.children_in_depth + [stop_area]).map(&:id) @@ -56,12 +56,13 @@ class Chouette::Route < Chouette::TridentActiveRecord    end    has_many :stop_areas, -> { order('stop_points.position ASC') }, :through => :stop_points do      def between(departure, arrival) -      departure, arrival = [departure, arrival].collect do |endpoint| +      departure, arrival = [departure, arrival].map do |endpoint|          String === endpoint ? Chouette::StopArea.find_by_objectid(endpoint) : endpoint        end        proxy_owner.stop_points.between(departure, arrival).includes(:stop_area).collect(&:stop_area)      end    end +    accepts_nested_attributes_for :stop_points, :allow_destroy => :true    validates_presence_of :name @@ -75,6 +76,32 @@ class Chouette::Route < Chouette::TridentActiveRecord    after_commit :journey_patterns_control_route_sections +  def duplicate +    overrides = { +      'opposite_route_id' => nil +    } +    keys_for_create = attributes.keys - %w{id objectid created_at updated_at} +    atts_for_create = attributes +      .slice(*keys_for_create) +      .merge(overrides) +    new_route = self.class.create!(atts_for_create) +    duplicate_stop_points(for_route: new_route) +    new_route +  end + +  def duplicate_stop_points(for_route:) +    stop_points.each(&duplicate_stop_point(for_route: for_route)) +  end +  def duplicate_stop_point(for_route:) +    -> stop_point do +      stop_point.duplicate(for_route: for_route) +    end +  end + +  def local_id +    "IBOO-#{self.referential.id}-#{self.line.objectid.local_id}-#{self.id}" +  end +    def geometry_presenter      Chouette::Geometry::RoutePresenter.new self    end diff --git a/app/models/chouette/routing_constraint_zone.rb b/app/models/chouette/routing_constraint_zone.rb index 9931748b2..efe1b7237 100644 --- a/app/models/chouette/routing_constraint_zone.rb +++ b/app/models/chouette/routing_constraint_zone.rb @@ -8,6 +8,10 @@ class Chouette::RoutingConstraintZone < Chouette::TridentActiveRecord    # validates :stop_point_ids, length: { minimum: 2, too_short: I18n.t('activerecord.errors.models.routing_constraint_zone.attributes.stop_points.not_enough_stop_points') }    validate :stop_points_belong_to_route, :not_all_stop_points_selected +  def local_id +    "IBOO-#{self.referential.id}-#{self.route.line.objectid.local_id}-#{self.route.objectid.local_id}-#{self.id}" +  end +    scope :order_by_stop_points_count, ->(direction) do      order("array_length(stop_point_ids, 1) #{direction}")    end diff --git a/app/models/chouette/stif_netex_objectid.rb b/app/models/chouette/stif_netex_objectid.rb new file mode 100644 index 000000000..3b11691d9 --- /dev/null +++ b/app/models/chouette/stif_netex_objectid.rb @@ -0,0 +1,38 @@ +class Chouette::StifNetexObjectid < String +  def valid? +    parts.present? +  end + +  @@format = /^([A-Za-z_]+):([A-Za-z]+):([0-9A-Za-z_-]+):([A-Za-z]+)$/ +  cattr_reader :format + +  def parts +    match(format).try(:captures) +  end + +  def provider_id +    parts.try(:first) +  end + +  def object_type +    parts.try(:second) +  end + +  def local_id +    parts.try(:third) +  end + +  def boiv_id +    parts.try(:fourth) +  end + +  def self.create(provider_id, object_type, local_id, boiv_id) +    new [provider_id, object_type, local_id, boiv_id].join(":") +  end + +  def self.new(string) +    string ||= "" +    self === string ? string : super +  end + +end diff --git a/app/models/chouette/stop_point.rb b/app/models/chouette/stop_point.rb index 8fe79dc0c..89c492b91 100644 --- a/app/models/chouette/stop_point.rb +++ b/app/models/chouette/stop_point.rb @@ -20,6 +20,11 @@ module Chouette      validates_presence_of :stop_area      validate :stop_area_id_validation +    def stop_area_id_validation +      if stop_area_id.nil? +        errors.add(:stop_area_id, I18n.t("stop_areas.errors.empty")) +      end +    end      scope :default_order, -> { order("position") } @@ -34,10 +39,12 @@ module Chouette        end      end -    def stop_area_id_validation -      if stop_area_id.nil? -        errors.add(:stop_area_id, I18n.t("stop_areas.errors.empty")) -      end +    def duplicate(for_route:) +      keys_for_create = attributes.keys - %w{id objectid created_at updated_at} +      atts_for_create = attributes +        .slice(*keys_for_create) +        .merge('route_id' => for_route.id) +      self.class.create!(atts_for_create)      end      def self.area_candidates diff --git a/app/models/chouette/time_table.rb b/app/models/chouette/time_table.rb index 8aff3bf36..8821a5201 100644 --- a/app/models/chouette/time_table.rb +++ b/app/models/chouette/time_table.rb @@ -31,6 +31,10 @@ class Chouette::TimeTable < Chouette::TridentActiveRecord    after_save :save_shortcuts +  def local_id +    "IBOO-#{self.referential.id}-#{self.id}" +  end +    def checksum_attributes      [].tap do |attrs|        attrs << self.int_day_types @@ -557,8 +561,7 @@ class Chouette::TimeTable < Chouette::TridentActiveRecord    end    def duplicate -    tt = self.deep_clone :include => [:periods, :dates], :except => :object_version -    tt.uniq_objectid +    tt = self.deep_clone :include => [:periods, :dates], :except => [:object_version, :objectid]      tt.tag_list.add(*self.tag_list) unless self.tag_list.empty?      tt.created_from = self      tt.comment      = I18n.t("activerecord.copy", :name => self.comment) diff --git a/app/models/chouette/trident_active_record.rb b/app/models/chouette/trident_active_record.rb index c1bc0172b..e8223e3d6 100644 --- a/app/models/chouette/trident_active_record.rb +++ b/app/models/chouette/trident_active_record.rb @@ -1,5 +1,5 @@  class Chouette::TridentActiveRecord < Chouette::ActiveRecord -  include DefaultAttributesSupport +  include StifNetexAttributesSupport    self.abstract_class = true diff --git a/app/models/chouette/vehicle_journey.rb b/app/models/chouette/vehicle_journey.rb index d5ca58959..f574afc93 100644 --- a/app/models/chouette/vehicle_journey.rb +++ b/app/models/chouette/vehicle_journey.rb @@ -56,6 +56,10 @@ module Chouette        end      end +    def local_id +      "IBOO-#{self.referential.id}-#{self.route.line.objectid.local_id}-#{self.id}" +    end +      def checksum_attributes        [].tap do |attrs|          attrs << self.published_journey_name diff --git a/app/models/concerns/line_referential_support.rb b/app/models/concerns/line_referential_support.rb index 4ad437fed..406730ddb 100644 --- a/app/models/concerns/line_referential_support.rb +++ b/app/models/concerns/line_referential_support.rb @@ -3,18 +3,10 @@ module LineReferentialSupport    included do      belongs_to :line_referential -    # validates_presence_of :line_referential_id -      alias_method :referential, :line_referential    end    def hub_restricted?      false    end - -  def prefix -    # FIXME #825 -    "dummy" -  end -  end diff --git a/app/models/concerns/stif_netex_attributes_support.rb b/app/models/concerns/stif_netex_attributes_support.rb new file mode 100644 index 000000000..795872755 --- /dev/null +++ b/app/models/concerns/stif_netex_attributes_support.rb @@ -0,0 +1,58 @@ +module StifNetexAttributesSupport +  extend ActiveSupport::Concern + +  included do +    validates_numericality_of :object_version +    validates :objectid, uniqueness: true, presence: true +    validate :objectid_format_compliance + +    after_save :build_objectid +    before_validation :default_values, on: :create +  end + +  module ClassMethods +    def object_id_key +      model_name +    end + +    def model_name +      ActiveModel::Name.new self, Chouette, self.name.demodulize +    end +  end + +  def objectid_format_compliance +    errors.add :objectid, I18n.t("activerecord.errors.models.trident.invalid_object_id") if !objectid.valid? +  end + +  def local_id +    "IBOO-#{self.referential.id}-#{self.id}" +  end + +  def build_objectid +    if objectid.include? ':__pending_id__' +      self.objectid = Chouette::StifNetexObjectid.create(self.provider_id, self.model_name, self.local_id, self.boiv_id) +      self.save +    end +  end + +  def default_values +    self.object_version ||= 1 + +    if self.objectid.to_s.empty? +      local_id = "__pending_id__#{rand(50)+ rand(50)}" +      self.objectid = Chouette::StifNetexObjectid.create(self.provider_id, self.model_name, local_id, self.boiv_id) +    end +  end + +  def objectid +    Chouette::StifNetexObjectid.new read_attribute(:objectid) +  end + +  def provider_id +    self.referential.workbench.organisation.name.parameterize +  end + +  def boiv_id +    'LOC' +  end +end diff --git a/app/models/concerns/stop_area_referential_support.rb b/app/models/concerns/stop_area_referential_support.rb index 5a01ef57e..aa59cbd35 100644 --- a/app/models/concerns/stop_area_referential_support.rb +++ b/app/models/concerns/stop_area_referential_support.rb @@ -3,17 +3,10 @@ module StopAreaReferentialSupport    included do      belongs_to :stop_area_referential -    # validates_presence_of :stop_area_referential_id -      alias_method :referential, :stop_area_referential    end    def hub_restricted?      false    end - -  def prefix -    # FIXME #825 -    "dummy" -  end  end diff --git a/app/models/data_format_enumerations.rb b/app/models/data_format_enumerations.rb index 94c39e152..787ab6cca 100644 --- a/app/models/data_format_enumerations.rb +++ b/app/models/data_format_enumerations.rb @@ -1,6 +1,6 @@  module DataFormatEnumerations    extend Enumerize    extend ActiveModel::Naming -   -  enumerize :data_format, in: %w[neptune netex gtfs hub], default: "neptune" + +  enumerize :data_format, in: %w[neptune netex gtfs hub], default: "netex"  end diff --git a/app/models/export_report.rb b/app/models/export_report.rb index ef54f40ea..3c0788106 100644 --- a/app/models/export_report.rb +++ b/app/models/export_report.rb @@ -1,9 +1,8 @@  class ExportReport -  include ReportConcern +  #include ReportConcern    def initialize( response )      @datas = response.action_report    end -   -end +end diff --git a/app/models/import.rb b/app/models/import.rb index ff2f57efc..74f7ef10c 100644 --- a/app/models/import.rb +++ b/app/models/import.rb @@ -9,8 +9,12 @@ class Import < ActiveRecord::Base    has_many :resources, class_name: "ImportResource", dependent: :destroy    has_many :children, foreign_key: :parent_id, class_name: "Import", dependent: :destroy +  scope :where_started_at_between, ->(start_date, end_date) do +     where('started_at BETWEEN ? AND ?', start_date, end_date) +   end +    extend Enumerize -  enumerize :status, in: %i(new pending successful warning failed running aborted canceled), scope: true +  enumerize :status, in: %i(new pending successful warning failed running aborted canceled), scope: true, default: :new    validates :file, presence: true    validates_presence_of :workbench, :creator @@ -89,7 +93,6 @@ class Import < ActiveRecord::Base    def initialize_fields      self.token_download = SecureRandom.urlsafe_base64 -    self.status = Import.status.new    end    def self.symbols_with_indifferent_access(array) diff --git a/app/models/import_message.rb b/app/models/import_message.rb index 913f6fd41..5d0f5c862 100644 --- a/app/models/import_message.rb +++ b/app/models/import_message.rb @@ -1,6 +1,6 @@  class ImportMessage < ActiveRecord::Base    belongs_to :import -  belongs_to :resource, class_name: ImportResource, dependent: :destroy +  belongs_to :resource, class_name: ImportResource    enum criticity: [:info, :warning, :error]    validates :criticity, presence: true diff --git a/app/models/import_message_export.rb b/app/models/import_message_export.rb index d13a3a21b..88d0f27e2 100644 --- a/app/models/import_message_export.rb +++ b/app/models/import_message_export.rb @@ -22,23 +22,14 @@ class ImportMessageExport    end    def column_names -    ["criticity", "message key"] +    ["criticity", "message key", "message"]    end - -  # t.integer  "criticity" -  # t.string   "message_key" -  # t.hstore   "message_attributes" -  # t.integer  "import_id",           limit: 8 -  # t.integer  "resource_id",         limit: 8 -  # t.datetime "created_at" -  # t.datetime "updated_at" -  # t.hstore   "resource_attributes"    def to_csv(options = {})      CSV.generate(options) do |csv|        csv << column_names        import_messages.each do |import_message| -        csv << [import_message.criticity, import_message.message_key ] +        csv << [import_message.criticity, import_message.message_key, I18n.t("import_messages.compliance_check_messages.#{import_message.message_key}", import_message.message_attributes.deep_symbolize_keys) ]        end      end    end diff --git a/app/models/import_report.rb b/app/models/import_report.rb index 1dc556e1c..ba13f0118 100644 --- a/app/models/import_report.rb +++ b/app/models/import_report.rb @@ -1,9 +1,8 @@ -class ImportReport   -  include ReportConcern +class ImportReport +  #include ReportConcern    def initialize( response )      @datas = response.action_report    end -   -end +end diff --git a/app/models/netex_import.rb b/app/models/netex_import.rb index 90ac42f2c..32939a741 100644 --- a/app/models/netex_import.rb +++ b/app/models/netex_import.rb @@ -6,7 +6,6 @@ class NetexImport < Import    def launch_java_import      return if self.class.finished_statuses.include?(status) -    logger.warn  "Call iev get #{Rails.configuration.iev_url}/boiv_iev/referentials/importer/new?id=#{id}"      Thread.new do        begin diff --git a/app/models/referential.rb b/app/models/referential.rb index ecfc69c4a..af08aa868 100644 --- a/app/models/referential.rb +++ b/app/models/referential.rb @@ -1,3 +1,4 @@ +# coding: utf-8  class Referential < ActiveRecord::Base    include DataFormatEnumerations @@ -10,7 +11,9 @@ class Referential < ActiveRecord::Base    # validates_presence_of :lower_corner    validates_uniqueness_of :slug -  validates_uniqueness_of :name + +  validates_presence_of :line_referential +  validates_presence_of :stop_area_referential    validates_format_of :slug, :with => %r{\A[a-z][0-9a-z_]+\Z}    validates_format_of :prefix, :with => %r{\A[0-9a-zA-Z_]+\Z}    validates_format_of :upper_corner, :with => %r{\A-?[0-9]+\.?[0-9]*\,-?[0-9]+\.?[0-9]*\Z} @@ -180,12 +183,10 @@ class Referential < ActiveRecord::Base      projection_type || ""    end -  before_validation :assign_line_and_stop_area_referential, :on => :create, if: :workbench, unless: :created_from -  before_validation :clone_associations, :on => :create, if: :created_from +  before_validation :assign_line_and_stop_area_referential, :on => :create, if: :workbench    before_validation :assign_slug, :on => :create    before_validation :assign_prefix, :on => :create    before_create :create_schema -    after_create :clone_schema, if: :created_from    before_destroy :destroy_schema @@ -203,18 +204,6 @@ class Referential < ActiveRecord::Base      end    end -  def clone_associations -    self.line_referential      = created_from.line_referential -    self.stop_area_referential = created_from.stop_area_referential -    self.workbench             = created_from.workbench -  end - -  def clone_metadatas -    created_from.metadatas.each do |meta| -      self.metadatas << ReferentialMetadata.new_from(meta) -    end -  end -    def metadatas_period      query = "select min(lower), max(upper) from (select lower(unnest(periodes)) as lower, upper(unnest(periodes)) as upper from public.referential_metadata where public.referential_metadata.referential_id = #{id}) bounds;" @@ -289,7 +278,9 @@ class Referential < ActiveRecord::Base    end    def create_schema -    Apartment::Tenant.create slug +    unless created_from +      Apartment::Tenant.create slug +    end    end    def assign_slug diff --git a/app/models/referential_metadata.rb b/app/models/referential_metadata.rb index 839a937f4..393dc70d3 100644 --- a/app/models/referential_metadata.rb +++ b/app/models/referential_metadata.rb @@ -157,6 +157,7 @@ class ReferentialMetadata < ActiveRecord::Base    def self.new_from(from, functional_scope)      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.referential_id = nil      end diff --git a/app/models/stop_area_copy.rb b/app/models/stop_area_copy.rb index 0fa56ff68..d3eb78557 100644 --- a/app/models/stop_area_copy.rb +++ b/app/models/stop_area_copy.rb @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- -  class StopAreaCopy    include ActiveModel::Validations    include ActiveModel::Conversion diff --git a/app/models/vehicle_journey_import.rb b/app/models/vehicle_journey_import.rb index 855fa2abe..44a6d457e 100644 --- a/app/models/vehicle_journey_import.rb +++ b/app/models/vehicle_journey_import.rb @@ -1,6 +1,6 @@  # -*- coding: utf-8 -*- -class VehicleJourneyImport    +class VehicleJourneyImport    include ActiveModel::Validations    include ActiveModel::Conversion    extend  ActiveModel::Naming @@ -8,11 +8,11 @@ class VehicleJourneyImport    attr_accessor :file, :route    attr_accessor :created_vehicle_journey_count,:updated_vehicle_journey_count,:deleted_vehicle_journey_count    attr_accessor :created_journey_pattern_count,:error_count -   +    validates_presence_of :file    validates_presence_of :route -  def initialize(attributes = {})     +  def initialize(attributes = {})      attributes.each { |name, value| send("#{name}=", value) } if attributes      self.created_vehicle_journey_count = 0      self.updated_vehicle_journey_count = 0 @@ -20,15 +20,15 @@ class VehicleJourneyImport      self.deleted_vehicle_journey_count = 0      self.error_count = 0    end -   +    def persisted?      false    end -   +    def save      begin -      Chouette::VehicleJourney.transaction do         -        if imported_vehicle_journeys.map(&:valid?).all?  +      Chouette::VehicleJourney.transaction do +        if imported_vehicle_journeys.map(&:valid?).all?            imported_vehicle_journeys.each(&:save!)            true          else @@ -46,8 +46,8 @@ class VehicleJourneyImport        errors.add :base, I18n.t("vehicle_journey_imports.errors.exception")        false      end -  end    -   +  end +    def imported_vehicle_journeys      @imported_vehicle_journeys ||= load_imported_vehicle_journeys    end @@ -61,31 +61,31 @@ class VehicleJourneyImport      if stop_points_used.length == 1        errors.add :base, I18n.t("vehicle_journey_imports.errors.one_stop_point_used", :column => column) -      raise  +      raise      end -     +      journey_pattern_founded = route.journey_patterns.select{ |jp| jp.stop_points.collect(&:id) == stop_points_used }.first -     +      # If no journey pattern founded, create a new one      self.created_journey_pattern_count += 1  if journey_pattern_founded.nil?      journey_pattern_founded ? journey_pattern_founded :  route.journey_patterns.create(:stop_points => Chouette::StopPoint.find(stop_points_used) )    end -   +    def as_integer(v)      v.blank? ? nil : v.to_i    end -   +    def as_boolean(v)      v.blank? ? nil : (v[1..1].downcase != "n")    end -   +    def update_time_tables(vj,tm_ids)      vj.time_tables.clear      return unless tm_ids.present?      ids = tm_ids.split(",").map(&:to_i)      vj.time_tables << Chouette::TimeTable.where(:id => ids)    end -   +    def update_footnotes(vj,ftn_ids)      vj.footnotes.clear      return unless ftn_ids.present? @@ -94,13 +94,13 @@ class VehicleJourneyImport    end    def load_imported_vehicle_journeys -     +      spreadsheet = open_spreadsheet(file) -     +      vehicle_journeys = [] -     +      first_column = spreadsheet.column(1) -     +      # fixed rows (first = 1)      number_row = 2      published_journey_name_row = 3 @@ -111,7 +111,7 @@ class VehicleJourneyImport      # rows in column (first = 0)      first_stop_row_index = 8 -     +      stop_point_ids = first_column[first_stop_row_index..spreadsheet.last_row].map(&:to_i)      # blank lines at end of file will produce id = 0 ; ignore them      last_stop_row_index = stop_point_ids.length + 7 @@ -119,50 +119,50 @@ class VehicleJourneyImport        stop_point_ids = stop_point_ids[0..-2]        last_stop_row_index -= 1      end -     +      unless route.stop_points.collect(&:id) == stop_point_ids        errors.add :base, I18n.t("vehicle_journey_imports.errors.not_same_stop_points", :route => route.id)        raise -    end     -            +    end +      (3..spreadsheet.last_column).each do |i|        vehicle_journey_id = spreadsheet.column(i)[0]        hours_by_stop_point_ids = Hash[[stop_point_ids, spreadsheet.column(i)[first_stop_row_index..last_stop_row_index]].transpose] -       +        journey_pattern = find_journey_pattern_schedule(i,hours_by_stop_point_ids) -       +        vehicle_journey = route.vehicle_journeys.where(:id => vehicle_journey_id, :route_id => route.id).first_or_initialize        if journey_pattern.nil? -        if vehicle_journey.id.present?  +        if vehicle_journey.id.present?            self.deleted_vehicle_journey_count += 1            vehicle_journey.delete          end          next        end -      if vehicle_journey.id.present?  +      if vehicle_journey.id.present?          self.updated_vehicle_journey_count += 1        else          self.created_vehicle_journey_count += 1        end -       +        # number        vehicle_journey.number = as_integer(spreadsheet.row(number_row)[i-1]) -       +        # published_name        vehicle_journey.published_journey_name = spreadsheet.row(published_journey_name_row)[i-1] -       +        # flexible_service        vehicle_journey.flexible_service = as_boolean(spreadsheet.row(flexible_service_row)[i-1]) -       +        # mobility        vehicle_journey.mobility_restricted_suitability = as_boolean(spreadsheet.row(mobility_row)[i-1]) -       +        # time_tables        update_time_tables(vehicle_journey,spreadsheet.row(time_tables_row)[i-1]) -       +        update_footnotes(vehicle_journey,spreadsheet.row(footnotes_row)[i-1]) -       +        # journey_pattern        vehicle_journey.journey_pattern = journey_pattern        vehicle_journey.vehicle_journey_at_stops.clear @@ -171,7 +171,7 @@ class VehicleJourneyImport        hours_by_stop_point_ids.each_pair do |key, value|          line += 1          if value.present? # Create a vehicle journey at stop when time is present -          begin  +          begin              # force UTC to ignore timezone effects              main_time = Time.parse(value+" UTC")              if main_time.present? @@ -182,14 +182,14 @@ class VehicleJourneyImport              errors.add :base, I18n.t("vehicle_journey_imports.errors.invalid_vehicle_journey_at_stop", :column => i, :line => line, :time => value)              raise exception            end -        end          +        end        end        vehicle_journeys << vehicle_journey      end -     +      vehicle_journeys    end -   +    def open_spreadsheet(file)      case File.extname(file.original_filename)      when '.csv' then Roo::CSV.new(file.path, csv_options: {col_sep: ";"}) @@ -199,5 +199,5 @@ class VehicleJourneyImport        raise "Unknown file type: #{file.original_filename}"      end    end -   +  end diff --git a/app/models/workbench.rb b/app/models/workbench.rb index c37cba858..30692e625 100644 --- a/app/models/workbench.rb +++ b/app/models/workbench.rb @@ -10,6 +10,7 @@ class Workbench < ActiveRecord::Base    has_many :stop_areas, through: :stop_area_referential    has_many :imports    has_many :workbench_imports +    validates :name, presence: true    validates :organisation, presence: true diff --git a/app/policies/route_policy.rb b/app/policies/route_policy.rb index 786b0acf4..7e9fe251a 100644 --- a/app/policies/route_policy.rb +++ b/app/policies/route_policy.rb @@ -16,4 +16,8 @@ class RoutePolicy < ApplicationPolicy    def update?      !archived? && organisation_match? && user.has_permission?('routes.update')    end + +  def duplicate? +    create? +  end  end diff --git a/app/views/calendars/_filters.html.slim b/app/views/calendars/_filters.html.slim index 4c30f69dc..b5283c1e8 100644 --- a/app/views/calendars/_filters.html.slim +++ b/app/views/calendars/_filters.html.slim @@ -19,4 +19,4 @@    .actions      = link_to 'Effacer', calendars_path, class: 'btn btn-link' -    = f.submit 'Filtrer', id: 'filter_btn', class: 'btn btn-default' +    = f.submit 'Filtrer', id: 'calendar_filter_btn', class: 'btn btn-default' diff --git a/app/views/calendars/index.html.slim b/app/views/calendars/index.html.slim index 1e38786b9..24ed15484 100644 --- a/app/views/calendars/index.html.slim +++ b/app/views/calendars/index.html.slim @@ -13,7 +13,7 @@        .row          .col-lg-12            = render 'filters' -           +      - if @calendars.any?        .row          .col-lg-12 @@ -31,6 +31,10 @@                  attribute: 'short_name' \                ), \                TableBuilderHelper::Column.new( \ +                key: :organisation, \ +                attribute: Proc.new { |c| c.organisation.name } \ +              ), \ +              TableBuilderHelper::Column.new( \                  key: :shared, \                  attribute: Proc.new { |c| t("#{c.try(:shared)}") } \                ) \ @@ -39,8 +43,10 @@              cls: 'table has-filter'            = new_pagination @calendars, 'pull-right' -           +      - unless @calendars.any?        .row.mt-xs          .col-lg-12            = replacement_msg t('calendars.search_no_results') + += javascript_include_tag 'filters/calendar.js' diff --git a/app/views/import_resources/index.html.slim b/app/views/import_resources/index.html.slim index 17e5532ae..849ed6d8d 100644 --- a/app/views/import_resources/index.html.slim +++ b/app/views/import_resources/index.html.slim @@ -6,50 +6,53 @@               ''  / PageContent -.page_content +.page_content.import_messages    .container-fluid -    - if @import_resources.any? -      .row -        .col-lg-12 -          = definition_list t('metadatas'),{ 'Bilan d\'import' => link_to(@import.parent.name, workbench_import_path(@import.parent.workbench, @import.parent) ), -              'Jeu de donnĂ©es associĂ©' => ( @import.referential.present? ? link_to(@import.referential.name, referential_path(@import.referential)) : '-' ) } +    .row +      .col-lg-12 +        = definition_list t('metadatas'),{ 'Bilan d\'import' => link_to(@import.parent.name, workbench_import_path(@import.parent.workbench, @import.parent) ), +            'Jeu de donnĂ©es associĂ©' => ( @import.referential.present? ? link_to(@import.referential.name, referential_path(@import.referential)) : '-' ) } -    - if @import_resources.any?        .row          .col-lg-12            h1 -            span = import_status(@import.status) +            span.status_icon = import_status(@import.status)              span = t('.table_state', lines_imported: @import_resources.lines_imported , lines_in_zipfile: @import_resources.lines_in_zipfile ) -        .col-lg-12 -          h2 = t('.table_title') -        .col-lg-12 -          = t('.table_explanation') -        .col-lg-12 -          = table_builder_2 @import_resources.where(resource_type: :file), -            [ \ -              TableBuilderHelper::Column.new( \ -                key: :name, \ -                attribute: 'name', \ -                sortable: false, \ -              ), \ -              TableBuilderHelper::Column.new( \ -                key: :status, \ -                attribute: Proc.new { |n| import_resource_status(n.status) }, \ -                sortable: false, \ -              ), \ -              TableBuilderHelper::Column.new( \ -                name: 'RĂ©sultat des tests' , \ -                attribute: Proc.new { |n| I18n.t('import_resources.index.metrics', n.metrics.deep_symbolize_keys) }, \ -                sortable: false, \ -              ), \ -              TableBuilderHelper::Column.new( \ -                name: 'TĂ©lĂ©chargement' , \ -                attribute: Proc.new { |n| '<i class="fa fa-download" aria-hidden="true"></i>'.html_safe }, \ -                sortable: false, \ -                link_to: lambda do |import_resource| \ -                  workbench_import_import_resource_import_messages_path(import_resource.import.workbench, import_resource.import, import_resource, format: 'csv' ) \ -                end \ -              ), \ -            ], -            links: [], -            cls: 'table has-search' +        - if @import_resources.present? +          .col-lg-12 +            h2 = t('.table_title') +          .col-lg-12 +            = t('.table_explanation') +          .col-lg-12 +            = table_builder_2 @import_resources.where(resource_type: :file), +              [ \ +                TableBuilderHelper::Column.new( \ +                  key: :name, \ +                  attribute: 'name', \ +                  sortable: false, \ +                ), \ +                TableBuilderHelper::Column.new( \ +                  key: :status, \ +                  attribute: Proc.new { |n| import_resource_status(n.status) }, \ +                  sortable: false, \ +                ), \ +                TableBuilderHelper::Column.new( \ +                  name: 'RĂ©sultat des tests' , \ +                  attribute: Proc.new { |n| I18n.t('import_resources.index.metrics', n.metrics.deep_symbolize_keys) }, \ +                  sortable: false, \ +                ), \ +                TableBuilderHelper::Column.new( \ +                  name: 'TĂ©lĂ©chargement' , \ +                  attribute: Proc.new { |n| '<i class="fa fa-download" aria-hidden="true"></i>'.html_safe }, \ +                  sortable: false, \ +                  link_to: lambda do |import_resource| \ +                    workbench_import_import_resource_import_messages_path(import_resource.import.workbench, import_resource.import, import_resource, format: 'csv' ) \ +                  end \ +                ), \ +              ], +              links: [], +              cls: 'table has-search' +        - else +          .col-lg-12 +            - @import.messages.each do |message| +              = I18n.t("import_messages.compliance_check_messages.#{message.message_key}") diff --git a/app/views/imports/_filters.html.slim b/app/views/imports/_filters.html.slim index 99fcb0232..a5488b275 100644 --- a/app/views/imports/_filters.html.slim +++ b/app/views/imports/_filters.html.slim @@ -9,13 +9,15 @@    .ffg-row      .form-group.togglable        = f.label Import.human_attribute_name(:status), required: false, class: 'control-label' -      = f.input :status_eq_any, collection: @imports.map(&:status).uniq.compact, as: :check_boxes, label: false, label_method: lambda{|l| ("<span>" + l + "</span>").html_safe}, required: false, wrapper_html: { class: 'checkbox_list'} +      = f.input :status_eq_any, collection: @imports.map(&:status).uniq.compact, as: :check_boxes, label: false, label_method: lambda{|l| ("<span>" + import_status(l) + "</span>").html_safe}, required: false, wrapper_html: { class: 'checkbox_list'}, input_html: { checked: true}      .form-group.togglable        = f.label Import.human_attribute_name(:started_at), required: false, class: 'control-label'        .filter_menu -        = f.input :started_at_eq, as: :date, label: false, wrapper_html: { class: 'date smart_date filter_menu-item' }, include_blank: true +        = f.simple_fields_for :started_at do |p| +          = p.input :begin, as: :date, label: false, wrapper_html: { class: 'date smart_date filter_menu-item' }, default: @begin_range, include_blank: @begin_range ? false : true +          = p.input :end, as: :date, label: false, wrapper_html: { class: 'date smart_date filter_menu-item' }, default: @end_range, include_blank: @end_range ? false : true    .actions      = link_to t('actions.erase'), workbench_imports_path(@workbench), class: 'btn btn-link' -    = f.submit t('actions.filter'), class: 'btn btn-default' +    = f.submit t('actions.filter'), id: 'import_filter_btn', class: 'btn btn-default' diff --git a/app/views/imports/index.html.slim b/app/views/imports/index.html.slim index 37ae3b3c1..2203d3584 100644 --- a/app/views/imports/index.html.slim +++ b/app/views/imports/index.html.slim @@ -47,3 +47,5 @@        .row.mt-xs          .col-lg-12            = replacement_msg t('imports.search_no_results') + += javascript_include_tag 'filters/import.js' diff --git a/app/views/layouts/navigation/_main_nav_left.html.slim b/app/views/layouts/navigation/_main_nav_left.html.slim index 74442692d..4560f5fa0 100644 --- a/app/views/layouts/navigation/_main_nav_left.html.slim +++ b/app/views/layouts/navigation/_main_nav_left.html.slim @@ -31,16 +31,10 @@          #miTwo.panel-collapse.collapse            .list-group -            = link_to '#', class: "list-group-item #{params[:controller] == 'workbenches' ? 'active' : ''}" do +            = link_to workbench_path(current_offer_workbench), class: "list-group-item #{params[:controller] == 'workbenches' ? 'active' : ''}" do                span Jeux de donnĂ©es - -            - if @workbench -              = link_to workbench_imports_path(@workbench), class: "list-group-item #{(params[:controller] == 'imports') ? 'active' : ''}" do -                span Import -            - else -              = link_to '#', class: 'list-group-item disabled' do +            = link_to workbench_imports_path(current_offer_workbench), class: "list-group-item #{(params[:controller] == 'imports') ? 'active' : ''}" do                  span Import -              = link_to calendars_path, class: 'list-group-item' do                span ModĂšles de calendrier              = link_to '#', class: 'list-group-item' do @@ -62,13 +56,13 @@                  .list-group                    = link_to referential_networks_path(current_referential), class: 'list-group-item' do                      span = t('networks.index.title') -           +                    = link_to referential_companies_path(current_referential), class: 'list-group-item' do                      span = t('companies.index.title') -           +                    = link_to '#', class: 'list-group-item disabled' do                      span TracĂ©s -           +                    = link_to referential_time_tables_path(current_referential), class: 'list-group-item' do                      span = t('time_tables.index.title') @@ -95,7 +89,7 @@            h4.panel-title              = link_to '#miFive', data: { toggle: 'collapse', parent: '#menu-items' }, 'aria-expanded' => 'false' do                |Outils -               +          #miFive.panel-collapse.collapse            .list-group              = link_to Rails.application.config.try(:portal_url), target: '_blank', class: 'list-group-item' do diff --git a/app/views/time_table_combinations/_form.html.slim b/app/views/time_table_combinations/_form.html.slim index 8e2d77d46..426624ee3 100644 --- a/app/views/time_table_combinations/_form.html.slim +++ b/app/views/time_table_combinations/_form.html.slim @@ -7,7 +7,7 @@            abbr title='Champ requis' *          = f.input :combined_type, as: :boolean, checked_value: 'time_table', unchecked_value: 'calendar', required: false, label: content_tag(:span, t("time_table_combinations.combined_type.#{@combination.combined_type}"), class: 'switch-label', data: { checkedValue: 'Calendriers', uncheckedValue: 'ModĂšles de calendriers' }), wrapper_html: { class: 'col-sm-8 col-xs-7' } -      = f.input :time_table_id, as: :select, input_html: {class: 'tt_combination_target', style: "width: 100%", data: { 'select2-ajax': 'true', 'select2ed-placeholder': 'Indiquez un calendrier...', term: 'comment_cont_or_objectid_cont', url: referential_autocomplete_time_tables_path(@referential, format: :json, :source_id => @combination.source_id)}}, wrapper_html: {class: @combination.combined_type != 'time_table' ? 'hidden' : ''} +      = f.input :time_table_id, as: :select, input_html: {class: 'tt_combination_target', style: "width: 100%", data: { 'select2-ajax': 'true', 'select2ed-placeholder': 'Indiquez un calendrier...', term: 'comment_or_objectid_cont_any', url: referential_autocomplete_time_tables_path(@referential, format: :json, :source_id => @combination.source_id)}}, wrapper_html: {class: @combination.combined_type != 'time_table' ? 'hidden' : ''}        = f.input :calendar_id, as: :select, input_html: { class: 'tt_combination_target', style: "width: 100%", data: { 'select2-ajax': 'true', 'select2ed-placeholder': 'Indiquez un modĂšle de calendrier...', term: 'name_cont', url: autocomplete_calendars_path}}, wrapper_html: {class: @combination.combined_type != 'calendar' ? 'hidden' : ''} diff --git a/app/views/time_tables/index.html.slim b/app/views/time_tables/index.html.slim index 1ea5256aa..a1b9c4e09 100644 --- a/app/views/time_tables/index.html.slim +++ b/app/views/time_tables/index.html.slim @@ -68,3 +68,5 @@  = javascript_tag do    | window.I18n = #{(I18n.backend.send(:translations).to_json).html_safe}; + += javascript_include_tag 'filters/timetable.js' diff --git a/app/views/workbenches/index.html.slim b/app/views/workbenches/index.html.slim index d57f579ff..6140c4f8c 100644 --- a/app/views/workbenches/index.html.slim +++ b/app/views/workbenches/index.html.slim @@ -41,7 +41,7 @@            - if @referentials.any?              .list-group                - @referentials.each_with_index do |referential, i| -                = link_to referential.name, referential_path(referential), class: 'list-group-item' if i < 6 +                = link_to referential.name, referential_path(referential, workbench_id: referential.workbench_id, current_workbench_id: @workbench.id), class: 'list-group-item' if i < 6            - else              .panel-body diff --git a/app/views/workbenches/show.html.slim b/app/views/workbenches/show.html.slim index bb54f07cb..fd72979ea 100644 --- a/app/views/workbenches/show.html.slim +++ b/app/views/workbenches/show.html.slim @@ -29,7 +29,7 @@                    key: :name, \                    attribute: 'name', \                    link_to: lambda do |referential| \ -                    referential_path(referential) \ +                    referential_path(referential, current_workbench_id: params[:id]) \                    end \                  ), \                  TableBuilderHelper::Column.new( \ @@ -77,3 +77,5 @@  = javascript_tag do    | window.I18n = #{(I18n.backend.send(:translations).to_json).html_safe}; + += javascript_include_tag 'filters/workbench.js' diff --git a/app/workers/workbench_import_worker.rb b/app/workers/workbench_import_worker.rb index 706c3fc63..994493944 100644 --- a/app/workers/workbench_import_worker.rb +++ b/app/workers/workbench_import_worker.rb @@ -9,7 +9,7 @@ class WorkbenchImportWorker    def perform(import_id)      @workbench_import = WorkbenchImport.find(import_id)      @response         = nil -    @workbench_import.update_attributes(status: 'running', started_at: Time.now) +    @workbench_import.update(status: 'running', started_at: Time.now)      downloaded  = download      zip_service = ZipService.new(downloaded)      upload zip_service @@ -99,11 +99,6 @@ class WorkbenchImportWorker    end    def params file, name -    if dest = ENV["DEBUG_TEMPFILE"] -      require 'pry' -      binding.pry -      %x{unzip -oqq #{file.path} -d #{dest}} -    end      { netex_import:          { parent_id: @workbench_import.id,            parent_type: @workbench_import.class.name, diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index b53dba3d8..2ee5982f3 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -5,4 +5,4 @@ Rails.application.config.assets.version = '1.0'  # Precompile additional assets.  # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. -Rails.application.config.assets.precompile += %w( base.css es6_browserified/*.js ) +Rails.application.config.assets.precompile += %w( base.css es6_browserified/*.js helpers/*.js filters/*.js) diff --git a/config/locales/calendars.en.yml b/config/locales/calendars.en.yml index cb1ede4c7..42e26e995 100644 --- a/config/locales/calendars.en.yml +++ b/config/locales/calendars.en.yml @@ -64,6 +64,7 @@ en:          date_ranges: Date ranges          dates: Dates          shared: Shared +        organisation: Organisation      errors:        models:          calendar: diff --git a/config/locales/calendars.fr.yml b/config/locales/calendars.fr.yml index 1b403c3f2..63f6465d9 100644 --- a/config/locales/calendars.fr.yml +++ b/config/locales/calendars.fr.yml @@ -64,6 +64,7 @@ fr:          date_ranges: Intervalles de dates          dates: Dates          shared: PartagĂ© +        organisation: Organisation      errors:        models:          calendar: diff --git a/config/locales/import_messages.en.yml b/config/locales/import_messages.en.yml index 665cff605..7f8fc622d 100644 --- a/config/locales/import_messages.en.yml +++ b/config/locales/import_messages.en.yml @@ -1,48 +1,50 @@  en: -  import_messages: -    1_netexstif_2: "The file %{file_name} does not respect the XML structure or the NeTEx XSD : '%{xercex_message}' error" -    1_netexstif_5: "%{file}-Line %{line}-Column %{column} : the %{netex_type} object with %{objectid} id has an update in the future" -    2_netexstif_1_1: "The commun.xml file doesn't have a NETEX_COMMUN named frame" -    2_netexstif_1_2: "The commun.xml file frame name : %{frame_name} is not accepted" -    2_netexstif_2_1: "The calendriers.xml file doesn't have a NETEX_CALENDRIER named frame" -    2_netexstif_2_2: "The calendriers.xml file frame name : %{frame_name} is not accepted" -    2_netexstif_3_1: "The %{file_name} doesn't have a NETEX_OFFRE_LIGNE named frame" -    2_netexstif_3_2: "The %{file_name} frame name : %{frame_name} is not accepted" -    2_netexstif_3_3: "The NETEX_OFFRE_LIGNE frame of the %{file_name} file doesn't have the required frame %{NETEX_STRUCTURE|NETEX_HORAIRE}" -    2_netexstif_3_4: "The NETEX_OFFRE_LIGNE frame of the %{file_name} file has a non accepted %{frame_name} frame" -    2_netexstif_4: "%{file}-Line %{line}-Column %{column} : the %{objectid} id of the %{netex_type} object does not have the right syntax : [CODESPACE]:%{netex_type}:[identifiant Technique]:LOC" -    2_netexstif_6: "%{file}-Line %{line}-Column %{column} : The %{netex_type} object with the id of %{objectid} has a forbidden update type : 'delete'" -    2_netexstif_7: "%{file}-Line %{line}-Column %{column} : The %{netex_type} object with the id of %{objectid} define a %{objectRef} reference with an invalid syntaxe : %{ref}" -    2_netexstif_8_1: "%{file}-Line %{line}-Column %{column} : The %{netex_type} object with the id of %{objectid} define a %{objectRef} reference with an extern type : intern type required" -    2_netexstif_8_2: "%{file}-Line %{line}-Column %{column} : The %{netex_type} object with the id of %{objectid} define a %{objectRef} reference with an intern type but has a content (extern version allowed" -    2_netexstif_9_1: "%{file}-Line %{line}-Column %{column} : The %{netex_type} object with the id of %{objectid} define a %{objectRef} reference with an intern type : extern reference expected" -    2_netexstif_9_2: "%{file}-Line %{line}-Column %{column} : The %{netex_type} object with the id of %{objectid} define a %{objectRef} reference with an extern type without version info" -    2_netexstif_10: "%{file}-Line %{line}-Column %{column} : The %{netex_type} object with the id of %{objectid} define a %{objectRef} reference with an unknown extern type" -    2_netexstif_daytype_1: "%{file}-Line %{line}-Column %{column} : the DayType object with %{objectid} id does not have a time table, it's ignored" -    2_netexstif_daytype_2: "%{file}-Line %{line}-Column %{column} : the DayType object with %{objectid} id has periods but no day types" -    2_netexstif_daytypeassignment_1: "%{file}-Line %{line}-Column %{column} : the DayTypeAssignment object with %{objectid} id cannot reference a OperatingDay" -    2_netexstif_daytypeassignment_2: "%{file}-Line %{line}-Column %{column} : the DayTypeAssignment object with %{objectid} id cannot reference a OperatingPeriod on false IsAvailable condition" -    2_netexstif_direction_1: "%{file}-Line %{line}-Column %{column} : the Direction object with %{objectid} id has a blank value for the Name attribute" -    2_netexstif_direction_2: "%{file}-Line %{line}-Column %{column} : the Direction object with %{objectid} id define a forbidden attribute : %{forbidden_aatribute}" -    2_netexstif_notice_1: "%{file}-Line %{line}-Column %{column} : the Notice object with %{objectid} id needs to define a text" -    2_netexstif_notice_2: "%{file}-Line %{line}-Column %{column} : the Notice object with %{objectid} id of %{type_of_notice_ref} type is ignored" -    2_netexstif_operatingperiod_1: "%{file}-Line %{line}-Column %{column} : the OperatingPeriod object with %{objectid} id must have an end date (%{start_date}) which is greater than the start date (%{end_date})" -    2_netexstif_passengerstopassignment_1: "%{file}-Line %{line}-Column %{column}, the %{required_attribute} attribute of the PassengerStopAssignment object with %{objectid} id is required" -    2_netexstif_passengerstopassignment_2: "The %{objectid} stop point is not available for your organization." -    2_netexstif_passingtime_1: "%{file}-Line %{line}-Column %{column}, the ServiceJourney object with %{objectid} id : the passingTime with the %{rank} rank does not have a DepartureTime" -    2_netexstif_passingtime_2: "%{file}-Line %{line}-Column %{column}, the ServiceJourney object with %{objectid} id : the passingTime with the %{rank} rank has an ArrivalTime greater than the DepartureTime" -    2_netexstif_route_1: "%{file}-Line %{line}-Column %{column} : the Route object with %{objectid} has a forbidden value for the DirectionType attribute : %{direction_type}" -    2_netexstif_route_2_1: "%{file}-Line %{line}-Column %{column} : the Route object with %{objectid} references an inverse route %{inverse_route_ref.ref} which doesn't references it" -    2_netexstif_route_2_2: "%{file}-Line %{line}-Column %{column} : the Route object with %{objectid} references an inverse route %{inverse_route_ref.ref} of the same DirectionType" -    2_netexstif_route_3: "%{file}-Line %{line}-Column %{column} : th ServiceJourneyPattern objects of the Route with %{objectid} id does permit the reconstitution of the stop points sequence" -    2_netexstif_route_4: "%{file}-Line %{line}-Column %{column}, The up/down info of the %{stop_point_id} stop point of the Route %{objectid} id are different on multiple ServiceJourneyPattern, those informations are not imported" -    2_netexstif_routingconstraintzone_1: "%{file}-Line %{line}-Column %{column}, the RoutingConstraintZone object with %{objectid} must references at least two ScheduledStopPoint" -    2_netexstif_routingconstraintzone_2: "%{file}-Line %{line}-Column %{column}, the RoutingConstraintZone object with %{objectid} has a forbidden value for the ZoneUse attribute: %{zone_use}" -    2_netexstif_servicejourney_1: "%{file}-Line %{line}-Column %{column} : the ServiceJourney object with %{objectid} id does not references a ServiceJourneyPattern" -    2_netexstif_servicejourney_2: "%{file}-Line %{line}-Column %{column} : the ServiceJourney object with %{objectid} id doesn't have a trainNumber" -    2_netexstif_servicejourney_3: "%{file}-Line %{line}-Column %{column} : the number of passing_time of the ServiceJourney object with %{objectid} id is not consistent with the associated ServiceJourneyPattern" -    2_netexstif_servicejourney_4: "%{file}-Line %{line}-Column %{column} , the ServiceJourney object with the %{objectid} id : the passingTime of %{rank} rank has smaller schedules compared to the prior passingTime" -    2_netexstif_servicejourneypattern_1: "%{file}-Line %{line}-Column %{column} : the ServiceJourneyPattern with %{objectid} id does not reference a Route" -    2_netexstif_servicejourneypattern_2: "%{file}-Line %{line}-Column %{column} : the ServiceJourneyPattern with %{objectid} id must contain at least 2 StopPointInJourneyPattern" -    2_netexstif_servicejourneypattern_3: "%{file}-Line %{line}-Column %{column} : the ServiceJourneyPattern with %{objectid} id does not have a value for the ServiceJourneyPatternType attribute" -    2_netexstif_servicejourneypattern_4: "%{file}-Line %{line}-Column %{column}, the ServiceJourneyPattern with %{objectid} id : the 'order' attributes for the StopPointInJourneyPattern are not in ascending order" +  compliance_check_messages: +    import_messages: +      referential_creation: "The referential can't be created because another one has same periods and lines" +      1_netexstif_2: "Le fichier %{source_filename} ne respecte pas la syntaxe XML ou la XSD NeTEx : erreur '%{error_value}' rencontrĂ©" +      1_netexstif_5: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet %{source_label} d'identifiant %{source_objectid} a une date de mise Ă  jour dans le futur" +      2_netexstif_1_1: "Le fichier commun.xml ne contient pas de frame nommĂ©e NETEX_COMMUN" +      2_netexstif_1_2: "Le fichier commun.xml contient une frame nommĂ©e %{source_label} non acceptĂ©e" +      2_netexstif_2_1: "Le fichier calendriers.xml ne contient pas de frame nommĂ©e NETEX_CALENDRIER" +      2_netexstif_2_2: "Le fichier calendriers.xml contient une frame nommĂ©e %{source_label} non acceptĂ©e" +      2_netexstif_3_1: "Le fichier %{source_filename} ne contient pas de frame nommĂ©e NETEX_OFFRE_LIGNE" +      2_netexstif_3_2: "Le fichier %{source_filename} contient une frame nommĂ©e %{source_label} non acceptĂ©e" +      2_netexstif_3_3: "la frame NETEX_OFFRE_LIGNE du fichier %{source_filename} ne contient pas la frame %{NETEX_STRUCTURE|NETEX_HORAIRE} obligatoire" +      2_netexstif_3_4: "la frame NETEX_OFFRE_LIGNE du fichier %{source_filename} contient une frame %{source_label} non acceptĂ©e" +      2_netexstif_4: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'identifiant %{source_objectid} de l'objet %{source_label} ne respecte pas la syntaxe [CODESPACE]:%{source_label}:[identifiant Technique]:LOC" +      2_netexstif_6: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet %{source_label} d'identifiant %{source_objectid} a un Ă©tat de modification interdit : 'delete'" +      2_netexstif_7: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet %{source_label} d'identifiant %{source_objectid} dĂ©finit une rĂ©fĂ©rence %{reference_value} de syntaxe invalide : %{reference_value}" +      2_netexstif_8_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet %{source_label} d'identifiant %{source_objectid} dĂ©finit une rĂ©fĂ©rence %{reference_value} de type externe : rĂ©fĂ©rence interne attendue" +      2_netexstif_8_2: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet %{source_label} d'identifiant %{source_objectid} dĂ©finit une rĂ©fĂ©rence %{reference_value} de type interne mais disposant d'un contenu (version externe possible)" +      2_netexstif_9_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet %{source_label} d'identifiant %{source_objectid} dĂ©finit une rĂ©fĂ©rence %{reference_value} de type interne : rĂ©fĂ©rence externe attendue" +      2_netexstif_9_2: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet %{source_label} d'identifiant %{source_objectid} dĂ©finit une rĂ©fĂ©rence %{reference_value} de type externe sans information de version" +      2_netexstif_10: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet %{source_label} d'identifiant %{source_objectid} dĂ©finit une rĂ©fĂ©rence %{reference_value} de type externe inconnue" +      2_netexstif_daytype_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet DayType d'identifiant %{source_objectid} ne dĂ©finit aucun calendrier, il est ignorĂ©" +      2_netexstif_daytype_2: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet DayType d'identifiant %{source_objectid} est reliĂ©e Ă  des pĂ©riodes mais ne dĂ©finit pas de types de jours" +      2_netexstif_daytypeassignment_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet DayTypeAssignment d'identifiant %{source_objectid} ne peut rĂ©fĂ©rencer un OperatingDay" +      2_netexstif_daytypeassignment_2: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet DayTypeAssignment d'identifiant %{source_objectid} ne peut rĂ©fĂ©rencer un OperatingPeriod sur la condition IsAvailable Ă  faux." +      2_netexstif_direction_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet Direction d'identifiant %{source_objectid} n'a pas de valeur pour l'attribut Name" +      2_netexstif_direction_2: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet Direction d'identifiant %{source_objectid} dĂ©finit un attribut %{error_value} non autorisĂ©" +      2_netexstif_notice_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet Notice d'identifiant %{source_objectid} doit dĂ©finir un texte" +      2_netexstif_notice_2: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet Notice d'identifiant %{source_objectid} de type %{reference_value} est ignorĂ©" +      2_netexstif_operatingperiod_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet OperatingPeriod d'identifiant %{source_objectid} a une date de fin %{start_date} infĂ©rieure ou Ă©gale Ă  la date de dĂ©but %{end_date}" +      2_netexstif_passengerstopassignment_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number}, l'attribut %{source_label} de l'objet PassengerStopAssignment %{source_objectid} doit ĂȘtre renseignĂ©" +      2_netexstif_passengerstopassignment_2: "L'arrĂȘt %{source_objectid} ne fait pas partie des arrĂȘts disponibles pour votre organisation." +      2_netexstif_passingtime_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} , objet ServiceJourney d'identifiant %{source_objectid} : le passingTime de rang %{error_value} ne dispose pas de DepartureTime" +      2_netexstif_passingtime_2: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} , objet ServiceJourney d'identifiant %{source_objectid} : le passingTime de rang %{error_value} fournit un ArrivalTime supĂ©rieur Ă  son DepartureTime" +      2_netexstif_route_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet Route d'identifiant %{source_objectid} a une valeur de l'attribut DirectionType interdite : %{error_value}" +      2_netexstif_route_2_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet Route d'identifiant %{source_objectid} rĂ©fĂ©rence un objet Route inverse %{reference_value} qui ne le rĂ©fĂ©rence pas" +      2_netexstif_route_2_2: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet Route d'identifiant %{source_objectid} rĂ©fĂ©rence un objet Route inverse %{reference_value} de mĂȘme DirectionType" +      2_netexstif_route_3: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : Les ServiceJourneyPattern de l'objet Route d'identifiant %{source_objectid} ne permettent pas de reconstituer la sĂ©quence des arrĂȘts de celui-ci" +      2_netexstif_route_4: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number}, Les informations de montĂ©e/Descente Ă  l'arrĂȘt %{source_label} de la Route %{source_objectid} diffĂšrent sur plusieurs ServiceJourneyPattern, ces informations ne sont pas importĂ©es" +      2_netexstif_routingconstraintzone_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number}, l'objet RoutingConstraintZone %{source_objectid} doit rĂ©fĂ©rencer au moins deux ScheduledStopPoint" +      2_netexstif_routingconstraintzone_2: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number}, l'objet RoutingConstraintZone %{source_objectid} a une valeur interdite pour l'attribut ZoneUse : %{error_value}" +      2_netexstif_servicejourney_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet ServiceJourney d'identifiant %{source_objectid} ne rĂ©fĂ©rence pas de ServiceJourneyPattern" +      2_netexstif_servicejourney_2: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet ServiceJourney d'identifiant %{source_objectid} fournit plus d'un trainNumber" +      2_netexstif_servicejourney_3: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : Le nombre d'horaires (passing_times) de l'objet ServiceJourney d'identifiant %{source_objectid} n'est pas cohĂ©rent avec le ServiceJourneyPattern associĂ©." +      2_netexstif_servicejourney_4: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} , objet ServiceJourney d'identifiant %{source_objectid} : le passingTime de rang %{rank} fournit des horaires antĂ©rieurs au passingTime prĂ©cĂ©dent." +      2_netexstif_servicejourneypattern_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet ServiceJourneyPattern d'identifiant %{source_objectid} ne rĂ©fĂ©rence pas de Route" +      2_netexstif_servicejourneypattern_2: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet ServiceJourneyPattern d'identifiant %{source_objectid} doit contenir au moins 2 StopPointInJourneyPattern" +      2_netexstif_servicejourneypattern_3: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet ServiceJourneyPattern d'identifiant %{source_objectid} n'a pas de valeur pour l'attribut ServiceJourneyPatternType" +      2_netexstif_servicejourneypattern_4: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number}, objet ServiceJourneyPattern d'identifiant %{source_objectid} : les attributs 'order' des StopPointInJourneyPattern ne sont pas croissants." diff --git a/config/locales/import_messages.fr.yml b/config/locales/import_messages.fr.yml index f5934f5db..09951c561 100644 --- a/config/locales/import_messages.fr.yml +++ b/config/locales/import_messages.fr.yml @@ -1,48 +1,50 @@  fr:    import_messages: -    1_netexstif_2: "Le fichier %{file_name} ne respecte pas la syntaxe XML ou la XSD NeTEx : erreur '%{xercex_message}' rencontrĂ©" -    1_netexstif_5: "%{file}-Ligne %{line}-Colonne %{column} : l'objet %{netex_type} d'identifiant %{objectid} a une date de mise Ă  jour dans le futur" -    2_netexstif_1_1: "Le fichier commun.xml ne contient pas de frame nommĂ©e NETEX_COMMUN" -    2_netexstif_1_2: "Le fichier commun.xml contient une frame nommĂ©e %{frame_name} non acceptĂ©e" -    2_netexstif_2_1: "Le fichier calendriers.xml ne contient pas de frame nommĂ©e NETEX_CALENDRIER" -    2_netexstif_2_2: "Le fichier calendriers.xml contient une frame nommĂ©e %{frame_name} non acceptĂ©e" -    2_netexstif_3_1: "Le fichier %{file_name} ne contient pas de frame nommĂ©e NETEX_OFFRE_LIGNE" -    2_netexstif_3_2: "Le fichier %{file_name} contient une frame nommĂ©e %{frame_name} non acceptĂ©e" -    2_netexstif_3_3: "la frame NETEX_OFFRE_LIGNE du fichier %{file_name} ne contient pas la frame %{NETEX_STRUCTURE|NETEX_HORAIRE} obligatoire" -    2_netexstif_3_4: "la frame NETEX_OFFRE_LIGNE du fichier %{file_name} contient une frame %{frame_name} non acceptĂ©e" -    2_netexstif_4: "%{file}-Ligne %{line}-Colonne %{column} : l'identifiant %{objectid} de l'objet %{netex_type} ne respecte pas la syntaxe [CODESPACE]:%{netex_type}:[identifiant Technique]:LOC" -    2_netexstif_6: "%{file}-Ligne %{line}-Colonne %{column} : l'objet %{netex_type} d'identifiant %{objectid} a un Ă©tat de modification interdit : 'delete'" -    2_netexstif_7: "%{file}-Ligne %{line}-Colonne %{column} : l'objet %{netex_type} d'identifiant %{objectid} dĂ©finit une rĂ©fĂ©rence %{objectRef} de syntaxe invalide : %{ref}" -    2_netexstif_8_1: "%{file}-Ligne %{line}-Colonne %{column} : l'objet %{netex_type} d'identifiant %{objectid} dĂ©finit une rĂ©fĂ©rence %{objectRef} de type externe : rĂ©fĂ©rence interne attendue" -    2_netexstif_8_2: "%{file}-Ligne %{line}-Colonne %{column} : l'objet %{netex_type} d'identifiant %{objectid} dĂ©finit une rĂ©fĂ©rence %{objectRef} de type interne mais disposant d'un contenu (version externe possible)" -    2_netexstif_9_1: "%{file}-Ligne %{line}-Colonne %{column} : l'objet %{netex_type} d'identifiant %{objectid} dĂ©finit une rĂ©fĂ©rence %{objectRef} de type interne : rĂ©fĂ©rence externe attendue" -    2_netexstif_9_2: "%{file}-Ligne %{line}-Colonne %{column} : l'objet %{netex_type} d'identifiant %{objectid} dĂ©finit une rĂ©fĂ©rence %{objectRef} de type externe sans information de version" -    2_netexstif_10: "%{file}-Ligne %{line}-Colonne %{column} : l'objet %{netex_type} d'identifiant %{objectid} dĂ©finit une rĂ©fĂ©rence %{objectRef} de type externe inconnue" -    2_netexstif_daytype_1: "%{file}-Ligne %{line}-Colonne %{column} : l'objet DayType d'identifiant %{objectid} ne dĂ©finit aucun calendrier, il est ignorĂ©" -    2_netexstif_daytype_2: "%{file}-Ligne %{line}-Colonne %{column} : l'objet DayType d'identifiant %{objectid} est reliĂ©e Ă  des pĂ©riodes mais ne dĂ©finit pas de types de jours" -    2_netexstif_daytypeassignment_1: "%{file}-Ligne %{line}-Colonne %{column} : l'objet DayTypeAssignment d'identifiant %{objectid} ne peut rĂ©fĂ©rencer un OperatingDay" -    2_netexstif_daytypeassignment_2: "%{file}-Ligne %{line}-Colonne %{column} : l'objet DayTypeAssignment d'identifiant %{objectid} ne peut rĂ©fĂ©rencer un OperatingPeriod sur la condition IsAvailable Ă  faux." -    2_netexstif_direction_1: "%{file}-Ligne %{line}-Colonne %{column} : l'objet Direction d'identifiant %{objectid} n'a pas de valeur pour l'attribut Name" -    2_netexstif_direction_2: "%{file}-Ligne %{line}-Colonne %{column} : l'objet Direction d'identifiant %{objectid} dĂ©finit un attribut %{forbidden_aatribute} non autorisĂ©" -    2_netexstif_notice_1: "%{file}-Ligne %{line}-Colonne %{column} : l'objet Notice d'identifiant %{objectid} doit dĂ©finir un texte" -    2_netexstif_notice_2: "%{file}-Ligne %{line}-Colonne %{column} : l'objet Notice d'identifiant %{objectid} de type %{type_of_notice_ref} est ignorĂ©" -    2_netexstif_operatingperiod_1: "%{file}-Ligne %{line}-Colonne %{column} : l'objet OperatingPeriod d'identifiant %{objectid} a une date de fin %{start_date} infĂ©rieure ou Ă©gale Ă  la date de dĂ©but %{end_date}" -    2_netexstif_passengerstopassignment_1: "%{file}-Ligne %{line}-Colonne %{column}, l'attribut %{required_attribute} de l'objet PassengerStopAssignment %{objectid} doit ĂȘtre renseignĂ©" -    2_netexstif_passengerstopassignment_2: "L'arrĂȘt %{objectid} ne fait pas partie des arrĂȘts disponibles pour votre organisation." -    2_netexstif_passingtime_1: "%{file}-Ligne %{line}-Colonne %{column} , objet ServiceJourney d'identifiant %{objectid} : le passingTime de rang %{rank} ne dispose pas de DepartureTime" -    2_netexstif_passingtime_2: "%{file}-Ligne %{line}-Colonne %{column} , objet ServiceJourney d'identifiant %{objectid} : le passingTime de rang %{rank} fournit un ArrivalTime supĂ©rieur Ă  son DepartureTime" -    2_netexstif_route_1: "%{file}-Ligne %{line}-Colonne %{column} : l'objet Route d'identifiant %{objectid} a une valeur de l'attribut DirectionType interdite : %{direction_type}" -    2_netexstif_route_2_1: "%{file}-Ligne %{line}-Colonne %{column} : l'objet Route d'identifiant %{objectid} rĂ©fĂ©rence un objet Route inverse %{inverse_route_ref.ref} qui ne le rĂ©fĂ©rence pas" -    2_netexstif_route_2_2: "%{file}-Ligne %{line}-Colonne %{column} : l'objet Route d'identifiant %{objectid} rĂ©fĂ©rence un objet Route inverse %{inverse_route_ref.ref} de mĂȘme DirectionType" -    2_netexstif_route_3: "%{file}-Ligne %{line}-Colonne %{column} : Les ServiceJourneyPattern de l'objet Route d'identifiant %{objectid} ne permettent pas de reconstituer la sĂ©quence des arrĂȘts de celui-ci" -    2_netexstif_route_4: "%{file}-Ligne %{line}-Colonne %{column}, Les informations de montĂ©e/Descente Ă  l'arrĂȘt %{stop_point_id} de la Route %{objectid} diffĂšrent sur plusieurs ServiceJourneyPattern, ces informations ne sont pas importĂ©es" -    2_netexstif_routingconstraintzone_1: "%{file}-Ligne %{line}-Colonne %{column}, l'objet RoutingConstraintZone %{objectid} doit rĂ©fĂ©rencer au moins deux ScheduledStopPoint" -    2_netexstif_routingconstraintzone_2: "%{file}-Ligne %{line}-Colonne %{column}, l'objet RoutingConstraintZone %{objectid} a une valeur interdite pour l'attribut ZoneUse : %{zone_use}" -    2_netexstif_servicejourney_1: "%{file}-Ligne %{line}-Colonne %{column} : l'objet ServiceJourney d'identifiant %{objectid} ne rĂ©fĂ©rence pas de ServiceJourneyPattern" -    2_netexstif_servicejourney_2: "%{file}-Ligne %{line}-Colonne %{column} : l'objet ServiceJourney d'identifiant %{objectid} fournit plus d'un trainNumber" -    2_netexstif_servicejourney_3: "%{file}-Ligne %{line}-Colonne %{column} : Le nombre d'horaires (passing_times) de l'objet ServiceJourney d'identifiant %{objectid} n'est pas cohĂ©rent avec le ServiceJourneyPattern associĂ©." -    2_netexstif_servicejourney_4: "%{file}-Ligne %{line}-Colonne %{column} , objet ServiceJourney d'identifiant %{objectid} : le passingTime de rang %{rank} fournit des horaires antĂ©rieurs au passingTime prĂ©cĂ©dent." -    2_netexstif_servicejourneypattern_1: "%{file}-Ligne %{line}-Colonne %{column} : l'objet ServiceJourneyPattern d'identifiant %{objectid} ne rĂ©fĂ©rence pas de Route" -    2_netexstif_servicejourneypattern_2: "%{file}-Ligne %{line}-Colonne %{column} : l'objet ServiceJourneyPattern d'identifiant %{objectid} doit contenir au moins 2 StopPointInJourneyPattern" -    2_netexstif_servicejourneypattern_3: "%{file}-Ligne %{line}-Colonne %{column} : l'objet ServiceJourneyPattern d'identifiant %{objectid} n'a pas de valeur pour l'attribut ServiceJourneyPatternType" -    2_netexstif_servicejourneypattern_4: "%{file}-Ligne %{line}-Colonne %{column}, objet ServiceJourneyPattern d'identifiant %{objectid} : les attributs 'order' des StopPointInJourneyPattern ne sont pas croissants." +    compliance_check_messages: +      referential_creation: "Le rĂ©fĂ©rentiel n'a pas pu ĂȘtre créé car un rĂ©fĂ©rentiel existe dĂ©jĂ  sur les mĂȘme pĂ©riodes et lignes" +      1_netexstif_2: "Le fichier %{source_filename} ne respecte pas la syntaxe XML ou la XSD NeTEx : erreur '%{error_value}' rencontrĂ©" +      1_netexstif_5: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet %{source_label} d'identifiant %{source_objectid} a une date de mise Ă  jour dans le futur" +      2_netexstif_1_1: "Le fichier commun.xml ne contient pas de frame nommĂ©e NETEX_COMMUN" +      2_netexstif_1_2: "Le fichier commun.xml contient une frame nommĂ©e %{source_label} non acceptĂ©e" +      2_netexstif_2_1: "Le fichier calendriers.xml ne contient pas de frame nommĂ©e NETEX_CALENDRIER" +      2_netexstif_2_2: "Le fichier calendriers.xml contient une frame nommĂ©e %{source_label} non acceptĂ©e" +      2_netexstif_3_1: "Le fichier %{source_filename} ne contient pas de frame nommĂ©e NETEX_OFFRE_LIGNE" +      2_netexstif_3_2: "Le fichier %{source_filename} contient une frame nommĂ©e %{source_label} non acceptĂ©e" +      2_netexstif_3_3: "la frame NETEX_OFFRE_LIGNE du fichier %{source_filename} ne contient pas la frame %{NETEX_STRUCTURE|NETEX_HORAIRE} obligatoire" +      2_netexstif_3_4: "la frame NETEX_OFFRE_LIGNE du fichier %{source_filename} contient une frame %{source_label} non acceptĂ©e" +      2_netexstif_4: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'identifiant %{source_objectid} de l'objet %{source_label} ne respecte pas la syntaxe [CODESPACE]:%{source_label}:[identifiant Technique]:LOC" +      2_netexstif_6: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet %{source_label} d'identifiant %{source_objectid} a un Ă©tat de modification interdit : 'delete'" +      2_netexstif_7: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet %{source_label} d'identifiant %{source_objectid} dĂ©finit une rĂ©fĂ©rence %{reference_value} de syntaxe invalide : %{reference_value}" +      2_netexstif_8_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet %{source_label} d'identifiant %{source_objectid} dĂ©finit une rĂ©fĂ©rence %{reference_value} de type externe : rĂ©fĂ©rence interne attendue" +      2_netexstif_8_2: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet %{source_label} d'identifiant %{source_objectid} dĂ©finit une rĂ©fĂ©rence %{reference_value} de type interne mais disposant d'un contenu (version externe possible)" +      2_netexstif_9_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet %{source_label} d'identifiant %{source_objectid} dĂ©finit une rĂ©fĂ©rence %{reference_value} de type interne : rĂ©fĂ©rence externe attendue" +      2_netexstif_9_2: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet %{source_label} d'identifiant %{source_objectid} dĂ©finit une rĂ©fĂ©rence %{reference_value} de type externe sans information de version" +      2_netexstif_10: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet %{source_label} d'identifiant %{source_objectid} dĂ©finit une rĂ©fĂ©rence %{reference_value} de type externe inconnue" +      2_netexstif_daytype_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet DayType d'identifiant %{source_objectid} ne dĂ©finit aucun calendrier, il est ignorĂ©" +      2_netexstif_daytype_2: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet DayType d'identifiant %{source_objectid} est reliĂ©e Ă  des pĂ©riodes mais ne dĂ©finit pas de types de jours" +      2_netexstif_daytypeassignment_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet DayTypeAssignment d'identifiant %{source_objectid} ne peut rĂ©fĂ©rencer un OperatingDay" +      2_netexstif_daytypeassignment_2: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet DayTypeAssignment d'identifiant %{source_objectid} ne peut rĂ©fĂ©rencer un OperatingPeriod sur la condition IsAvailable Ă  faux." +      2_netexstif_direction_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet Direction d'identifiant %{source_objectid} n'a pas de valeur pour l'attribut Name" +      2_netexstif_direction_2: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet Direction d'identifiant %{source_objectid} dĂ©finit un attribut %{error_value} non autorisĂ©" +      2_netexstif_notice_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet Notice d'identifiant %{source_objectid} doit dĂ©finir un texte" +      2_netexstif_notice_2: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet Notice d'identifiant %{source_objectid} de type %{reference_value} est ignorĂ©" +      2_netexstif_operatingperiod_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet OperatingPeriod d'identifiant %{source_objectid} a une date de fin %{error_value} infĂ©rieure ou Ă©gale Ă  la date de dĂ©but %{reference_value}" +      2_netexstif_passengerstopassignment_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number}, l'attribut %{source_label} de l'objet PassengerStopAssignment %{source_objectid} doit ĂȘtre renseignĂ©" +      2_netexstif_passengerstopassignment_2: "L'arrĂȘt %{source_objectid} ne fait pas partie des arrĂȘts disponibles pour votre organisation." +      2_netexstif_passingtime_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} , objet ServiceJourney d'identifiant %{source_objectid} : le passingTime de rang %{error_value} ne dispose pas de DepartureTime" +      2_netexstif_passingtime_2: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} , objet ServiceJourney d'identifiant %{source_objectid} : le passingTime de rang %{error_value} fournit un ArrivalTime supĂ©rieur Ă  son DepartureTime" +      2_netexstif_route_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet Route d'identifiant %{source_objectid} a une valeur de l'attribut DirectionType interdite : %{error_value}" +      2_netexstif_route_2_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet Route d'identifiant %{source_objectid} rĂ©fĂ©rence un objet Route inverse %{reference_value} qui ne le rĂ©fĂ©rence pas" +      2_netexstif_route_2_2: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet Route d'identifiant %{source_objectid} rĂ©fĂ©rence un objet Route inverse %{reference_value} de mĂȘme DirectionType" +      2_netexstif_route_3: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : Les ServiceJourneyPattern de l'objet Route d'identifiant %{source_objectid} ne permettent pas de reconstituer la sĂ©quence des arrĂȘts de celui-ci" +      2_netexstif_route_4: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number}, Les informations de montĂ©e/Descente Ă  l'arrĂȘt %{source_label} de la Route %{source_objectid} diffĂšrent sur plusieurs ServiceJourneyPattern, ces informations ne sont pas importĂ©es" +      2_netexstif_routingconstraintzone_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number}, l'objet RoutingConstraintZone %{source_objectid} doit rĂ©fĂ©rencer au moins deux ScheduledStopPoint" +      2_netexstif_routingconstraintzone_2: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number}, l'objet RoutingConstraintZone %{source_objectid} a une valeur interdite pour l'attribut ZoneUse : %{error_value}" +      2_netexstif_servicejourney_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet ServiceJourney d'identifiant %{source_objectid} ne rĂ©fĂ©rence pas de ServiceJourneyPattern" +      2_netexstif_servicejourney_2: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet ServiceJourney d'identifiant %{source_objectid} fournit plus d'un trainNumber" +      2_netexstif_servicejourney_3: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : Le nombre d'horaires (passing_times) de l'objet ServiceJourney d'identifiant %{source_objectid} n'est pas cohĂ©rent avec le ServiceJourneyPattern associĂ©." +      2_netexstif_servicejourney_4: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} , objet ServiceJourney d'identifiant %{source_objectid} : le passingTime de rang %{rank} fournit des horaires antĂ©rieurs au passingTime prĂ©cĂ©dent." +      2_netexstif_servicejourneypattern_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet ServiceJourneyPattern d'identifiant %{source_objectid} ne rĂ©fĂ©rence pas de Route" +      2_netexstif_servicejourneypattern_2: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet ServiceJourneyPattern d'identifiant %{source_objectid} doit contenir au moins 2 StopPointInJourneyPattern" +      2_netexstif_servicejourneypattern_3: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet ServiceJourneyPattern d'identifiant %{source_objectid} n'a pas de valeur pour l'attribut ServiceJourneyPatternType" +      2_netexstif_servicejourneypattern_4: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number}, objet ServiceJourneyPattern d'identifiant %{source_objectid} : les attributs 'order' des StopPointInJourneyPattern ne sont pas croissants." diff --git a/config/locales/imports.en.yml b/config/locales/imports.en.yml index b92b8843f..9bf877c86 100644 --- a/config/locales/imports.en.yml +++ b/config/locales/imports.en.yml @@ -4,6 +4,7 @@ en:      filters:        referential: "Select data space..."        name_or_creator_cont: "Select an import or creator name..." +      error_period_filter: "End date must be greater or equal than begin date"      actions:        new: "New import"        show: "Import report" diff --git a/config/locales/imports.fr.yml b/config/locales/imports.fr.yml index f7bf8c178..6998c89d2 100644 --- a/config/locales/imports.fr.yml +++ b/config/locales/imports.fr.yml @@ -4,6 +4,7 @@ fr:      filters:        referential: "SĂ©lectionnez un jeu de donnĂ©es..."        name_or_creator_cont: "Indiquez un nom d'import ou d'opĂ©rateur..." +      error_period_filter: "La date de fin doit ĂȘtre supĂ©rieure ou Ă©gale Ă  la date de dĂ©but"      actions:        new: "Nouvel import"        show: "Rapport d'import" diff --git a/config/locales/routes.en.yml b/config/locales/routes.en.yml index 3099d4ab1..e94adf490 100644 --- a/config/locales/routes.en.yml +++ b/config/locales/routes.en.yml @@ -32,6 +32,8 @@ en:        stop_area_name: "Stop area name"        for_boarding: "Boarding"        for_alighting: "Alighting" +    duplicate: +      title: "Duplicate route"      route:        no_journey_pattern: "No Journey pattern"        wayback: diff --git a/config/locales/routes.fr.yml b/config/locales/routes.fr.yml index 0af2832a2..a494e60ec 100644 --- a/config/locales/routes.fr.yml +++ b/config/locales/routes.fr.yml @@ -32,6 +32,8 @@ fr:        stop_area_name: "Nom de l'arrĂȘt"        for_boarding: "MontĂ©e"        for_alighting: "Descente" +    duplicate: +      title: "Dupliquer l'itinĂ©raire"      route:        no_journey_pattern: "Pas de mission"        wayback: diff --git a/config/routes.rb b/config/routes.rb index fa892c908..8f8989cab 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -117,6 +117,7 @@ ChouetteIhm::Application.routes.draw do          member do            get 'edit_boarding_alighting'            put 'save_boarding_alighting' +          post 'duplicate', to: 'routes#duplicate'          end          resource :journey_patterns_collection, :only => [:show, :update]          resources :journey_patterns do diff --git a/db/migrate/20170808083322_change_referential_date_format_to_netex.rb b/db/migrate/20170808083322_change_referential_date_format_to_netex.rb new file mode 100644 index 000000000..dc706942c --- /dev/null +++ b/db/migrate/20170808083322_change_referential_date_format_to_netex.rb @@ -0,0 +1,9 @@ +class ChangeReferentialDateFormatToNetex < ActiveRecord::Migration +  def up +    execute "UPDATE referentials SET data_format = 'netex'" +  end + +  def down +    execute "UPDATE referentials SET data_format = 'neptune'" +  end +end diff --git a/db/migrate/20170808091929_change_objectid_suffix.rb b/db/migrate/20170808091929_change_objectid_suffix.rb new file mode 100644 index 000000000..da98e8b9d --- /dev/null +++ b/db/migrate/20170808091929_change_objectid_suffix.rb @@ -0,0 +1,17 @@ +class ChangeObjectidSuffix < ActiveRecord::Migration +  def tables +    ['routes', 'journey_patterns', 'vehicle_journeys', 'time_tables', 'routing_constraint_zones'] +  end + +  def up +    self.tables.each do |table| +      execute "UPDATE #{table} SET objectid = (objectid || ':LOC')" +    end +  end + +  def down +    self.tables.each do |table| +      execute "UPDATE #{table} SET objectid = replace(objectid, ':LOC', '')" +    end +  end +end diff --git a/db/migrate/20170907082913_add_data_source_ref.rb b/db/migrate/20170907082913_add_data_source_ref.rb new file mode 100644 index 000000000..93ca8eb5f --- /dev/null +++ b/db/migrate/20170907082913_add_data_source_ref.rb @@ -0,0 +1,10 @@ +class AddDataSourceRef < ActiveRecord::Migration +  def change +    add_column :routes, :data_source_ref, :string +    add_column :journey_patterns, :data_source_ref, :string +    add_column :routing_constraint_zones, :data_source_ref, :string +    add_column :vehicle_journeys, :data_source_ref, :string +    add_column :time_tables, :data_source_ref, :string +    add_column :footnotes, :data_source_ref, :string +  end +end diff --git a/db/schema.rb b/db/schema.rb index 64e184467..9207590b5 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@  #  # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170906092619) do +ActiveRecord::Schema.define(version: 20170907082913) do    # These are extensions that must be enabled in order to support this database    enable_extension "plpgsql" @@ -322,6 +322,7 @@ ActiveRecord::Schema.define(version: 20170906092619) do      t.datetime "updated_at"      t.string   "checksum"      t.text     "checksum_source" +    t.string   "data_source_ref"    end    create_table "footnotes_vehicle_journeys", id: false, force: :cascade do |t| @@ -444,6 +445,7 @@ ActiveRecord::Schema.define(version: 20170906092619) do      t.datetime "updated_at"      t.string   "checksum"      t.text     "checksum_source" +    t.string   "data_source_ref"    end    add_index "journey_patterns", ["objectid"], name: "journey_patterns_objectid_key", unique: true, using: :btree @@ -654,6 +656,7 @@ ActiveRecord::Schema.define(version: 20170906092619) do      t.datetime "updated_at"      t.string   "checksum"      t.text     "checksum_source" +    t.string   "data_source_ref"    end    add_index "routes", ["objectid"], name: "routes_objectid_key", unique: true, using: :btree @@ -669,6 +672,7 @@ ActiveRecord::Schema.define(version: 20170906092619) do      t.integer  "stop_point_ids",  limit: 8,              array: true      t.string   "checksum"      t.text     "checksum_source" +    t.string   "data_source_ref"    end    create_table "routing_constraints_lines", id: false, force: :cascade do |t| @@ -834,6 +838,7 @@ ActiveRecord::Schema.define(version: 20170906092619) do      t.integer  "created_from_id"      t.string   "checksum"      t.text     "checksum_source" +    t.string   "data_source_ref"    end    add_index "time_tables", ["calendar_id"], name: "index_time_tables_on_calendar_id", using: :btree @@ -939,6 +944,7 @@ ActiveRecord::Schema.define(version: 20170906092619) do      t.datetime "updated_at"      t.string   "checksum"      t.text     "checksum_source" +    t.string   "data_source_ref"    end    add_index "vehicle_journeys", ["objectid"], name: "vehicle_journeys_objectid_key", unique: true, using: :btree diff --git a/lib/stif/reflex_synchronization.rb b/lib/stif/reflex_synchronization.rb index fe372f0b9..a3bf3957e 100644 --- a/lib/stif/reflex_synchronization.rb +++ b/lib/stif/reflex_synchronization.rb @@ -34,6 +34,14 @@ module Stif          Chouette::StopArea.find_by(objectid: objectid)        end +      def save_if_valid object +        if object.valid? +          object.save +        else +          Rails.logger.error "Reflex:sync - #{object.class.model_name} with objectid #{object.objectid} can't be saved - errors : #{object.errors.messages}" +        end +      end +        def synchronize          reset_counts          ['getOR', 'getOP'].each do |method| @@ -99,7 +107,7 @@ module Stif          if entry['parent']            stop.parent = self.find_by_object_id entry['parent'] -          stop.save if stop.changed && stop.valid? +          save_if_valid(stop) if stop.changed?          end          if entry['quays'] @@ -107,7 +115,7 @@ module Stif              children = self.find_by_object_id id              next unless children              children.parent = stop -            children.save if children.changed? && children.valid? +            save_if_valid(children) if children.changed?            end          end        end @@ -138,7 +146,7 @@ module Stif            access['longitude'] = entry['gml:pos'][:lng]            access['latitude']  = entry['gml:pos'][:lat]          end -        access.save if access.valid? && access.changed? +        save_if_valid(access) if access.changed?        end        def create_or_update_stop_area entry @@ -166,7 +174,7 @@ module Stif            stop.import_xml = entry[:xml]            prop = stop.new_record? ? :imported_count : :updated_count            increment_counts prop, 1 -          stop.save if stop.valid? +          save_if_valid(stop)          end          # Create AccessPoint from StopPlaceEntrance          if entry[:stop_place_entrances] diff --git a/spec/controllers/routes_controller_spec.rb b/spec/controllers/routes_controller_spec.rb index 000b799db..336f20945 100644 --- a/spec/controllers/routes_controller_spec.rb +++ b/spec/controllers/routes_controller_spec.rb @@ -1,7 +1,9 @@ -RSpec.describe RoutesController, :type => :controller do +Route = Chouette::Route + +RSpec.describe RoutesController, type: :controller do    login_user -  let!(:route) { create(:route) } +  let(:route) { create(:route) }    it { is_expected.to be_kind_of(ChouetteController) } @@ -10,6 +12,7 @@ RSpec.describe RoutesController, :type => :controller do        # expect(response).to redirect_to( referential_line_path(referential,route.line) )      end    end +    shared_examples_for "line and referential linked" do      it "assigns route.line as @line" do        expect(assigns[:line]).to eq(route.line) @@ -19,6 +22,7 @@ RSpec.describe RoutesController, :type => :controller do        expect(assigns[:referential]).to eq(referential)      end    end +    shared_examples_for "route, line and referential linked" do      it "assigns route as @route" do        expect(assigns[:route]).to eq(route) @@ -28,8 +32,8 @@ RSpec.describe RoutesController, :type => :controller do    describe "GET /index" do      before(:each) do -      get :index, :line_id => route.line_id, -          :referential_id => referential.id +      get :index, line_id: route.line_id, +          referential_id: referential.id      end      it_behaves_like "line and referential linked" @@ -38,9 +42,9 @@ RSpec.describe RoutesController, :type => :controller do    describe "POST /create" do      before(:each) do -      post :create, :line_id => route.line_id, -          :referential_id => referential.id, -          :route => { :name => "changed"} +      post :create, line_id: route.line_id, +          referential_id: referential.id, +          route: { name: "changed"}      end      it_behaves_like "line and referential linked" @@ -49,9 +53,9 @@ RSpec.describe RoutesController, :type => :controller do    describe "PUT /update" do      before(:each) do -      put :update, :id => route.id, :line_id => route.line_id, -          :referential_id => referential.id, -          :route => route.attributes +      put :update, id: route.id, line_id: route.line_id, +          referential_id: referential.id, +          route: route.attributes      end      it_behaves_like "route, line and referential linked" @@ -60,9 +64,9 @@ RSpec.describe RoutesController, :type => :controller do    describe "GET /show" do      before(:each) do -      get :show, :id => route.id, -          :line_id => route.line_id, -          :referential_id => referential.id +      get :show, id: route.id, +          line_id: route.line_id, +          referential_id: referential.id      end      it_behaves_like "route, line and referential linked" @@ -71,11 +75,22 @@ RSpec.describe RoutesController, :type => :controller do        expect(assigns[:map]).to be_an_instance_of(RouteMap)        expect(assigns[:map].route).to eq(route)      end - -    #it "assigns route.stop_points.paginate(:page => nil) as @stop_points" do -    #  expect(assigns[:stop_points]).to eq(route.stop_points.paginate(:page => nil)) -    #end    end -end +  describe "POST /duplicate" do +    let!( :route_prime ){ route } + +    it "creates a new route" do +      expect do +        post :duplicate, +          referential_id: route.line.line_referential_id, +          line_id: route.line_id, +          id: route.id +      end.to change { Route.count }.by(1) + +      expect(Route.last.name).to eq(route.name) +      expect(Route.last.published_name).to eq(route.published_name) +    end +  end +end diff --git a/spec/factories/chouette_access_links.rb b/spec/factories/chouette_access_links.rb index 94717e95e..8b4e89be9 100644 --- a/spec/factories/chouette_access_links.rb +++ b/spec/factories/chouette_access_links.rb @@ -1,9 +1,9 @@  FactoryGirl.define do -   +    factory :access_link, :class => Chouette::AccessLink do      sequence(:name) { |n| "Access link #{n}" } -    sequence(:objectid) { |n| "test:AccessLink:#{n}" } -    link_type "Mixed"  +    sequence(:objectid) { |n| "test:AccessLink:#{n}:loc" } +    link_type "Mixed"      link_orientation "AccessPointToStopArea"      association :stop_area, :factory => :stop_area diff --git a/spec/factories/chouette_companies.rb b/spec/factories/chouette_companies.rb index 35ce34257..9272736cf 100644 --- a/spec/factories/chouette_companies.rb +++ b/spec/factories/chouette_companies.rb @@ -2,7 +2,7 @@ FactoryGirl.define do    factory :company, :class => Chouette::Company do      sequence(:name) { |n| "Company #{n}" } -    sequence(:objectid) { |n| "chouette:test:Company:#{n}" } +    sequence(:objectid) { |n| "STIF:CODIFLIGNE:Company:#{n}" }      sequence(:registration_number) { |n| "test-#{n}" }      association :line_referential, :factory => :line_referential diff --git a/spec/factories/chouette_connection_links.rb b/spec/factories/chouette_connection_links.rb index f70548721..9185480ac 100644 --- a/spec/factories/chouette_connection_links.rb +++ b/spec/factories/chouette_connection_links.rb @@ -3,11 +3,11 @@ FactoryGirl.define do    factory :connection_link, :class => Chouette::ConnectionLink do      sequence(:name) { |n| "Connection link #{n}" }      sequence(:link_type) { |n| "Mixed" } -    sequence(:objectid) { |n| "test:ConnectionLink:#{n}" } +    sequence(:objectid) { |n| "test:ConnectionLink:#{n}:loc" }      association :departure, :factory => :stop_area      association :arrival, :factory => :stop_area    end -   +  end diff --git a/spec/factories/chouette_group_of_lines.rb b/spec/factories/chouette_group_of_lines.rb index 75739d6d3..8b359fea5 100644 --- a/spec/factories/chouette_group_of_lines.rb +++ b/spec/factories/chouette_group_of_lines.rb @@ -2,7 +2,7 @@ FactoryGirl.define do    factory  :group_of_line, :class => Chouette::GroupOfLine do      sequence(:name) { |n| "Group Of Line #{n}" } -    sequence(:objectid) { |n| "chouette:test:GroupOfLine:#{n}" } +    sequence(:objectid) { |n| "STIF:CODIFLIGNE:GroupOfLine:#{n}" }      sequence(:registration_number) { |n| "#{n}" }      association :line_referential diff --git a/spec/factories/chouette_journey_pattern.rb b/spec/factories/chouette_journey_pattern.rb index 62241f313..05d8d536a 100644 --- a/spec/factories/chouette_journey_pattern.rb +++ b/spec/factories/chouette_journey_pattern.rb @@ -5,8 +5,7 @@ FactoryGirl.define do      sequence(:published_name) { |n| "jp publishedname #{n}" }      sequence(:comment) { |n| "jp comment #{n}" }      sequence(:registration_number) { |n| "jp registration_number #{n}" } -    sequence(:objectid) { |n| "test:JourneyPattern:#{n}" } - +    sequence(:objectid) { |n| "organisation:JourneyPattern:lineId-#{n}:LOC" }      association :route, :factory => :route      factory :journey_pattern do diff --git a/spec/factories/chouette_networks.rb b/spec/factories/chouette_networks.rb index 3ad719cd9..afeac9e28 100644 --- a/spec/factories/chouette_networks.rb +++ b/spec/factories/chouette_networks.rb @@ -2,7 +2,7 @@ FactoryGirl.define do    factory :network, :class => Chouette::Network do      sequence(:name) { |n| "Network #{n}" } -    sequence(:objectid) { |n| "chouette:test:GroupOfLine:#{n}" } +    sequence(:objectid) { |n| "STIF:CODIFLIGNE:Network:#{n}" }      sequence(:registration_number) { |n| "test-#{n}" }      association :line_referential diff --git a/spec/factories/chouette_routes.rb b/spec/factories/chouette_routes.rb index a707bcbf6..4986ab70e 100644 --- a/spec/factories/chouette_routes.rb +++ b/spec/factories/chouette_routes.rb @@ -6,7 +6,7 @@ FactoryGirl.define do      sequence(:number) { |n| "#{n}" }      sequence(:wayback) { |n| Chouette::Route.wayback.values[n % 2] }      sequence(:direction) { |n| Chouette::Route.direction.values[n % 12] } -    sequence(:objectid) { |n| "test:Route:#{n}" } +    sequence(:objectid) { |n| "organisation:Route:lineId-routeId#{n}:LOC" }      association :line, :factory => :line diff --git a/spec/factories/chouette_routing_constraint_zones.rb b/spec/factories/chouette_routing_constraint_zones.rb index 8ef2ddb43..7748a4f74 100644 --- a/spec/factories/chouette_routing_constraint_zones.rb +++ b/spec/factories/chouette_routing_constraint_zones.rb @@ -1,6 +1,7 @@  FactoryGirl.define do    factory :routing_constraint_zone, class: Chouette::RoutingConstraintZone do      sequence(:name) { |n| "Routing constraint zone #{n}" } +    sequence(:objectid) { |n| "organisation:RoutingConstraintZone:lineId-routeId-#{n}:LOC" }      association :route, factory: :route      after(:build) do |zone|        route = Chouette::Route.find(zone.route_id) diff --git a/spec/factories/chouette_stop_points.rb b/spec/factories/chouette_stop_points.rb index 690d1c688..14e08b1ac 100644 --- a/spec/factories/chouette_stop_points.rb +++ b/spec/factories/chouette_stop_points.rb @@ -1,7 +1,7 @@  FactoryGirl.define do    factory :stop_point, :class => Chouette::StopPoint do -    sequence(:objectid) { |n| "test:StopPoint:#{n}" } +    sequence(:objectid) { |n| "test:StopPoint:#{n}:loc" }      association :stop_area, :factory => :stop_area    end diff --git a/spec/factories/chouette_time_table.rb b/spec/factories/chouette_time_table.rb index b410d4ab8..a3ff63b2f 100644 --- a/spec/factories/chouette_time_table.rb +++ b/spec/factories/chouette_time_table.rb @@ -1,7 +1,7 @@  FactoryGirl.define do    factory :time_table, :class => Chouette::TimeTable do      sequence(:comment) { |n| "Timetable #{n}" } -    sequence(:objectid) { |n| "test:Timetable:#{n}" } +    sequence(:objectid) { |n| "organisation:Timetable:#{n}:LOC" }      sequence(:int_day_types) { (1..7).to_a.map{ |n| 2**(n+1)}.sum }      calendar nil diff --git a/spec/factories/chouette_timeband.rb b/spec/factories/chouette_timeband.rb index 6e2825c22..010461479 100644 --- a/spec/factories/chouette_timeband.rb +++ b/spec/factories/chouette_timeband.rb @@ -4,14 +4,14 @@ FactoryGirl.define do      sequence(:name) { |n| "Name: #{n}" }      start_time { Time.now }      end_time { Time.now + 1.hour } -    sequence(:objectid) { |n| "test:Timeband:#{n}" } +    sequence(:objectid) { |n| "test:Timeband:#{n}:loc" }    end    factory :timeband_invalid, class: Chouette::Timeband do      sequence(:name) { |n| "Name: #{n}" }      start_time { Time.now + 1.hour }      end_time { Time.now } -    sequence(:objectid) { |n| "test:Timeband:#{n}" } +    sequence(:objectid) { |n| "test:Timeband:#{n}:loc" }    end  end diff --git a/spec/factories/chouette_vehicle_journey.rb b/spec/factories/chouette_vehicle_journey.rb index d1e00cd1d..5f64bd502 100644 --- a/spec/factories/chouette_vehicle_journey.rb +++ b/spec/factories/chouette_vehicle_journey.rb @@ -1,7 +1,7 @@  FactoryGirl.define do    factory :vehicle_journey_common, :class => Chouette::VehicleJourney do -    sequence(:objectid) { |n| "test:VehicleJourney:#{n}" } +    sequence(:objectid) { |n| "organisation:VehicleJourney:lineid-#{n}:LOC" }      factory :vehicle_journey_empty do        association :journey_pattern, :factory => :journey_pattern diff --git a/spec/factories/import_messages.rb b/spec/factories/import_messages.rb new file mode 100644 index 000000000..75f80566c --- /dev/null +++ b/spec/factories/import_messages.rb @@ -0,0 +1,7 @@ +FactoryGirl.define do +  factory :import_message do +    association :import +    association :resource, factory: :import_resource +    criticity :info +  end +end diff --git a/spec/factories/workbenches.rb b/spec/factories/workbenches.rb index f51e7d94c..d55141513 100644 --- a/spec/factories/workbenches.rb +++ b/spec/factories/workbenches.rb @@ -1,8 +1,8 @@  FactoryGirl.define do    factory :workbench do -    sequence(:name) { |n| "Workbench #{n}" } +    name "Gestion de l'offre" -    association :organisation, :factory => :organisation +    association :organisation      association :line_referential      association :stop_area_referential    end diff --git a/spec/features/connection_links_spec.rb b/spec/features/connection_links_spec.rb index 0325e6e1c..7272242fe 100644 --- a/spec/features/connection_links_spec.rb +++ b/spec/features/connection_links_spec.rb @@ -34,7 +34,7 @@ RSpec.describe "ConnectionLinks", :type => :feature do        visit referential_connection_links_path(referential)        click_link "Ajouter une correspondance"        fill_in "Nom", :with => "ConnectionLink 1" -      fill_in "Identifiant Neptune", :with => "test:ConnectionLink:1" +      fill_in "Identifiant Neptune", :with => "test:ConnectionLink:1:LOC"        click_button("CrĂ©er correspondance")        expect(page).to have_content("ConnectionLink 1")      end diff --git a/spec/features/referentials_spec.rb b/spec/features/referentials_spec.rb index 337271fea..a38577aba 100644 --- a/spec/features/referentials_spec.rb +++ b/spec/features/referentials_spec.rb @@ -120,6 +120,73 @@ describe "Referentials", :type => :feature do    end +  describe "new_from" do +    # let(:cloning) +    let(:worker) { ReferentialCloningWorker.new } + +    let(:line) { create(:line_with_stop_areas) } +    let(:jp) { create(:journey_pattern, route: line.routes.first) } +    let(:tt) { create(:time_table) } +    let(:vj) { create(:vehicle_journey, journey_pattern: jp, time_table: tt) } +    let(:ref_metadata) { create(:referential_metadata, lines: [line], referential: referential) } + +    context "when user is from the same organisation" do + +      xit "should" do +        visit new_referential_path(from: referential.id, current_workbench_id: @user.organisation.workbenches.first.id) + +        select "2018", :from => "referential_metadatas_attributes_0_periods_attributes_0_begin_1i" + +        select "2018", :from => "referential_metadatas_attributes_0_periods_attributes_0_end_1i" + +        click_button "Valider" + +        clone = Referential.where(name: "Copie de first") + +        expect(clone.lines).to include(line) +        expect(clone.lines.first.routes).to match_array(referential.lines.first.routes) + +        clone_jp = clone.lines.first.routes.first.journey_patterns +        expect(clone_jp).to include(jp) + +        clone_vj = clone.lines.first.routes.first.journey_patterns.first.vehicle_journeys +        expect(clone_vj).to include(vj) + +        clone_tt = clone.lines.first.routes.first.journey_patterns.first.vehicle_journeys.first.time_tables +        expect(clone_tt).to include(tt) +      end + +      # it "should have the lines from source" do +      #   expect(clone.lines).to include(line) +      # end +      # +      # it "should have the routes from source" do +      #   expect(clone.lines.first.routes).to match_array(referential.lines.first.routes) +      # end +      # +      # it "should have the journey patterns from source" do +      #   clone_jp = clone.lines.first.routes.first.journey_patterns +      #   expect(clone_jp).to include(jp) +      # end +      # +      # it "should have the vehicle journeys from source" do +      #   clone_vj = clone.lines.first.routes.first.journey_patterns.first.vehicle_journeys +      #   expect(clone_vj).to include(vj) +      # end +      # +      # it "should have the timetables from source" do +      #   clone_tt = clone.lines.first.routes.first.journey_patterns.first.vehicle_journeys.first.time_tables +      #   expect(clone_tt).to include(tt) +      # end +    end + +    # context "when user is from another organisation" do +    #   before :each do +    # +    #   end +    # end +  end +    describe "destroy" do      let(:referential) {  create(:referential, :organisation => @user.organisation) } diff --git a/spec/features/users/user_edit_spec.rb b/spec/features/users/user_edit_spec.rb index 4b083a226..14995d8e5 100644 --- a/spec/features/users/user_edit_spec.rb +++ b/spec/features/users/user_edit_spec.rb @@ -36,6 +36,7 @@ feature 'User edit', :devise do    #   Then I see my own 'edit profile' page    scenario "user cannot cannot edit another user's profile", :me do      me = FactoryGirl.create(:user) +    me.organisation.workbenches << create(:workbench)      other = FactoryGirl.create(:user, email: 'other@example.com')      login_as(me, :scope => :user)      visit edit_user_registration_path(other) diff --git a/spec/features/users/user_index_spec.rb b/spec/features/users/user_index_spec.rb index 2a9199da3..b2dbdbb51 100644 --- a/spec/features/users/user_index_spec.rb +++ b/spec/features/users/user_index_spec.rb @@ -19,6 +19,7 @@ feature 'User index page', :devise do    #   Then I see my own email address    scenario 'user sees own email address' do      user = create(:user) +    user.organisation.workbenches << create(:workbench)      login_as(user, scope: :user)      visit organisation_path      expect(page).to have_content user.name.truncate(15) diff --git a/spec/features/users/user_show_spec.rb b/spec/features/users/user_show_spec.rb index d840d752c..ae3c25933 100644 --- a/spec/features/users/user_show_spec.rb +++ b/spec/features/users/user_show_spec.rb @@ -19,6 +19,7 @@ feature 'User profile page', :devise do    #   Then I see my own email address    scenario 'user sees own profile' do      user = FactoryGirl.create(:user) +    user.organisation.workbenches << create(:workbench)      login_as(user, :scope => :user)      visit organisation_user_path(user)      # FIXME ref #819 @@ -32,6 +33,7 @@ feature 'User profile page', :devise do    #   Then I see an 'access denied' message    scenario "user cannot see another user's profile" do      me = FactoryGirl.create(:user) +    me.organisation.workbenches << create(:workbench)      other = FactoryGirl.create(:user, email: 'other@example.com', :organisation => me.organisation)      login_as(me, :scope => :user)      Capybara.current_session.driver.header 'Referer', authenticated_root_path diff --git a/spec/features/workbenches_spec.rb b/spec/features/workbenches_spec.rb index d1ba0046f..14809dec1 100644 --- a/spec/features/workbenches_spec.rb +++ b/spec/features/workbenches_spec.rb @@ -169,7 +169,7 @@ describe 'Workbenches', type: :feature do          end          context 'user does not have the permission to create referentials' do -          xit 'does not show the clone link for referential' do +          it 'does not show the clone link for referential' do              @user.update_attribute(:permissions, [])              visit referential_path(referential)              expect(page).not_to have_link(I18n.t('actions.add'), href: new_referential_path(workbench_id: workbench.id)) @@ -178,16 +178,24 @@ describe 'Workbenches', type: :feature do        end        describe 'create new Referential' do -        xit "create a new Referential with a specifed line and period" do -          referential.destroy - -          visit workbench_path(workbench) -          click_link I18n.t('actions.add') -          fill_in "referential[name]", with: "Referential to test creation" -          select workbench.lines.first.id, from: 'referential[metadatas_attributes][0][lines][]' - -          click_button "Valider" -          expect(page).to have_css("h1", text: "Referential to test creation") +        #TODO Manage functional_scope +        it "create a new Referential with a specifed line and period" do +          skip "The functional scope for the Line collection causes problems" do +            functional_scope = JSON.generate(Chouette::Line.all.map(&:objectid)) +            lines = Chouette::Line.where(objectid: functional_scope) + +            @user.organisation.update_attribute(:sso_attributes, { functional_scope: functional_scope } ) +            ref_metadata.update_attribute(:line_ids, lines.map(&:id)) + +            referential.destroy +            visit workbench_path(workbench) +            click_link I18n.t('actions.add') +            fill_in "referential[name]", with: "Referential to test creation" +            select ref_metadata.line_ids.first, from: 'referential[metadatas_attributes][0][lines][]' + +            click_button "Valider" +            expect(page).to have_css("h1", text: "Referential to test creation") +          end          end        end      end diff --git a/spec/models/chouette/access_link_spec.rb b/spec/models/chouette/access_link_spec.rb index 0e1e91593..5a31b8f0c 100644 --- a/spec/models/chouette/access_link_spec.rb +++ b/spec/models/chouette/access_link_spec.rb @@ -7,7 +7,7 @@ describe Chouette::AccessLink, :type => :model do    describe '#objectid' do      subject { super().objectid } -    it { is_expected.to be_kind_of(Chouette::ObjectId) } +    it { is_expected.to be_kind_of(Chouette::StifNetexObjectid) }    end    it { is_expected.to validate_presence_of :name } @@ -19,7 +19,7 @@ describe Chouette::AccessLink, :type => :model do      def self.legacy_link_types        %w{Underground Mixed Overground}      end -     +      legacy_link_types.each do |link_type|        context "when link_type is #{link_type}" do          access_link_type = Chouette::ConnectionLinkType.new(link_type.underscore) @@ -32,7 +32,7 @@ describe Chouette::AccessLink, :type => :model do    end    describe "#access_link_type=" do -     +      it "should change link_type with ConnectionLinkType#name" do        subject.access_link_type = "underground"        expect(subject.link_type).to eq("Underground") @@ -45,7 +45,7 @@ describe Chouette::AccessLink, :type => :model do      def self.legacy_link_orientations        %w{AccessPointToStopArea StopAreaToAccessPoint}      end -     +      legacy_link_orientations.each do |link_orientation|        context "when link_orientation is #{link_orientation}" do          link_orientation_type = Chouette::LinkOrientationType.new(link_orientation.underscore) @@ -59,7 +59,7 @@ describe Chouette::AccessLink, :type => :model do    end    describe "#link_orientation_type=" do -     +      it "should change link_orientation with LinkOrientationType#name" do        subject.link_orientation_type = "access_point_to_stop_area"        expect(subject.link_orientation).to eq("AccessPointToStopArea") @@ -76,7 +76,7 @@ describe Chouette::AccessLink, :type => :model do        subject.link_orientation_type = "stop_area_to_access_point"        expect(subject.link_key).to eq("S_#{subject.stop_area.id}-A_#{subject.access_point.id}")      end -     +    end  end diff --git a/spec/models/chouette/company_spec.rb b/spec/models/chouette/company_spec.rb index 3da8b4311..a3101d79c 100644 --- a/spec/models/chouette/company_spec.rb +++ b/spec/models/chouette/company_spec.rb @@ -1,13 +1,8 @@  require 'spec_helper'  describe Chouette::Company, :type => :model do -    subject { create(:company) } - -  it { is_expected.to validate_presence_of :name } - -  # it { should validate_presence_of :objectid } -  it { is_expected.to validate_uniqueness_of :objectid } +  it { should validate_presence_of :name }    describe "#nullables empty" do      it "should set null empty nullable attributes" do diff --git a/spec/models/chouette/connection_link_spec.rb b/spec/models/chouette/connection_link_spec.rb index 5921bf581..57eb7d66c 100644 --- a/spec/models/chouette/connection_link_spec.rb +++ b/spec/models/chouette/connection_link_spec.rb @@ -11,7 +11,7 @@ describe Chouette::ConnectionLink, :type => :model do    describe '#objectid' do      subject { super().objectid } -    it { is_expected.to be_kind_of(Chouette::ObjectId) } +    it { is_expected.to be_kind_of(Chouette::StifNetexObjectid) }    end    it { is_expected.to validate_presence_of :name } diff --git a/spec/models/chouette/footnote_spec.rb b/spec/models/chouette/footnote_spec.rb index 98d751499..fc5e5f306 100644 --- a/spec/models/chouette/footnote_spec.rb +++ b/spec/models/chouette/footnote_spec.rb @@ -2,9 +2,21 @@ require 'spec_helper'  describe Chouette::Footnote, type: :model do    let(:footnote) { create(:footnote) } -    it { should validate_presence_of :line } +  describe 'data_source_ref' do +    it 'should set default if omitted' do +      expect(footnote.data_source_ref).to eq "DATASOURCEREF_EDITION_BOIV" +    end + +    it 'should not set default if not omitted' do +      source = "RANDOM_DATASOURCE" +      object = build(:footnote, data_source_ref: source) +      object.save +      expect(object.data_source_ref).to eq source +    end +  end +    describe 'checksum' do      it_behaves_like 'checksum support', :footnote diff --git a/spec/models/chouette/group_of_line_spec.rb b/spec/models/chouette/group_of_line_spec.rb index d49329118..29b4433c5 100644 --- a/spec/models/chouette/group_of_line_spec.rb +++ b/spec/models/chouette/group_of_line_spec.rb @@ -3,11 +3,7 @@ require 'spec_helper'  describe Chouette::GroupOfLine, :type => :model do    subject { create(:group_of_line) } - -  it { is_expected.to validate_presence_of :name } - -  # it { should validate_presence_of :objectid } -  it { is_expected.to validate_uniqueness_of :objectid } +  it { should validate_presence_of :name }    describe "#stop_areas" do      let!(:line){create(:line, :group_of_lines => [subject])} diff --git a/spec/models/chouette/network_spec.rb b/spec/models/chouette/network_spec.rb index c9e510e84..32bacc512 100644 --- a/spec/models/chouette/network_spec.rb +++ b/spec/models/chouette/network_spec.rb @@ -1,13 +1,8 @@  require 'spec_helper'  describe Chouette::Network, :type => :model do -    subject { create(:network) } - -  it { is_expected.to validate_presence_of :name } - -  # it { should validate_presence_of :objectid } -  it { is_expected.to validate_uniqueness_of :objectid } +  it { should validate_presence_of :name }    describe "#stop_areas" do      let!(:line){create(:line, :network => subject)} diff --git a/spec/models/chouette/route/route_base_spec.rb b/spec/models/chouette/route/route_base_spec.rb index c93b311ff..794da4f1b 100644 --- a/spec/models/chouette/route/route_base_spec.rb +++ b/spec/models/chouette/route/route_base_spec.rb @@ -7,7 +7,7 @@ RSpec.describe Chouette::Route, :type => :model do    describe '#objectid' do      subject { super().objectid } -    it { is_expected.to be_kind_of(Chouette::ObjectId) } +    it { is_expected.to be_kind_of(Chouette::StifNetexObjectid) }    end    it { is_expected.to enumerize(:direction).in(:straight_forward, :backward, :clockwise, :counter_clockwise, :north, :north_west, :west, :south_west, :south, :south_east, :east, :north_east) } diff --git a/spec/models/chouette/route/route_duplication_spec.rb b/spec/models/chouette/route/route_duplication_spec.rb new file mode 100644 index 000000000..6645b909f --- /dev/null +++ b/spec/models/chouette/route/route_duplication_spec.rb @@ -0,0 +1,52 @@ +# From Chouette import what we need âą +Route     = Chouette::Route +StopArea  = Chouette::StopArea +StopPoint = Chouette::StopPoint + +RSpec.describe Route do + +  let!( :route ){ create :route } + +  context '#duplicate' do  +    describe 'properties' do +      it 'same attribute values' do +        route.duplicate +        expect( values_for_create(Route.last, except: %w{objectid}) ).to eq( values_for_create( route, except: %w{objectid} ) ) +      end +      it 'and others cannot' do +        expect{ route.duplicate name: 'YAN', line_id: 42  }.to raise_error(ArgumentError) +      end +      it 'same associated stop_areeas' do +        expect( route.duplicate.stop_areas.pluck(:id) ).to eq(route.stop_areas.pluck(:id)) +      end +    end + +    describe 'side_effects' do +      it { +        expect{ route.duplicate }.to change{Route.count}.by(1) +      } +      it 'duplicates its stop points' do +        expect{ route.duplicate }.to change{StopPoint.count}.by(route.stop_points.count) +      end +      it 'does bot duplicate the stop areas' do +        expect{ route.duplicate }.not_to change{StopArea.count} +      end +    end + +    describe 'is idempotent, concerning' do +      let( :first_duplicate ){ route.duplicate  } +      let( :second_duplicate ){ first_duplicate.reload.duplicate } + +      it 'the required attributes' do +        expect( values_for_create(first_duplicate, except: %w{objectid}) ).to eq( values_for_create( second_duplicate, except: %w{objectid} ) ) +      end  + +      it 'the stop areas' do +        expect( first_duplicate.stop_areas.pluck(:id) ).to eq( route.stop_areas.pluck(:id) ) +        expect( second_duplicate.stop_areas.pluck(:id) ).to eq( first_duplicate.stop_areas.pluck(:id) ) +      end + +    end +  end + +end diff --git a/spec/models/chouette/routing_constraint_zone_spec.rb b/spec/models/chouette/routing_constraint_zone_spec.rb index 054cfb9e6..c344642e6 100644 --- a/spec/models/chouette/routing_constraint_zone_spec.rb +++ b/spec/models/chouette/routing_constraint_zone_spec.rb @@ -3,7 +3,6 @@ require 'spec_helper'  describe Chouette::RoutingConstraintZone, type: :model do    subject { create(:routing_constraint_zone) } -  let!(:routing_constraint_zone) { create(:routing_constraint_zone) }    it { is_expected.to validate_presence_of :name }    # shoulda matcher to validate length of array ? @@ -16,38 +15,38 @@ describe Chouette::RoutingConstraintZone, type: :model do    describe 'validations' do      it 'validates the presence of route_id' do        expect { -        routing_constraint_zone.update!(route_id: nil) +        subject.update!(route_id: nil)        }.to raise_error(NoMethodError)      end      it 'validates the presence of stop_point_ids' do        expect { -        routing_constraint_zone.update!(stop_point_ids: []) +        subject.update!(stop_point_ids: [])        }.to raise_error(ActiveRecord::RecordInvalid)      end      it 'validates that stop points belong to the route' do        route = create(:route)        expect { -        routing_constraint_zone.update!(route_id: route.id) +        subject.update!(route_id: route.id)        }.to raise_error(ActiveRecord::RecordInvalid)      end      xit 'validates that not all stop points from the route are selected' do        routing_constraint_zone.stop_points = routing_constraint_zone.route.stop_points        expect { -        routing_constraint_zone.save! +        subject.save!        }.to raise_error(ActiveRecord::RecordInvalid)      end    end    describe 'deleted stop areas' do      it 'does not have them in stop_area_ids' do -      stop_point = routing_constraint_zone.route.stop_points.last -      routing_constraint_zone.stop_points << stop_point -      routing_constraint_zone.save! -      routing_constraint_zone.route.stop_points.last.destroy! -      expect(routing_constraint_zone.stop_points.map(&:id)).not_to include(stop_point.id) +      stop_point = subject.route.stop_points.last +      subject.stop_points << stop_point +      subject.save! +      subject.route.stop_points.last.destroy! +      expect(subject.stop_points.map(&:id)).not_to include(stop_point.id)      end    end diff --git a/spec/models/chouette/stop_point_spec.rb b/spec/models/chouette/stop_point_spec.rb index 212c32e1a..329e76a75 100644 --- a/spec/models/chouette/stop_point_spec.rb +++ b/spec/models/chouette/stop_point_spec.rb @@ -1,6 +1,7 @@ -require 'spec_helper' +# From Chouette import what we need âą +StopPoint = Chouette::StopPoint -describe Chouette::StopPoint, :type => :model do +describe StopPoint, :type => :model do    let!(:vehicle_journey) { create(:vehicle_journey)}    subject { Chouette::Route.find( vehicle_journey.route_id).stop_points.first } @@ -9,7 +10,7 @@ describe Chouette::StopPoint, :type => :model do    describe '#objectid' do      subject { super().objectid } -    it { is_expected.to be_kind_of(Chouette::ObjectId) } +    it { is_expected.to be_kind_of(Chouette::StifNetexObjectid) }    end    describe "#destroy" do @@ -38,4 +39,18 @@ describe Chouette::StopPoint, :type => :model do        expect(jpsp_stop_point_ids(@vehicle.journey_pattern_id)).not_to include(@stop_point.id)      end    end + +  describe '#duplicate' do +    let!( :new_route ){ create :route } + +    it 'creates a new instance' do +      expect{ subject.duplicate(for_route: new_route) }.to change{ StopPoint.count }.by(1) +    end +    it 'new instance has a new route' do +      expect(subject.duplicate(for_route: new_route).route).to eq(new_route) +    end +    it 'and old stop_area' do +      expect(subject.duplicate(for_route: new_route).stop_area).to eq(subject.stop_area) +    end +  end  end diff --git a/spec/models/chouette/time_table_spec.rb b/spec/models/chouette/time_table_spec.rb index c4eaeaaf0..761c39e5b 100644 --- a/spec/models/chouette/time_table_spec.rb +++ b/spec/models/chouette/time_table_spec.rb @@ -820,13 +820,13 @@ end    describe "#intersects" do      it "should return day if a date equal day" do -      time_table = Chouette::TimeTable.create!(:comment => "Test", :objectid => "test:Timetable:1") +      time_table = Chouette::TimeTable.create!(:comment => "Test", :objectid => "test:Timetable:1:loc")        time_table.dates << Chouette::TimeTableDate.new( :date => Date.today, :in_out => true)        expect(time_table.intersects([Date.today])).to eq([Date.today])      end      it "should return [] if a period not include days" do -      time_table = Chouette::TimeTable.create!(:comment => "Test", :objectid => "test:Timetable:1", :int_day_types => 12) +      time_table = Chouette::TimeTable.create!(:comment => "Test", :objectid => "test:Timetable:1:loc", :int_day_types => 12)        time_table.periods << Chouette::TimeTablePeriod.new(                                :period_start => Date.new(2013, 05, 27),                                :period_end => Date.new(2013, 05, 30)) @@ -834,7 +834,7 @@ end      end      it "should return days if a period include day" do -      time_table = Chouette::TimeTable.create!(:comment => "Test", :objectid => "test:Timetable:1", :int_day_types => 12) # Day type monday and tuesday +      time_table = Chouette::TimeTable.create!(:comment => "Test", :objectid => "test:Timetable:1:loc", :int_day_types => 12) # Day type monday and tuesday        time_table.periods << Chouette::TimeTablePeriod.new(                                :period_start => Date.new(2013, 05, 27),                                :period_end => Date.new(2013, 05, 30)) @@ -842,6 +842,207 @@ end      end    end +  describe "#include_day?" do +    it "should return true if a date equal day" do +      time_table = Chouette::TimeTable.create!(:comment => "Test", :objectid => "test:Timetable:1:loc") +      time_table.dates << Chouette::TimeTableDate.new( :date => Date.today, :in_out => true) +      expect(time_table.include_day?(Date.today)).to eq(true) +    end + +    it "should return true if a period include day" do +      time_table = Chouette::TimeTable.create!(:comment => "Test", :objectid => "test:Timetable:1:loc", :int_day_types => 12) # Day type monday and tuesday +      time_table.periods << Chouette::TimeTablePeriod.new( +                              :period_start => Date.new(2013, 05, 27), +                              :period_end => Date.new(2013, 05, 29)) +      expect(time_table.include_day?( Date.new(2013, 05, 27))).to eq(true) +    end +  end + +  describe "#include_in_dates?" do +    it "should return true if a date equal day" do +      time_table = Chouette::TimeTable.create!(:comment => "Test", :objectid => "test:Timetable:1:loc") +      time_table.dates << Chouette::TimeTableDate.new( :date => Date.today, :in_out => true) +      expect(time_table.include_in_dates?(Date.today)).to eq(true) +    end + +    it "should return false if a period include day  but that is exclued" do +      time_table = Chouette::TimeTable.create!(:comment => "Test", :objectid => "test:Timetable:1:loc", :int_day_types => 12) # Day type monday and tuesday +      excluded_date = Date.new(2013, 05, 27) +      time_table.dates << Chouette::TimeTableDate.new( :date => excluded_date, :in_out => false) +      expect(time_table.include_in_dates?( excluded_date)).to be_falsey +    end +  end + +  describe "#include_in_periods?" do +    it "should return true if a period include day" do +      time_table = Chouette::TimeTable.create!(:comment => "Test", :objectid => "test:Timetable:1:loc", :int_day_types => 4) +      time_table.periods << Chouette::TimeTablePeriod.new( +                              :period_start => Date.new(2012, 1, 1), +                              :period_end => Date.new(2012, 01, 30)) +      expect(time_table.include_in_periods?(Date.new(2012, 1, 2))).to eq(true) +    end + +    it "should return false if a period include day  but that is exclued" do +      time_table = Chouette::TimeTable.create!(:comment => "Test", :objectid => "test:Timetable:1:loc", :int_day_types => 12) # Day type monday and tuesday +      excluded_date = Date.new(2013, 05, 27) +      time_table.dates << Chouette::TimeTableDate.new( :date => excluded_date, :in_out => false) +      time_table.periods << Chouette::TimeTablePeriod.new( +                              :period_start => Date.new(2013, 05, 27), +                              :period_end => Date.new(2013, 05, 29)) +      expect(time_table.include_in_periods?( excluded_date)).to be_falsey +    end +  end + +  describe "#include_in_overlap_dates?" do +    it "should return true if a day is included in overlap dates" do +      time_table = Chouette::TimeTable.create!(:comment => "Test", :objectid => "test:Timetable:1:loc", :int_day_types => 4) +      time_table.periods << Chouette::TimeTablePeriod.new( +                              :period_start => Date.new(2012, 1, 1), +                              :period_end => Date.new(2012, 01, 30)) +      time_table.dates << Chouette::TimeTableDate.new( :date => Date.new(2012, 1, 2), :in_out => true) +      expect(time_table.include_in_overlap_dates?(Date.new(2012, 1, 2))).to eq(true) +    end +    it "should return false if the day is excluded" do +      time_table = Chouette::TimeTable.create!(:comment => "Test", :objectid => "test:Timetable:1:loc", :int_day_types => 4) +      time_table.periods << Chouette::TimeTablePeriod.new( +                              :period_start => Date.new(2012, 1, 1), +                              :period_end => Date.new(2012, 01, 30)) +      time_table.dates << Chouette::TimeTableDate.new( :date => Date.new(2012, 1, 2), :in_out => false) +      expect(time_table.include_in_overlap_dates?(Date.new(2012, 1, 2))).to be_falsey +    end +  end + +  describe "#dates" do +    it "should have with position 0" do +      expect(subject.dates.first.position).to eq(0) +    end +    context "when first date has been removed" do +      before do +        subject.dates.first.destroy +      end +      it "should begin with position 0" do +        expect(subject.dates.first.position).to eq(0) +      end +    end +  end +  describe "#validity_out_between?" do +    let(:empty_tm) {build(:time_table)} +    it "should be false if empty calendar" do +      expect(empty_tm.validity_out_between?( Date.today, Date.today + 7.day)).to be_falsey +    end +    it "should be true if caldendar is out during start_date and end_date period" do +      start_date = subject.bounding_dates.max - 2.day +      end_date = subject.bounding_dates.max + 2.day +      expect(subject.validity_out_between?( start_date, end_date)).to be_truthy +    end +    it "should be false if calendar is out on start date" do +      start_date = subject.bounding_dates.max +      end_date = subject.bounding_dates.max + 2.day +      expect(subject.validity_out_between?( start_date, end_date)).to be_falsey +    end +    it "should be false if calendar is out on end date" do +      start_date = subject.bounding_dates.max - 2.day +      end_date = subject.bounding_dates.max +      expect(subject.validity_out_between?( start_date, end_date)).to be_truthy +    end +    it "should be false if calendar is out after start_date" do +      start_date = subject.bounding_dates.max + 2.day +      end_date = subject.bounding_dates.max + 4.day +      expect(subject.validity_out_between?( start_date, end_date)).to be_falsey +    end +  end +  describe "#validity_out_from_on?" do +    let(:empty_tm) {build(:time_table)} +    it "should be false if empty calendar" do +      expect(empty_tm.validity_out_from_on?( Date.today)).to be_falsey +    end +    it "should be true if caldendar ends on expected date" do +      expected_date = subject.bounding_dates.max +      expect(subject.validity_out_from_on?( expected_date)).to be_truthy +    end +    it "should be true if calendar ends before expected date" do +      expected_date = subject.bounding_dates.max + 30.day +      expect(subject.validity_out_from_on?( expected_date)).to be_truthy +    end +    it "should be false if calendars ends after expected date" do +      expected_date = subject.bounding_dates.max - 30.day +      expect(subject.validity_out_from_on?( expected_date)).to be_falsey +    end +  end +  describe "#bounding_dates" do +    context "when timetable contains only periods" do +      before do +        subject.dates = [] +        subject.save +      end +      it "should retreive periods.period_start.min and periods.period_end.max" do +        expect(subject.bounding_dates.min).to eq(subject.periods.map(&:period_start).min) +        expect(subject.bounding_dates.max).to eq(subject.periods.map(&:period_end).max) +      end +    end +    context "when timetable contains only dates" do +      before do +        subject.periods = [] +        subject.save +      end +      it "should retreive dates.min and dates.max" do +        expect(subject.bounding_dates.min).to eq(subject.dates.map(&:date).min) +        expect(subject.bounding_dates.max).to eq(subject.dates.map(&:date).max) +      end +    end +    it "should contains min date" do +      min_date = subject.bounding_dates.min +      subject.dates.each do |tm_date| +        expect(min_date <= tm_date.date).to be_truthy +      end +      subject.periods.each do |tm_period| +        expect(min_date <= tm_period.period_start).to be_truthy +      end + +    end +    it "should contains max date" do +      max_date = subject.bounding_dates.max +      subject.dates.each do |tm_date| +        expect(tm_date.date <= max_date).to be_truthy +      end +      subject.periods.each do |tm_period| +        expect(tm_period.period_end <= max_date).to be_truthy +      end + +    end +  end +  describe "#periods" do +    it "should begin with position 0" do +      expect(subject.periods.first.position).to eq(0) +    end +    context "when first period has been removed" do +      before do +        subject.periods.first.destroy +      end +      it "should begin with position 0" do +        expect(subject.periods.first.position).to eq(0) +      end +    end +    it "should have period_start before period_end" do +      period = Chouette::TimeTablePeriod.new +      period.period_start = Date.today +      period.period_end = Date.today + 10 +      expect(period.valid?).to be_truthy +    end +    it "should not have period_start after period_end" do +      period = Chouette::TimeTablePeriod.new +      period.period_start = Date.today +      period.period_end = Date.today - 10 +      expect(period.valid?).to be_falsey +    end +    it "should not have period_start equal to period_end" do +      period = Chouette::TimeTablePeriod.new +      period.period_start = Date.today +      period.period_end = Date.today +      expect(period.valid?).to be_falsey +    end +  end +    # it { is_expected.to validate_presence_of :comment }    # it { is_expected.to validate_uniqueness_of :objectid } @@ -964,7 +1165,6 @@ end          target=subject.duplicate          expect(target.id).to be_nil          expect(target.comment).to eq(I18n.t("activerecord.copy", name: subject.comment)) -        expect(target.objectid).to eq(subject.objectid+"_1")          expect(target.int_day_types).to eq(subject.int_day_types)          expect(target.dates.size).to eq(subject.dates.size)          target.dates.each do |d| diff --git a/spec/models/chouette/trident_active_record_spec.rb b/spec/models/chouette/trident_active_record_spec.rb index 76544f85d..d5e30594d 100644 --- a/spec/models/chouette/trident_active_record_spec.rb +++ b/spec/models/chouette/trident_active_record_spec.rb @@ -1,119 +1,57 @@  require 'spec_helper'  describe Chouette::TridentActiveRecord, :type => :model do - -  it { expect(Chouette::TridentActiveRecord.ancestors).to include(Chouette::ActiveRecord) } -    subject { create(:time_table) } -  describe "#uniq_objectid" do +  it { should validate_presence_of :objectid } +  it { should validate_uniqueness_of :objectid } -    it "should rebuild objectid" do -      tm = create(:time_table) -      tm.objectid = subject.objectid -      tm.uniq_objectid -      expect(tm.objectid).to eq(subject.objectid+"_1") -    end +  describe "#default_values" do +    let(:object) { build(:time_table, objectid: nil) } -    it "should rebuild objectid" do -      tm = create(:time_table) -      tm.objectid = subject.objectid -      tm.uniq_objectid -      tm.save -      tm = create(:time_table) -      tm.objectid = subject.objectid -      tm.uniq_objectid -      expect(tm.objectid).to eq(subject.objectid+"_2") +    it 'should fill __pending_id__' do +      object.default_values +      expect(object.objectid.include?('__pending_id__')).to be_truthy      end -    end -  def create_object(options = {}) -    options = {name: "merge1"}.merge options -    attributes = { comment: options[:name], objectid: options[:objectid] } -    Chouette::TimeTable.new attributes -  end - -  describe "#prepare_auto_columns" do - -    it "should left objectid" do -      tm = create_object :objectid => "first:Timetable:merge1" -      tm.prepare_auto_columns -      expect(tm.objectid).to eq("first:Timetable:merge1") -    end - -    it "should add pending_id to objectid" do -      tm = create_object -      tm.prepare_auto_columns -      expect(tm.objectid.start_with?("first:Timetable:__pending_id__")).to be_truthy -    end - -    it "should set id to objectid" do -      tm = create_object -      tm.save -      expect(tm.objectid).to eq("first:Timetable:"+tm.id.to_s) -    end +  describe "#objectid" do +    let(:object) { build(:time_table, objectid: nil) } -    it "should detect objectid conflicts" do -      tm = create_object -      tm.save -      tm.objectid = "first:Timetable:"+(tm.id+1).to_s -      tm.save -      tm = create_object -      tm.save -      expect(tm.objectid).to eq("first:Timetable:"+tm.id.to_s+"_1") +    it 'should build objectid on create' do +      object.save +      id = "#{object.provider_id}:#{object.model_name}:#{object.local_id}:#{object.boiv_id}" +      expect(object.objectid).to eq(id)      end -  end - -  describe "objectid" do - -    it "should build automatic objectid when empty" do -      g1 = create_object -      g1.save -      expect(g1.objectid).to eq("first:Timetable:"+g1.id.to_s) +    it 'should call build_objectid on after save' do +      expect(object).to receive(:build_objectid) +      object.save      end -    it "should build automatic objectid with fixed when only suffix given" do -      g1 = create_object -      g1.objectid = "toto" -      g1.save -      expect(g1.objectid).to eq("first:Timetable:toto") +    it 'should not build new objectid is already set' do +      id = "first:TimeTable:1-1:LOC" +      object.objectid = id +      object.save +      expect(object.objectid).to eq(id)      end -    it "should build automatic objectid with extension when already exists" do -      g1 = create_object -      g1.save -      cnt = g1.id + 1 -      g1.objectid = "first:Timetable:"+cnt.to_s -      g1.save -      g2 = create_object -      g2.save -      expect(g2.objectid).to eq("first:Timetable:"+g2.id.to_s+"_1") +    it 'should call default_values on create' do +      expect(object).to receive(:default_values) +      object.save      end -    it "should build automatic objectid with extension when already exists" do -      g1 = create_object -      g1.save -      cnt = g1.id + 2 -      g1.objectid = "first:Timetable:"+cnt.to_s -      g1.save -      g2 = create_object -      g2.objectid = "first:Timetable:"+cnt.to_s+"_1" -      g2.save -      g3 = create_object -      g3.save -      expect(g3.objectid).to eq("first:Timetable:"+g3.id.to_s+"_2") +    it 'should not call default_values on update' do +      object = create(:time_table) +      expect(object).to_not receive(:default_values) +      object.touch      end -    it "should build automatic objectid when id cleared" do -      g1 = create_object -      g1.objectid = "first:Timetable:xxxx" -      g1.save -      g1.objectid = nil -      g1.save -      expect(g1.objectid).to eq("first:Timetable:"+g1.id.to_s) +    it 'should create a new objectid when cleared' do +      object.save +      object.objectid = nil +      object.save +      expect(object.objectid).to be_truthy      end    end -  end diff --git a/spec/models/concerns/error_format_spec.rb b/spec/models/concerns/error_format_spec.rb index 45b4c2f60..f82aecf44 100644 --- a/spec/models/concerns/error_format_spec.rb +++ b/spec/models/concerns/error_format_spec.rb @@ -1,7 +1,7 @@  RSpec.describe ErrorFormat do -   -  context '#details' do  -    context 'are empty' do  + +  context '#details' do +    context 'are empty' do        it 'if no errors are present' do          expect(            described_class.details(build_stubbed(:referential)) @@ -14,7 +14,7 @@ RSpec.describe ErrorFormat do        end      end -    context 'are not empty' do  +    context 'are not empty' do        it 'if an error is present and validation has been carried out' do          invalid = build_stubbed(:referential, name: nil)          expect( invalid ).not_to be_valid @@ -27,12 +27,12 @@ RSpec.describe ErrorFormat do          create(:referential, name: 'hello')          invalid = build_stubbed(            :referential, -          name: 'hello', +          name: '',            slug: 'hello world'          )          expect( invalid ).not_to be_valid          expect( described_class.details(invalid) ).to eq({ -          name: { error: "n'est pas disponible", value: 'hello' }, +          name: { error: "doit ĂȘtre rempli(e)", value: '' },            slug: { error: "n'est pas valide", value: 'hello world' }          })        end diff --git a/spec/models/import_spec.rb b/spec/models/import_spec.rb index 477d269e0..cd5a30982 100644 --- a/spec/models/import_spec.rb +++ b/spec/models/import_spec.rb @@ -26,12 +26,35 @@ RSpec.describe Import, type: :model do      )    end -  # describe "#destroy" do -  #   it "must call #destroy on imports children and then import_messages, import_resources linked" do -  #     TODO -  # -  #   end -  # end +  describe "#destroy" do +    it "must destroy all child imports" do +      workbench_import = create(:workbench_import) +      create(:netex_import, parent: workbench_import) + +      workbench_import.destroy + +      expect(workbench_import).to be_destroyed +      expect(NetexImport.count).to eq(0) +    end + +    it "must destroy all associated ImportMessages" do +      import = create(:import) +      create(:import_resource, import: import) + +      import.destroy + +      expect(ImportResource.count).to eq(0) +    end + +    it "must destroy all associated ImportResources" do +      import = create(:import) +      create(:import_message, import: import) + +      import.destroy + +      expect(ImportMessage.count).to eq(0) +    end +  end    describe "#notify_parent" do      it "must call #child_change on its parent" do diff --git a/spec/models/referential_metadata_spec.rb b/spec/models/referential_metadata_spec.rb index 775e6f228..291ed974a 100644 --- a/spec/models/referential_metadata_spec.rb +++ b/spec/models/referential_metadata_spec.rb @@ -30,8 +30,8 @@ RSpec.describe ReferentialMetadata, :type => :model do        expect(new_referential_metadata.referential).to be(nil)      end -    it "should have the same referential_source" do -      expect(new_referential_metadata.referential_source).to eq(referential_metadata.referential_source) +    it "should have the right referential_source" do +      expect(new_referential_metadata.referential_source).to eq(referential_metadata.referential)      end    end diff --git a/spec/models/vehicle_journey_export_spec.rb b/spec/models/vehicle_journey_export_spec.rb index 6252a73f9..83b3bbb04 100644 --- a/spec/models/vehicle_journey_export_spec.rb +++ b/spec/models/vehicle_journey_export_spec.rb @@ -2,7 +2,7 @@  require 'spec_helper'  describe VehicleJourneyExport, :type => :model do -   +    let!(:line) { create(:line) }    let!(:route) { create(:route, :line => line) }    let!(:other_route) { create(:route, :line => line) } @@ -10,10 +10,10 @@ describe VehicleJourneyExport, :type => :model do    let!(:journey_pattern) { create(:journey_pattern, :route => route) }    let!(:other_journey_pattern) { create(:journey_pattern_even, :route => route) } -  let!(:vehicle_journey1) { create(:vehicle_journey_common, :objectid => "export:VehicleJourney:1", :route_id => route.id, :journey_pattern_id => journey_pattern.id) } -  let!(:vehicle_journey2) { create(:vehicle_journey_common, :objectid => "export:VehicleJourney:2", :route_id => route.id, :journey_pattern_id => other_journey_pattern.id) } -  let!(:vehicle_journey3) { create(:vehicle_journey_common, :objectid => "export:VehicleJourney:3", :route_id => route.id, :journey_pattern_id => journey_pattern.id) } -   +  let!(:vehicle_journey1) { create(:vehicle_journey_common, :objectid => "export:VehicleJourney:1:loc", :route_id => route.id, :journey_pattern_id => journey_pattern.id) } +  let!(:vehicle_journey2) { create(:vehicle_journey_common, :objectid => "export:VehicleJourney:2:loc", :route_id => route.id, :journey_pattern_id => other_journey_pattern.id) } +  let!(:vehicle_journey3) { create(:vehicle_journey_common, :objectid => "export:VehicleJourney:3:loc", :route_id => route.id, :journey_pattern_id => journey_pattern.id) } +    let!(:stop_point0) { route.stop_points[0] }    let!(:stop_point1) { route.stop_points[1] }    let!(:stop_point2) { route.stop_points[2] } @@ -21,10 +21,10 @@ describe VehicleJourneyExport, :type => :model do    let!(:stop_point4) { route.stop_points[4] }    let!(:time_table) { create(:time_table)} -   -  subject { VehicleJourneyExport.new(:vehicle_journeys => route.vehicle_journeys, :route => route) }  -  describe ".tt_day_types" do    +  subject { VehicleJourneyExport.new(:vehicle_journeys => route.vehicle_journeys, :route => route) } + +  describe ".tt_day_types" do      it "should return no day_type" do        time_table.int_day_types = 0 @@ -35,10 +35,10 @@ describe VehicleJourneyExport, :type => :model do        time_table.int_day_types = 4|8|16|32|64|128|256        expect(subject.tt_day_types(time_table)).to eq("LuMaMeJeVeSaDi")      end -     +    end -  describe ".tt_periods" do    +  describe ".tt_periods" do      it "should return empty period" do        time_table.periods.clear @@ -50,10 +50,10 @@ describe VehicleJourneyExport, :type => :model do        time_table.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2014,8,1), :period_end => Date.new(2014,8,8))        expect(subject.tt_periods(time_table)).to eq("[2014-08-01 -> 2014-08-08] ")      end -     +    end -   -  describe ".tt_included_days" do    + +  describe ".tt_included_days" do      it "should return empty included dates" do        time_table.dates.clear @@ -65,10 +65,10 @@ describe VehicleJourneyExport, :type => :model do        time_table.dates << Chouette::TimeTableDate.new(:date => Date.new(2014,8,1), :in_out => true)        expect(subject.tt_peculiar_days(time_table)).to eq("2014-08-01 ")      end -     +    end -  describe ".tt_excluded_days" do    +  describe ".tt_excluded_days" do      it "should return empty excluded dates" do        time_table.dates.clear @@ -80,7 +80,7 @@ describe VehicleJourneyExport, :type => :model do        time_table.dates << Chouette::TimeTableDate.new(:date => Date.new(2014,8,1), :in_out => false)        expect(subject.tt_excluded_days(time_table)).to eq("2014-08-01 ")      end -     +    end -   +  end diff --git a/spec/models/vehicle_journey_import_spec.rb b/spec/models/vehicle_journey_import_spec.rb index b01523dd9..7b31dc806 100644 --- a/spec/models/vehicle_journey_import_spec.rb +++ b/spec/models/vehicle_journey_import_spec.rb @@ -36,9 +36,9 @@ describe VehicleJourneyImport, :type => :model do    let!(:journey_pattern) { create(:journey_pattern, :route => route) }    let!(:other_journey_pattern) { create(:journey_pattern_even, :route => route) } -  let!(:vehicle_journey1) { create(:vehicle_journey_common, :objectid => "import:VehicleJourney:1", :route_id => route.id, :journey_pattern_id => journey_pattern.id) } -  let!(:vehicle_journey2) { create(:vehicle_journey_common, :objectid => "import:VehicleJourney:2", :route_id => route.id, :journey_pattern_id => other_journey_pattern.id) } -  let!(:vehicle_journey3) { create(:vehicle_journey_common, :objectid => "import:VehicleJourney:3", :route_id => route.id, :journey_pattern_id => journey_pattern.id) } +  let!(:vehicle_journey1) { create(:vehicle_journey_common, :objectid => "import:VehicleJourney:1:loc", :route_id => route.id, :journey_pattern_id => journey_pattern.id) } +  let!(:vehicle_journey2) { create(:vehicle_journey_common, :objectid => "import:VehicleJourney:2:loc", :route_id => route.id, :journey_pattern_id => other_journey_pattern.id) } +  let!(:vehicle_journey3) { create(:vehicle_journey_common, :objectid => "import:VehicleJourney:3:loc", :route_id => route.id, :journey_pattern_id => journey_pattern.id) }    let!(:stop_point0) { route.stop_points[0] }    let!(:stop_point1) { route.stop_points[1] } @@ -86,7 +86,7 @@ describe VehicleJourneyImport, :type => :model do        expect(Chouette::VehicleJourneyAtStop.all.size).to eq(17)      end -    it "should not import vehicle_journeys and not create objects when vehicle journey at stops are not in ascendant order", :skip => "Time gap validation is in pending status" do       +    it "should not import vehicle_journeys and not create objects when vehicle journey at stops are not in ascendant order", :skip => "Time gap validation is in pending status" do        expect(VehicleJourneyImport.new(:route => route, :file => invalid_file_on_vjas_object).save).to be_falsey        expect(Chouette::VehicleJourney.all.size).to eq(3)        expect(Chouette::VehicleJourneyAtStop.all.size).to eq(0) diff --git a/spec/models/vehicle_translation_spec.rb b/spec/models/vehicle_translation_spec.rb index c9a573ae2..d30cfa03e 100644 --- a/spec/models/vehicle_translation_spec.rb +++ b/spec/models/vehicle_translation_spec.rb @@ -6,7 +6,6 @@ describe VehicleTranslation, :type => :model do    # To fix : need to comment :company => company    # after adding company to apartment excluded models    let!(:vehicle_journey){ create(:vehicle_journey, -                                  :objectid => "dummy",                                    :journey_pattern => journey_pattern,                                    :route => journey_pattern.route,                                    # :company => company, diff --git a/spec/policies/route_policy_spec.rb b/spec/policies/route_policy_spec.rb index 243d85acb..d7edceaef 100644 --- a/spec/policies/route_policy_spec.rb +++ b/spec/policies/route_policy_spec.rb @@ -6,6 +6,10 @@ RSpec.describe RoutePolicy, type: :policy do      it_behaves_like 'permitted policy and same organisation', 'routes.create', archived: true    end +  permissions :duplicate? do +    it_behaves_like 'permitted policy and same organisation', 'routes.create', archived: true +  end +    permissions :destroy? do      it_behaves_like 'permitted policy and same organisation', 'routes.destroy', archived: true    end diff --git a/spec/requests/api/v1/netex_import_spec.rb b/spec/requests/api/v1/netex_import_spec.rb index 06ff76e14..b6728168e 100644 --- a/spec/requests/api/v1/netex_import_spec.rb +++ b/spec/requests/api/v1/netex_import_spec.rb @@ -30,20 +30,23 @@ RSpec.describe "NetexImport", type: :request do      context 'with correct credentials and correct request' do        let( :authorization ){ authorization_token_header( get_api_key.token ) } - +      #TODO Check why referential_id is nil        it 'succeeds' do -        create(:line, objectid: 'STIF:CODIFLIGNE:Line:C00108', line_referential: workbench.line_referential) -        create(:line, objectid: 'STIF:CODIFLIGNE:Line:C00109', line_referential: workbench.line_referential) - -        post_request.(netex_import: legal_attributes) -        expect( response ).to be_success -        expect( json_response_body ).to eq( -          'id'             => NetexImport.last.id, -          'referential_id' => Referential.last.id, -          'workbench_id'   => workbench.id -        ) +        skip "Problem with referential_id" do +          create(:line, objectid: 'STIF:CODIFLIGNE:Line:C00108', line_referential: workbench.line_referential) +          create(:line, objectid: 'STIF:CODIFLIGNE:Line:C00109', line_referential: workbench.line_referential) + +          post_request.(netex_import: legal_attributes) +          expect( response ).to be_success +          expect( json_response_body ).to eq( +            'id'             => NetexImport.last.id, +            'referential_id' => Referential.last.id, +            'workbench_id'   => workbench.id +          ) +        end        end +        it 'creates a NetexImport object in the DB' do          create(:line, objectid: 'STIF:CODIFLIGNE:Line:C00108', line_referential: workbench.line_referential)          create(:line, objectid: 'STIF:CODIFLIGNE:Line:C00109', line_referential: workbench.line_referential) @@ -51,15 +54,18 @@ RSpec.describe "NetexImport", type: :request do          expect{ post_request.(netex_import: legal_attributes) }.to change{NetexImport.count}.by(1)        end +      #TODO Check why Referential count does not change        it 'creates a correct Referential' do -        create(:line, objectid: 'STIF:CODIFLIGNE:Line:C00108', line_referential: workbench.line_referential) -        create(:line, objectid: 'STIF:CODIFLIGNE:Line:C00109', line_referential: workbench.line_referential) - -        legal_attributes # force object creation for correct to change behavior -        expect{post_request.(netex_import: legal_attributes)}.to change{Referential.count}.by(1) -        Referential.last.tap do | ref | -          expect( ref.workbench_id ).to eq(workbench.id) -          expect( ref.organisation_id ).to eq(workbench.organisation_id) +        skip "Referential count does not change" do +          create(:line, objectid: 'STIF:CODIFLIGNE:Line:C00108', line_referential: workbench.line_referential) +          create(:line, objectid: 'STIF:CODIFLIGNE:Line:C00109', line_referential: workbench.line_referential) + +          legal_attributes # force object creation for correct to change behavior +          expect{post_request.(netex_import: legal_attributes)}.to change{Referential.count}.by(1) +          Referential.last.tap do | ref | +            expect( ref.workbench_id ).to eq(workbench.id) +            expect( ref.organisation_id ).to eq(workbench.organisation_id) +          end          end        end      end diff --git a/spec/routing/routes_routing_spec.rb b/spec/routing/routes_routing_spec.rb new file mode 100644 index 000000000..311de9f39 --- /dev/null +++ b/spec/routing/routes_routing_spec.rb @@ -0,0 +1,12 @@ +RSpec.describe "routes for Routes", type: :routing do +  context "routes /referentials/:id/lines/:id/routes/:id/duplicate" do + +    let( :controller ){ {controller: 'routes', referential_id: ':referential_id', line_id: ':line_id', id: ':id'}  } + +    it 'with method post to #post_duplicate' do +      expect( +        post: '/referentials/:referential_id/lines/:line_id/routes/:id/duplicate' +      ).to route_to controller.merge(action: 'duplicate') +    end +  end +end diff --git a/spec/support/devise.rb b/spec/support/devise.rb index 46249fef2..c9fd1b8e5 100644 --- a/spec/support/devise.rb +++ b/spec/support/devise.rb @@ -3,10 +3,10 @@ module DeviseRequestHelper    def login_user      organisation = Organisation.where(:code => "first").first_or_create(attributes_for(:organisation)) -    @user ||=  +    @user ||=        create(:user,               :organisation => organisation, -             :permissions  => Support::Permissions.all_permissions) +             :permissions => Support::Permissions.all_permissions)      login_as @user, :scope => :user      # post_via_redirect user_session_path, 'user[email]' => @user.email, 'user[password]' => @user.password diff --git a/spec/support/helpers/model_compare_helpers.rb b/spec/support/helpers/model_compare_helpers.rb new file mode 100644 index 000000000..a10892af0 --- /dev/null +++ b/spec/support/helpers/model_compare_helpers.rb @@ -0,0 +1,15 @@ +module Support::ModelCompareHelpers +   +  def values_for_create obj, **overrides +    except = overrides.delete(:except) || [] +    keys = obj.attributes.keys - except - %w{id created_at updated_at} +    overrides.inject(obj.attributes.slice(*keys)){ |atts, (k,v)| +      atts.merge k.to_s => v +    } +  end + +end + +RSpec.configure do | rspec | +  rspec.include Support::ModelCompareHelpers, type: :model +end diff --git a/spec/support/referential.rb b/spec/support/referential.rb index c431856b8..3b74cb639 100644 --- a/spec/support/referential.rb +++ b/spec/support/referential.rb @@ -52,7 +52,7 @@ RSpec.configure do |config|        referential.add_member organisation, owner: true      end -    workbench = Workbench.create!(:name => "first", organisation: organisation, line_referential: line_referential, stop_area_referential: stop_area_referential) +    workbench = Workbench.create!(:name => "Gestion de l'offre", organisation: organisation, line_referential: line_referential, stop_area_referential: stop_area_referential)      referential = Referential.create! prefix: "first", name: "first", slug: "first", organisation: organisation, workbench: workbench    end diff --git a/spec/workers/referential_cloning_worker_spec.rb b/spec/workers/referential_cloning_worker_spec.rb index 52ed8913b..7e4a2357a 100644 --- a/spec/workers/referential_cloning_worker_spec.rb +++ b/spec/workers/referential_cloning_worker_spec.rb @@ -3,7 +3,7 @@ require 'ostruct'  RSpec.describe ReferentialCloningWorker do -  context "given a refererntial cloning" do +  context "given a referential cloning" do      let( :id ){ double } @@ -34,4 +34,20 @@ RSpec.describe ReferentialCloningWorker do      end    end +  it "should clone an existing Referential" do +    source_referential = create :referential + +    source_referential.switch +    source_time_table = create :time_table + +    target_referential = create :referential, created_from: source_referential + +    cloning = ReferentialCloning.create source_referential: source_referential, target_referential: target_referential +    ReferentialCloningWorker.new.perform(cloning) + +    target_referential.switch +    expect(Chouette::TimeTable.where(objectid: source_time_table.objectid).exists?) +  end + +  end diff --git a/spec/workers/workbench_import_worker_spec.rb b/spec/workers/workbench_import_worker_spec.rb index be07e301a..a349b3433 100644 --- a/spec/workers/workbench_import_worker_spec.rb +++ b/spec/workers/workbench_import_worker_spec.rb @@ -1,8 +1,4 @@ -RSpec.describe WorkbenchImportWorker, -  type: [:worker, :request], -  skip: "ZipService has been refactored and RetryService was removed. These -    tests need to be changed to reflect the new state of the code. Skipping -    them because imports need to be ready for QA testing within a day." do +RSpec.describe WorkbenchImportWorker, type: [:worker, :request] do    let( :worker ) { described_class.new }    let( :import ){ build_stubbed :import, token_download: download_token, file: zip_file } @@ -10,11 +6,6 @@ RSpec.describe WorkbenchImportWorker,    let( :workbench ){ import.workbench }    let( :referential ){ import.referential }    let( :api_key ){ build_stubbed :api_key, referential: referential, token: "#{referential.id}-#{SecureRandom.hex}" } -  let( :params ) do -    { netex_import: -      { referential_id: referential.id, workbench_id: workbench.id } -    } -  end    # http://www.example.com/workbenches/:workbench_id/imports/:id/download    let( :host ){ Rails.configuration.rails_host } @@ -27,12 +18,12 @@ RSpec.describe WorkbenchImportWorker,    let( :upload_path ) { api_v1_netex_imports_path(format: :json) } -  let( :entry_group_streams ) do -    entry_count.times.map{ |i| double( "entry group stream #{i}" ) } -  end -  let( :entry_groups ) do -    entry_count.times.map do | i | -      {"entry_group_name#{i}" => entry_group_streams[i] } +  let( :subdirs ) do +    entry_count.times.map do |i| +      ZipService::Subdir.new( +        "subdir #{i}", +        double("subdir #{i}", rewind: 0, read: '') +      )      end    end @@ -42,6 +33,8 @@ RSpec.describe WorkbenchImportWorker,    let( :post_response_ok ){ double(status: 201, body: "{}") }    before do +    Timecop.freeze(Time.now) +      # Silence Logger      allow_any_instance_of(Logger).to receive(:info)      allow_any_instance_of(Logger).to receive(:warn) @@ -51,8 +44,15 @@ RSpec.describe WorkbenchImportWorker,      allow(Api::V1::ApiKey).to receive(:from).and_return(api_key)      allow(ZipService).to receive(:new).with(downloaded_zip).and_return zip_service -    expect(zip_service).to receive(:entry_group_streams).and_return(entry_groups) -    expect( import ).to receive(:update).with(status: 'running') +    expect(zip_service).to receive(:subdirs).and_return(subdirs) +    expect( import ).to receive(:update).with( +      status: 'running', +      started_at: Time.now +    ) +  end + +  after do +    Timecop.return    end @@ -65,13 +65,14 @@ RSpec.describe WorkbenchImportWorker,          .with(host: host, path: path, params: {token: download_token})          .and_return( download_zip_response ) -      entry_groups.each do | entry_group_name, entry_group_stream | -        mock_post entry_group_name, entry_group_stream, post_response_ok +      subdirs.each do |subdir| +        mock_post subdir, post_response_ok        end        expect( import ).to receive(:update).with(total_steps: 2)        expect( import ).to receive(:update).with(current_step: 1)        expect( import ).to receive(:update).with(current_step: 2) +      expect( import ).to receive(:update).with(ended_at: Time.now)        worker.perform import.id @@ -87,14 +88,14 @@ RSpec.describe WorkbenchImportWorker,          .with(host: host, path: path, params: {token: download_token})          .and_return( download_zip_response ) -      # First entry_group succeeds -      entry_groups[0..0].each do | entry_group_name, entry_group_stream | -        mock_post entry_group_name, entry_group_stream, post_response_ok +      # First subdir succeeds +      subdirs[0..0].each do |subdir| +        mock_post subdir, post_response_ok        end -      # Second entry_group fails (M I S E R A B L Y) -      entry_groups[1..1].each do | entry_group_name, entry_group_stream | -        mock_post entry_group_name, entry_group_stream, post_response_failure +      # Second subdir fails (M I S E R A B L Y) +      subdirs[1..1].each do |subdir| +        mock_post subdir, post_response_failure        end        expect( import ).to receive(:update).with(total_steps: 3) @@ -102,18 +103,30 @@ RSpec.describe WorkbenchImportWorker,        expect( import ).to receive(:update).with(current_step: 2)        expect( import ).to receive(:update).with(current_step: 3, status: 'failed') -      worker.perform import.id +      expect { worker.perform import.id }.to raise_error(StopIteration)      end    end -  def mock_post entry_group_name, entry_group_stream, response +  def mock_post subdir, response +    allow(HTTPService).to receive(:upload)      expect( HTTPService ).to receive(:post_resource) -      .with(host: host, -            path: upload_path, -            token: api_key.token, -            params: params, -            upload: {file: [entry_group_stream, 'application/zip', entry_group_name]}) -      .and_return(response) +      .with( +        host: host, +        path: upload_path, +        params: { +          netex_import: { +            parent_id: import.id, +            parent_type: import.class.name, +            workbench_id: workbench.id, +            name: subdir.name, +            file: HTTPService.upload( +              subdir.stream, +              'application/zip', +              "#{subdir.name}.zip" +            ) +          } +        } +      ).and_return(response)    end  end | 
