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 |
