aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/assets/stylesheets/modules/_jp_collection.sass7
-rw-r--r--app/controllers/application_controller.rb5
-rw-r--r--app/controllers/journey_patterns_collections_controller.rb1
-rw-r--r--app/controllers/merges_controller.rb2
-rw-r--r--app/controllers/vehicle_journeys_controller.rb6
-rw-r--r--app/decorators/network_decorator.rb2
-rw-r--r--app/javascript/helpers/stop_area_header_manager.js9
-rw-r--r--app/javascript/journey_patterns/components/JourneyPattern.js65
-rw-r--r--app/javascript/packs/vehicle_journeys/index.js3
-rw-r--r--app/javascript/vehicle_journeys/components/tools/CreateModal.js9
-rw-r--r--app/javascript/vehicle_journeys/components/tools/CustomFieldsInputs.js50
-rw-r--r--app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js17
-rw-r--r--app/javascript/vehicle_journeys/containers/tools/AddVehicleJourney.js1
-rw-r--r--app/javascript/vehicle_journeys/reducers/custom_fields.js6
-rw-r--r--app/javascript/vehicle_journeys/reducers/index.js4
-rw-r--r--app/javascript/vehicle_journeys/reducers/vehicleJourneys.js5
-rw-r--r--app/models/chouette/stop_area.rb6
-rw-r--r--app/models/chouette/vehicle_journey.rb16
-rw-r--r--app/models/chouette/vehicle_journey_at_stop.rb30
-rw-r--r--app/models/merge.rb2
-rw-r--r--app/models/referential.rb12
-rw-r--r--app/models/workgroup.rb4
-rw-r--r--app/policies/referential_policy.rb4
-rw-r--r--app/views/autocomplete_stop_areas/around.rabl2
-rw-r--r--app/views/autocomplete_stop_areas/index.rabl2
-rw-r--r--app/views/networks/_form.html.slim10
-rw-r--r--app/views/networks/show.html.slim6
-rw-r--r--app/views/referentials/show.html.slim2
-rw-r--r--app/views/vehicle_journeys/index.html.slim1
-rw-r--r--app/views/vehicle_journeys/show.rabl10
-rw-r--r--app/views/workbenches/show.html.slim4
-rw-r--r--config/locales/area_types.en.yml1
-rw-r--r--config/locales/referentials.en.yml2
-rw-r--r--config/locales/referentials.fr.yml2
-rw-r--r--db/migrate/20180111200406_add_merged_at_to_referentials.rb5
-rw-r--r--db/schema.rb9
-rw-r--r--spec/decorators/referential_decorator_spec.rb1
-rw-r--r--spec/factories/chouette_vehicle_journey_at_stop.rb2
-rw-r--r--spec/helpers/table_builder_helper_spec.rb4
-rw-r--r--spec/javascript/vehicle_journeys/components/CustomFieldsInputs_spec.js42
-rw-r--r--spec/javascript/vehicle_journeys/components/__snapshots__/CustomFieldsInputs_spec.js.snap3
-rw-r--r--spec/javascript/vehicle_journeys/reducers/vehicleJourneys_spec.js24
-rw-r--r--spec/models/chouette/vehicle_journey_at_stop_spec.rb24
-rw-r--r--spec/models/chouette/vehicle_journey_spec.rb37
-rw-r--r--spec/models/custom_field_spec.rb11
-rw-r--r--spec/policies/referential_policy_spec.rb7
46 files changed, 404 insertions, 73 deletions
diff --git a/app/assets/stylesheets/modules/_jp_collection.sass b/app/assets/stylesheets/modules/_jp_collection.sass
index 9d68a217f..b4370a5ac 100644
--- a/app/assets/stylesheets/modules/_jp_collection.sass
+++ b/app/assets/stylesheets/modules/_jp_collection.sass
@@ -5,7 +5,6 @@
#journey_patterns
.table-2entries
.t2e-head
-
> .td
position: relative
padding-left: 25px
@@ -119,6 +118,12 @@
.td
padding: 15px 8px
+ .totals
+ color: $blue
+ padding-top: 4px
+ i
+ padding-right: 3px
+
$link-size: 10px
.link
position: absolute
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 474277da1..80d194096 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -41,6 +41,11 @@ class ApplicationController < ActionController::Base
end
helper_method :current_offer_workbench
+ def current_workgroup
+ current_offer_workbench.workgroup
+ end
+ helper_method :current_workgroup
+
def current_functional_scope
functional_scope = current_organisation.sso_attributes.try(:[], "functional_scope") if current_organisation
JSON.parse(functional_scope) if functional_scope
diff --git a/app/controllers/journey_patterns_collections_controller.rb b/app/controllers/journey_patterns_collections_controller.rb
index b37ac6cd0..da567779e 100644
--- a/app/controllers/journey_patterns_collections_controller.rb
+++ b/app/controllers/journey_patterns_collections_controller.rb
@@ -44,6 +44,7 @@ class JourneyPatternsCollectionsController < ChouetteController
:zip_code => sp.stop_area.try(:zip_code),
:city_name => sp.stop_area.try(:city_name),
:country_name => sp.stop_area.try(:country_name),
+ :time_zone_formatted_offset => sp.stop_area.try(:time_zone_formatted_offset),
:comment => sp.stop_area.try(:comment),
:area_type => sp.stop_area.try(:area_type),
:registration_number => sp.stop_area.try(:registration_number),
diff --git a/app/controllers/merges_controller.rb b/app/controllers/merges_controller.rb
index a95768139..1ce64ed58 100644
--- a/app/controllers/merges_controller.rb
+++ b/app/controllers/merges_controller.rb
@@ -11,7 +11,7 @@ class MergesController < ChouetteController
private
def set_mergeable_controllers
- @mergeable_referentials ||= parent.referentials.ready.not_in_referential_suite
+ @mergeable_referentials ||= parent.referentials.mergeable
Rails.logger.debug "Mergeables: #{@mergeable_referentials.inspect}"
end
diff --git a/app/controllers/vehicle_journeys_controller.rb b/app/controllers/vehicle_journeys_controller.rb
index e3e067782..eb3367d0c 100644
--- a/app/controllers/vehicle_journeys_controller.rb
+++ b/app/controllers/vehicle_journeys_controller.rb
@@ -49,6 +49,7 @@ class VehicleJourneysController < ChouetteController
end
format.html do
load_missions
+ load_custom_fields
@stop_points_list = []
@stop_points_list = route.stop_points.includes(:stop_area).map do |sp|
{
@@ -59,6 +60,7 @@ class VehicleJourneysController < ChouetteController
:for_boarding => sp.try(:for_boarding),
:for_alighting => sp.try(:for_alighting),
:name => sp.stop_area.try(:name),
+ :time_zone_formatted_offset => sp.stop_area.try(:time_zone_formatted_offset),
:zip_code => sp.stop_area.try(:zip_code),
:city_name => sp.stop_area.try(:city_name),
:comment => sp.stop_area.try(:comment),
@@ -176,6 +178,10 @@ class VehicleJourneysController < ChouetteController
end
private
+ def load_custom_fields
+ @custom_fields = current_workgroup.custom_fields_definitions
+ end
+
def load_missions
@all_missions = route.journey_patterns.count > 10 ? [] : route.journey_patterns.map do |item|
{
diff --git a/app/decorators/network_decorator.rb b/app/decorators/network_decorator.rb
index 1f62fe512..b0a19cf60 100644
--- a/app/decorators/network_decorator.rb
+++ b/app/decorators/network_decorator.rb
@@ -35,7 +35,7 @@ class NetworkDecorator < Draper::Decorator
object
),
method: :delete,
- data: { confirm: t('networks.actions.destroy_confirm') }
+ data: { confirm: h.t('networks.actions.destroy_confirm') }
)
end
diff --git a/app/javascript/helpers/stop_area_header_manager.js b/app/javascript/helpers/stop_area_header_manager.js
index 54d957be9..c9f397dee 100644
--- a/app/javascript/helpers/stop_area_header_manager.js
+++ b/app/javascript/helpers/stop_area_header_manager.js
@@ -21,7 +21,14 @@ export default class StopAreaHeaderManager {
data-headline={showHeadline}
title={sp.city_name + ' (' + sp.zip_code +')'}
>
- <span><span>{sp.name}</span></span>
+ <span>
+ <span>
+ {sp.name}
+ {sp.time_zone_formatted_offset && <span className="small">
+ &nbsp;({sp.time_zone_formatted_offset})
+ </span>}
+ </span>
+ </span>
</div>
)
}
diff --git a/app/javascript/journey_patterns/components/JourneyPattern.js b/app/javascript/journey_patterns/components/JourneyPattern.js
index 8dc542bc8..ecbebe2cc 100644
--- a/app/javascript/journey_patterns/components/JourneyPattern.js
+++ b/app/javascript/journey_patterns/components/JourneyPattern.js
@@ -74,18 +74,60 @@ export default class JourneyPattern extends Component{
return !this.props.status.policy[`journey_patterns.${action}`]
}
+ totals(){
+ let totalTime = 0
+ let totalDistance = 0
+ let from = null
+ this.props.value.stop_points.map((stopPoint, i) =>{
+ if(from && stopPoint.checked){
+ let [costsKey, costs, time, distance] = this.getTimeAndDistanceBetweenStops(from, stopPoint.id)
+ totalTime += time
+ totalDistance += distance
+ }
+ if(stopPoint.checked){
+ from = stopPoint.id
+ }
+ })
+ return [this.formatTime(totalTime), this.formatDistance(totalDistance)]
+ }
+
+ getTimeAndDistanceBetweenStops(from, to){
+ let costsKey = from + "-" + to
+ let costs = this.props.value.costs[costsKey] || {distance: 0, time: 0}
+ let time = costs['time'] || 0
+ let distance = costs['distance'] || 0
+ return [costsKey, costs, time, distance]
+ }
+
+ formatDistance(distance){
+ return parseFloat(Math.round(distance * 100) / 100).toFixed(2) + " km"
+ }
+
+ formatTime(time){
+ if(time < 60){
+ return time + " min"
+ }
+ else{
+ let hours = parseInt(time/60)
+ return hours + " h " + (time - 60*hours) + " min"
+ }
+ }
+
render() {
this.previousSpId = undefined
+ let [totalTime, totalDistance] = this.totals()
return (
<div className={'t2e-item' + (this.props.value.deletable ? ' disabled' : '') + (this.props.value.object_id ? '' : ' to_record') + (this.props.value.errors ? ' has-error': '') + (this.hasFeature('costs_in_journey_patterns') ? ' with-costs' : '')}>
- {/* Errors */}
- {/* this.props.value.errors ? this.getErrors(this.props.value.errors) : '' */}
-
<div className='th'>
<div className='strong mb-xs'>{this.props.value.object_id ? this.props.value.short_id : '-'}</div>
<div>{this.props.value.registration_number}</div>
<div>{actions.getChecked(this.props.value.stop_points).length} arrêt(s)</div>
-
+ {this.hasFeature('costs_in_journey_patterns') &&
+ <div className="small row totals">
+ <span className="col-md-6"><i className="fa fa-arrows-h"></i>{totalDistance}</span>
+ <span className="col-md-6"><i className="fa fa-clock-o"></i>{totalTime}</span>
+ </div>
+ }
<div className={this.props.value.deletable ? 'btn-group disabled' : 'btn-group'}>
<div
className={this.props.value.deletable ? 'btn dropdown-toggle disabled' : 'btn dropdown-toggle'}
@@ -132,17 +174,8 @@ export default class JourneyPattern extends Component{
let distance = null
let time_in_words = null
if(this.previousSpId && stopPoint.checked){
- costsKey = this.previousSpId + "-" + stopPoint.id
- costs = this.props.value.costs[costsKey] || {distance: 0, time: 0}
- time = costs['time'] || 0
- distance = costs['distance'] || 0
- if(time < 60){
- time_in_words = time + " min"
- }
- else{
- let hours = parseInt(time/60)
- time_in_words = hours + " h " + (time - 60*hours) + " min"
- }
+ [costsKey, costs, time, distance] = this.getTimeAndDistanceBetweenStops(this.previousSpId, stopPoint.id)
+ time_in_words = this.formatTime(time)
}
if(stopPoint.checked){
this.previousSpId = stopPoint.id
@@ -165,7 +198,7 @@ export default class JourneyPattern extends Component{
</p>
</div>}
{!this.props.editMode && <div>
- <p><i className="fa fa-arrows-h"></i>{(costs['distance'] || 0) + " km"}</p>
+ <p><i className="fa fa-arrows-h"></i>{this.formatDistance(costs['distance'] || 0)}</p>
<p><i className="fa fa-clock-o"></i>{time_in_words}</p>
</div>}
</div>}
diff --git a/app/javascript/packs/vehicle_journeys/index.js b/app/javascript/packs/vehicle_journeys/index.js
index ab28371fe..aa5738d59 100644
--- a/app/javascript/packs/vehicle_journeys/index.js
+++ b/app/javascript/packs/vehicle_journeys/index.js
@@ -71,7 +71,8 @@ var initialState = {
modalProps: {},
confirmModal: {}
},
- missions: window.all_missions
+ missions: window.all_missions,
+ custom_fields: window.custom_fields
}
if (window.jpOrigin){
diff --git a/app/javascript/vehicle_journeys/components/tools/CreateModal.js b/app/javascript/vehicle_journeys/components/tools/CreateModal.js
index 07c684760..90328458b 100644
--- a/app/javascript/vehicle_journeys/components/tools/CreateModal.js
+++ b/app/javascript/vehicle_journeys/components/tools/CreateModal.js
@@ -3,15 +3,17 @@ import PropTypes from 'prop-types'
import actions from '../../actions'
import MissionSelect2 from './select2s/MissionSelect2'
import CompanySelect2 from './select2s/CompanySelect2'
+import CustomFieldsInputs from './CustomFieldsInputs'
export default class CreateModal extends Component {
constructor(props) {
super(props)
+ this.custom_fields = _.assign({}, this.props.custom_fields)
}
handleSubmit() {
if (actions.validateFields(...this.refs, $('.vjCreateSelectJP')[0]) && this.props.modal.modalProps.selectedJPModal) {
- this.props.onAddVehicleJourney(this.refs, this.props.modal.modalProps.selectedJPModal, this.props.stopPointsList, this.props.modal.modalProps.vehicleJourney && this.props.modal.modalProps.vehicleJourney.company)
+ this.props.onAddVehicleJourney(_.assign({}, this.refs, {custom_fields: this.custom_fields}), this.props.modal.modalProps.selectedJPModal, this.props.stopPointsList, this.props.modal.modalProps.vehicleJourney && this.props.modal.modalProps.vehicleJourney.company)
this.props.onModalClose()
$('#NewVehicleJourneyModal').modal('hide')
}
@@ -89,6 +91,11 @@ export default class CreateModal extends Component {
/>
</div>
</div>
+ <CustomFieldsInputs
+ values={this.props.custom_fields}
+ onUpdate={(code, value) => this.custom_fields[code]["value"] = value}
+ disabled={false}
+ />
{ this.props.modal.modalProps.selectedJPModal && this.props.modal.modalProps.selectedJPModal.full_schedule && <div className='col-lg-6 col-md-6 col-sm-6 col-xs-12'>
<div className='form-group'>
<label className='control-label'>Heure de départ</label>
diff --git a/app/javascript/vehicle_journeys/components/tools/CustomFieldsInputs.js b/app/javascript/vehicle_journeys/components/tools/CustomFieldsInputs.js
new file mode 100644
index 000000000..90d72a801
--- /dev/null
+++ b/app/javascript/vehicle_journeys/components/tools/CustomFieldsInputs.js
@@ -0,0 +1,50 @@
+import _ from 'lodash'
+import Select2 from 'react-select2-wrapper'
+import React, { Component } from 'react'
+import PropTypes from 'prop-types'
+
+export default class CustomFieldsInputs extends Component {
+ constructor(props) {
+ super(props)
+ }
+
+ listInput(cf){
+ return(
+ <Select2
+ data={_.map(cf.options.list_values, (v, k) => {
+ return {id: k, text: (v.length > 0 ? v : '\u00A0')}
+ })}
+ ref={'custom_fields.' + cf.code}
+ className='form-control'
+ defaultValue={cf.value}
+ disabled={this.props.disabled}
+ options={{
+ theme: 'bootstrap',
+ width: '100%'
+ }}
+ onSelect={(e) => this.props.onUpdate(cf.code, e.params.data.id) }
+ />
+ )
+ }
+
+ render() {
+ return (
+ <div>
+ {_.map(this.props.values, (cf, code) =>
+ <div className='col-lg-6 col-md-6 col-sm-6 col-xs-12' key={code}>
+ <div className='form-group'>
+ <label className='control-label'>{cf.name}</label>
+ {this[cf.field_type + "Input"](cf)}
+ </div>
+ </div>
+ )}
+ </div>
+ )
+ }
+}
+
+CustomFieldsInputs.propTypes = {
+ onUpdate: PropTypes.func.isRequired,
+ values: PropTypes.object.isRequired,
+ disabled: PropTypes.bool.isRequired
+}
diff --git a/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js b/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js
index 08d74baba..2893422f8 100644
--- a/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js
+++ b/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js
@@ -2,6 +2,7 @@ import React, { Component } from 'react'
import PropTypes from 'prop-types'
import actions from '../../actions'
import CompanySelect2 from './select2s/CompanySelect2'
+import CustomFieldsInputs from './CustomFieldsInputs'
export default class EditVehicleJourney extends Component {
constructor(props) {
@@ -15,8 +16,8 @@ export default class EditVehicleJourney extends Component {
company = this.props.modal.modalProps.selectedCompany
} else if (typeof this.props.modal.modalProps.vehicleJourney.company === "object") {
company = this.props.modal.modalProps.vehicleJourney.company
- }
- this.props.onEditVehicleJourney(this.refs, company)
+ }
+ this.props.onEditVehicleJourney(_.assign({}, this.refs, {custom_fields: this.custom_fields}), company)
this.props.onModalClose()
$('#EditVehicleJourneyModal').modal('hide')
}
@@ -27,6 +28,9 @@ export default class EditVehicleJourney extends Component {
return false
}
if(this.props.status.fetchSuccess == true) {
+ if(this.props.modal.modalProps.vehicleJourney){
+ this.custom_fields = _.assign({}, this.props.modal.modalProps.vehicleJourney.custom_fields)
+ }
return (
<li className='st_action'>
<button
@@ -140,8 +144,15 @@ export default class EditVehicleJourney extends Component {
defaultValue={this.props.modal.modalProps.vehicleJourney.checksum}
/>
</div>
-
+ <div className='row'>
+ <CustomFieldsInputs
+ values={this.props.modal.modalProps.vehicleJourney.custom_fields}
+ onUpdate={(code, value) => this.custom_fields[code]["value"] = value}
+ disabled={!this.props.editMode}
+ />
+ </div>
</div>
+
{
this.props.editMode &&
<div className='modal-footer'>
diff --git a/app/javascript/vehicle_journeys/containers/tools/AddVehicleJourney.js b/app/javascript/vehicle_journeys/containers/tools/AddVehicleJourney.js
index 0f4a0ea7d..0db7628be 100644
--- a/app/javascript/vehicle_journeys/containers/tools/AddVehicleJourney.js
+++ b/app/javascript/vehicle_journeys/containers/tools/AddVehicleJourney.js
@@ -10,6 +10,7 @@ const mapStateToProps = (state, ownProps) => {
status: state.status,
stopPointsList: state.stopPointsList,
missions: state.missions,
+ custom_fields: state.custom_fields,
}
}
diff --git a/app/javascript/vehicle_journeys/reducers/custom_fields.js b/app/javascript/vehicle_journeys/reducers/custom_fields.js
new file mode 100644
index 000000000..482fd91cb
--- /dev/null
+++ b/app/javascript/vehicle_journeys/reducers/custom_fields.js
@@ -0,0 +1,6 @@
+export default function custom_fields(state = [], action) {
+ switch (action.type) {
+ default:
+ return state
+ }
+}
diff --git a/app/javascript/vehicle_journeys/reducers/index.js b/app/javascript/vehicle_journeys/reducers/index.js
index 862c864ae..1963f7c6d 100644
--- a/app/javascript/vehicle_journeys/reducers/index.js
+++ b/app/javascript/vehicle_journeys/reducers/index.js
@@ -7,6 +7,7 @@ import filters from './filters'
import editMode from './editMode'
import stopPointsList from './stopPointsList'
import missions from './missions'
+import custom_fields from './custom_fields'
const vehicleJourneysApp = combineReducers({
vehicleJourneys,
@@ -16,7 +17,8 @@ const vehicleJourneysApp = combineReducers({
filters,
editMode,
stopPointsList,
- missions
+ missions,
+ custom_fields
})
export default vehicleJourneysApp
diff --git a/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js b/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js
index 0549c7adc..62b846d9a 100644
--- a/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js
+++ b/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js
@@ -54,6 +54,7 @@ const vehicleJourney= (state = {}, action, keep) => {
pristineVjasList.push(newVjas)
})
+
return {
company: action.selectedCompany,
journey_pattern: action.selectedJourneyPattern,
@@ -68,7 +69,8 @@ const vehicleJourney= (state = {}, action, keep) => {
selected: false,
deletable: false,
transport_mode: window.transportMode ? window.transportMode : 'undefined',
- transport_submode: window.transportSubmode ? window.transportSubmode : 'undefined'
+ transport_submode: window.transportSubmode ? window.transportSubmode : 'undefined',
+ custom_fields: action.data.custom_fields
}
case 'DUPLICATE_VEHICLEJOURNEY':
case 'SHIFT_VEHICLEJOURNEY':
@@ -148,6 +150,7 @@ export default function vehicleJourneys(state = [], action) {
company: action.selectedCompany,
published_journey_name: action.data.published_journey_name.value,
published_journey_identifier: action.data.published_journey_identifier.value,
+ custom_fields: action.data.custom_fields,
})
}else{
return vj
diff --git a/app/models/chouette/stop_area.rb b/app/models/chouette/stop_area.rb
index 52602be9f..37d20ae02 100644
--- a/app/models/chouette/stop_area.rb
+++ b/app/models/chouette/stop_area.rb
@@ -358,11 +358,17 @@ module Chouette
update_attribute :deleted_at, Time.now
end
+
def country_name
return unless country_code
country = ISO3166::Country[country_code]
country.translations[I18n.locale.to_s] || country.name
end
+
+ def time_zone_formatted_offset
+ return nil unless time_zone.present?
+ ActiveSupport::TimeZone[time_zone]&.formatted_offset
+ end
end
end
diff --git a/app/models/chouette/vehicle_journey.rb b/app/models/chouette/vehicle_journey.rb
index 1904e1b92..8a704d8c0 100644
--- a/app/models/chouette/vehicle_journey.rb
+++ b/app/models/chouette/vehicle_journey.rb
@@ -132,10 +132,14 @@ module Chouette
def update_vjas_from_state state
state.each do |vjas|
next if vjas["dummy"]
+ stop_point = Chouette::StopPoint.find_by(objectid: vjas['stop_point_objectid'])
+ stop_area = stop_point&.stop_area
+ tz = stop_area&.time_zone
+ tz = tz && ActiveSupport::TimeZone[tz]
params = {}.tap do |el|
['arrival_time', 'departure_time'].each do |field|
time = "#{vjas[field]['hour']}:#{vjas[field]['minute']}"
- el[field.to_sym] = Time.parse("2000-01-01 #{time}:00 UTC")
+ el[field.to_sym] = Time.parse("2000-01-01 #{time}:00 #{tz&.formatted_offset || "UTC"}")
end
end
stop = create_or_find_vjas_from_state(vjas)
@@ -220,6 +224,7 @@ module Chouette
['company', 'journey_pattern'].map do |association|
attrs["#{association}_id"] = item[association]['id'] if item[association]
end
+ attrs["custom_field_values"] = Hash[*(item["custom_fields"] || {}).map{|k, v| [k, v["value"]]}.flatten]
attrs
end
@@ -258,8 +263,15 @@ module Chouette
end
end
+ def self.custom_fields
+ CustomField.where(resource_type: self.name.split("::").last)
+ end
+
+
def custom_fields
- CustomField.where(resource_type: self.class.name.split("::").last)
+ Hash[*self.class.custom_fields.map do |v|
+ [v.code, v.slice(:code, :name, :field_type, :options).update(value: custom_field_value(v.code))]
+ end.flatten]
end
def custom_field_value key
diff --git a/app/models/chouette/vehicle_journey_at_stop.rb b/app/models/chouette/vehicle_journey_at_stop.rb
index 6b3c1e7de..f1a3cdcaa 100644
--- a/app/models/chouette/vehicle_journey_at_stop.rb
+++ b/app/models/chouette/vehicle_journey_at_stop.rb
@@ -77,11 +77,37 @@ module Chouette
end
def departure
- departure_time.utc.strftime "%H:%M" if departure_time
+ format_time departure_time.utc
end
def arrival
- arrival_time.utc.strftime "%H:%M" if arrival_time
+ format_time arrival_time.utc
+ end
+
+ def departure_local_time
+ local_time departure_time
+ end
+
+ def arrival_local_time
+ local_time arrival_time
+ end
+
+ def departure_local
+ format_time departure_local_time
+ end
+
+ def arrival_local
+ format_time arrival_local_time
+ end
+
+ private
+ def local_time time
+ return time unless stop_point&.stop_area&.time_zone.present?
+ time + ActiveSupport::TimeZone[stop_point.stop_area.time_zone].utc_offset
+ end
+
+ def format_time time
+ time.strftime "%H:%M" if time
end
end
diff --git a/app/models/merge.rb b/app/models/merge.rb
index 26bd5398b..eebf1d2e1 100644
--- a/app/models/merge.rb
+++ b/app/models/merge.rb
@@ -360,6 +360,8 @@ class Merge < ActiveRecord::Base
def save_current
output.update current: new, new: nil
output.current.update referential_suite: output
+
+ referentials.update_all merged_at: created_at, archived_at: created_at
end
def fixme_functional_scope
diff --git a/app/models/referential.rb b/app/models/referential.rb
index 718f60ffd..92931564d 100644
--- a/app/models/referential.rb
+++ b/app/models/referential.rb
@@ -463,6 +463,18 @@ class Referential < ActiveRecord::Base
not metadatas_overlap?
end
+ def merged?
+ merged_at.present?
+ end
+
+ def self.not_merged
+ where merged_at: nil
+ end
+
+ def self.mergeable
+ ready.not_merged.not_in_referential_suite
+ end
+
private
def lock_table
diff --git a/app/models/workgroup.rb b/app/models/workgroup.rb
index 995917fac..511bbfeb0 100644
--- a/app/models/workgroup.rb
+++ b/app/models/workgroup.rb
@@ -11,4 +11,8 @@ class Workgroup < ActiveRecord::Base
validates_presence_of :stop_area_referential_id
has_many :custom_fields
+
+ def custom_fields_definitions
+ Hash[*custom_fields.map{|cf| [cf.code, cf]}.flatten]
+ end
end
diff --git a/app/policies/referential_policy.rb b/app/policies/referential_policy.rb
index af5c14880..f5c2d7c08 100644
--- a/app/policies/referential_policy.rb
+++ b/app/policies/referential_policy.rb
@@ -18,7 +18,7 @@ class ReferentialPolicy < ApplicationPolicy
end
def clone?
- !referential_read_only? && create?
+ !record.in_referential_suite? && create?
end
def validate?
@@ -30,7 +30,7 @@ class ReferentialPolicy < ApplicationPolicy
end
def unarchive?
- !record.archived_at.nil? && organisation_match? && user.has_permission?('referentials.update')
+ record.archived? && !record.merged? && organisation_match? && user.has_permission?('referentials.update')
end
def common_lines?
diff --git a/app/views/autocomplete_stop_areas/around.rabl b/app/views/autocomplete_stop_areas/around.rabl
index bc8f06054..d067dc4d0 100644
--- a/app/views/autocomplete_stop_areas/around.rabl
+++ b/app/views/autocomplete_stop_areas/around.rabl
@@ -12,7 +12,7 @@ child @stop_areas, root: :features, object_root: false do
name: s.name,
short_name: truncate(s.name, :length => 30) || "",
city_name: s.city_name,
- area_type: s.area_type,
+ area_type: Chouette::AreaType.find(s.area_type).label,
registration_number: s.registration_number,
stoparea_id: s.id,
text: "#{s.name}, #{s.zip_code} #{s.city_name}",
diff --git a/app/views/autocomplete_stop_areas/index.rabl b/app/views/autocomplete_stop_areas/index.rabl
index d20051ad5..c92b708f4 100644
--- a/app/views/autocomplete_stop_areas/index.rabl
+++ b/app/views/autocomplete_stop_areas/index.rabl
@@ -13,7 +13,7 @@ node do |stop_area|
:user_objectid => stop_area.user_objectid,
:longitude => stop_area.longitude,
:latitude => stop_area.latitude,
- :area_type => stop_area.area_type,
+ :area_type => Chouette::AreaType.find(stop_area.area_type).label,
:comment => stop_area.comment,
:text => stop_area.full_name
}
diff --git a/app/views/networks/_form.html.slim b/app/views/networks/_form.html.slim
index 362584f97..f91a112e8 100644
--- a/app/views/networks/_form.html.slim
+++ b/app/views/networks/_form.html.slim
@@ -4,11 +4,11 @@
= f.input :name, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@line_referential)}.network.name")}
= f.input :registration_number, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@line_referential)}.network.registration_number")}
= f.input :comment
- = f.input :version_date, :label_html => { :class => 'string optional col-sm-4 col-xs-5 control-label' }, :wrapper => :multi_select_inline
- = f.input :description
- = f.input :source_name
- = f.input :source_type_name, as: :select, :collection => Chouette::Network.source_type_name.options, :include_blank => true
- = f.input :source_identifier
+ / = f.input :version_date, :label_html => { :class => 'string optional col-sm-4 col-xs-5 control-label' }, :wrapper => :multi_select_inline
+ / = f.input :description
+ / = f.input :source_name
+ / = f.input :source_type_name, as: :select, :collection => Chouette::Network.source_type_name.options, :include_blank => true
+ / = f.input :source_identifier
.separator
= f.button :submit, t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'network_form'
diff --git a/app/views/networks/show.html.slim b/app/views/networks/show.html.slim
index f7d40a049..8e40a13b2 100644
--- a/app/views/networks/show.html.slim
+++ b/app/views/networks/show.html.slim
@@ -14,4 +14,8 @@
.row
.col-lg-6.col-md-6.col-sm-12.col-xs-12
= definition_list t('metadatas'),
- { 'ID Codif' => @network.try(:get_objectid).try(:short_id) }
+ { @network.human_attribute_name(:id) => @network.get_objectid.try(:short_id), \
+ @network.human_attribute_name(:name) => @network.name, \
+ @network.human_attribute_name(:registration_number) => @network.registration_number, \
+ @network.human_attribute_name(:comment) => (@network.comment.presence || '-'), \
+ }
diff --git a/app/views/referentials/show.html.slim b/app/views/referentials/show.html.slim
index 305d04f6b..cbb622c44 100644
--- a/app/views/referentials/show.html.slim
+++ b/app/views/referentials/show.html.slim
@@ -25,7 +25,7 @@
- attributes[@referential.human_attribute_name(:status)] = @referential.referential_read_only? ? "<div class='td-block'><span class='fa fa-archive'></span><span>#{t('activerecord.attributes.referential.archived_at')}</span></div>".html_safe : "<div class='td-block'><span class='sb sb-lg sb-preparing'></span><span>#{t('activerecord.attributes.referential.archived_at_null')}</span></div>".html_safe unless @referential.in_referential_suite?
- attributes[@referential.human_attribute_name(:validity_period)] = (@referential.validity_period.present? ? t('validity_range', debut: l(@referential.try(:validity_period).try(:begin), format: :short), end: l(@referential.try(:validity_period).try(:end), format: :short)) : '-')
- attributes[@referential.human_attribute_name(:organisation)] = @referential.organisation.name
- - attributes[@referential.human_attribute_name(:published_at)] = '-' unless @referential.in_referential_suite?
+ - attributes[@referential.human_attribute_name(:merged_at)] = @referential.merged_at ? l(@referential.merged_at, format: :short) : '-' unless @referential.in_referential_suite?
= definition_list t('metadatas'), attributes
- if params[:q].present? or @reflines.any?
diff --git a/app/views/vehicle_journeys/index.html.slim b/app/views/vehicle_journeys/index.html.slim
index 66e90d839..f7796b188 100644
--- a/app/views/vehicle_journeys/index.html.slim
+++ b/app/views/vehicle_journeys/index.html.slim
@@ -27,6 +27,7 @@
| window.perms = #{raw @perms};
| window.features = #{raw @features};
| window.all_missions = #{(@all_missions.to_json).html_safe};
+ | window.custom_fields = #{(@custom_fields.to_json).html_safe};
| window.I18n = #{(I18n.backend.send(:translations).to_json).html_safe};
= javascript_pack_tag 'vehicle_journeys/index.js'
diff --git a/app/views/vehicle_journeys/show.rabl b/app/views/vehicle_journeys/show.rabl
index eeed79b34..fc65e6cb6 100644
--- a/app/views/vehicle_journeys/show.rabl
+++ b/app/views/vehicle_journeys/show.rabl
@@ -1,6 +1,6 @@
object @vehicle_journey
-[:objectid, :published_journey_name, :published_journey_identifier, :company_id, :comment, :checksum].each do |attr|
+[:objectid, :published_journey_name, :published_journey_identifier, :company_id, :comment, :checksum, :custom_fields].each do |attr|
attributes attr, :unless => lambda { |m| m.send( attr).nil?}
end
@@ -59,11 +59,11 @@ child(:vehicle_journey_at_stops_matrix, :object_root => false) do |vehicle_stops
vehicle_stop.stop_point.stop_area.city_name
end
- [:arrival_time, :departure_time].each do |att|
- node(att) do |vs|
+ [:arrival, :departure].each do |att|
+ node("#{att}_time") do |vs|
{
- hour: vs.send(att).try(:strftime, '%H'),
- minute: vs.send(att).try(:strftime, '%M')
+ hour: vs.send("#{att}_local_time").try(:strftime, '%H'),
+ minute: vs.send("#{att}_local_time").try(:strftime, '%M')
}
end
end
diff --git a/app/views/workbenches/show.html.slim b/app/views/workbenches/show.html.slim
index 17ad75051..8907f3f08 100644
--- a/app/views/workbenches/show.html.slim
+++ b/app/views/workbenches/show.html.slim
@@ -54,8 +54,8 @@
attribute: Proc.new {|w| l(w.updated_at, format: :short)} \
), \
TableBuilderHelper::Column.new( \
- key: :published_at, \
- attribute: '' \
+ key: :merged_at, \
+ attribute: Proc.new {|w| w.merged_at ? l(w.merged_at, format: :short) : '-'} \
) \
],
selectable: ->(ref){ @workbench.referentials.include?(ref) },
diff --git a/config/locales/area_types.en.yml b/config/locales/area_types.en.yml
index 9f505c5e6..34ec3243d 100644
--- a/config/locales/area_types.en.yml
+++ b/config/locales/area_types.en.yml
@@ -6,4 +6,3 @@ en:
zdlp: ZDLp
zdlr: ZDLr
lda: LDA
-
diff --git a/config/locales/referentials.en.yml b/config/locales/referentials.en.yml
index f41e35446..eb8eae98d 100644
--- a/config/locales/referentials.en.yml
+++ b/config/locales/referentials.en.yml
@@ -91,7 +91,7 @@ en:
routing_constraint_zone: Routing constraint zone
validity_period: "Inclusive validity period"
updated_at: "Updated"
- published_at: "Integrated"
+ merged_at: "Finalized"
archived_at: "Archived"
archived_at_null: "Unarchived"
created_from: 'Created from'
diff --git a/config/locales/referentials.fr.yml b/config/locales/referentials.fr.yml
index 0f6e71520..37af8a4eb 100644
--- a/config/locales/referentials.fr.yml
+++ b/config/locales/referentials.fr.yml
@@ -92,7 +92,7 @@ fr:
validity_period: "Période de validité englobante"
updated_at: "Edité le"
created_at: "Créé le"
- published_at: "Intégré le"
+ merged_at: "Finalisé le"
archived_at: "Conservé"
archived_at_null: "En préparation"
created_from: 'Créé à partir de'
diff --git a/db/migrate/20180111200406_add_merged_at_to_referentials.rb b/db/migrate/20180111200406_add_merged_at_to_referentials.rb
new file mode 100644
index 000000000..27b11fa29
--- /dev/null
+++ b/db/migrate/20180111200406_add_merged_at_to_referentials.rb
@@ -0,0 +1,5 @@
+class AddMergedAtToReferentials < ActiveRecord::Migration
+ def change
+ add_column :referentials, :merged_at, :datetime
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index f55800c8b..f2cf6b4b6 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: 20180109180350) do
+ActiveRecord::Schema.define(version: 20180111200406) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -676,6 +676,7 @@ ActiveRecord::Schema.define(version: 20180109180350) do
t.boolean "ready", default: false
t.integer "referential_suite_id", limit: 8
t.string "objectid_format"
+ t.datetime "merged_at"
end
add_index "referentials", ["created_from_id"], name: "index_referentials_on_created_from_id", using: :btree
@@ -955,7 +956,7 @@ ActiveRecord::Schema.define(version: 20180109180350) do
t.integer "route_id", limit: 8
t.integer "journey_pattern_id", limit: 8
t.integer "company_id", limit: 8
- t.string "objectid", null: false
+ t.string "objectid", null: false
t.integer "object_version", limit: 8
t.string "comment"
t.string "status_value"
@@ -967,13 +968,13 @@ ActiveRecord::Schema.define(version: 20180109180350) do
t.integer "number", limit: 8
t.boolean "mobility_restricted_suitability"
t.boolean "flexible_service"
- t.integer "journey_category", default: 0, null: false
+ t.integer "journey_category", default: 0, null: false
t.datetime "created_at"
t.datetime "updated_at"
t.string "checksum"
t.text "checksum_source"
t.string "data_source_ref"
- t.jsonb "custom_field_values", default: {}
+ t.jsonb "custom_field_values"
end
add_index "vehicle_journeys", ["objectid"], name: "vehicle_journeys_objectid_key", unique: true, using: :btree
diff --git a/spec/decorators/referential_decorator_spec.rb b/spec/decorators/referential_decorator_spec.rb
index 879ab7d4b..9e34a0109 100644
--- a/spec/decorators/referential_decorator_spec.rb
+++ b/spec/decorators/referential_decorator_spec.rb
@@ -69,6 +69,7 @@ RSpec.describe ReferentialDecorator, type: [:helper, :decorator] do
expect_action_link_elements.to be_empty
expect_action_link_hrefs.to eq([
referential_time_tables_path(object),
+ new_referential_path(from: object)
])
end
end
diff --git a/spec/factories/chouette_vehicle_journey_at_stop.rb b/spec/factories/chouette_vehicle_journey_at_stop.rb
index 831e347d4..07a4ec557 100644
--- a/spec/factories/chouette_vehicle_journey_at_stop.rb
+++ b/spec/factories/chouette_vehicle_journey_at_stop.rb
@@ -1,9 +1,9 @@
FactoryGirl.define do
factory :vehicle_journey_at_stop, :class => Chouette::VehicleJourneyAtStop do
association :vehicle_journey, :factory => :vehicle_journey
+ association :stop_point, :factory => :stop_point
departure_day_offset { 0 }
departure_time { Time.now }
arrival_time { Time.now - 1.hour }
end
end
-
diff --git a/spec/helpers/table_builder_helper_spec.rb b/spec/helpers/table_builder_helper_spec.rb
index e82697b0a..8b383d88d 100644
--- a/spec/helpers/table_builder_helper_spec.rb
+++ b/spec/helpers/table_builder_helper_spec.rb
@@ -55,7 +55,7 @@ describe TableBuilderHelper, type: :helper do
<th><a href="/workbenches/#{workbench.id}?direction=desc&amp;sort=lines">Lignes<span class="orderers"><span class="fa fa-sort-asc active"></span><span class="fa fa-sort-desc "></span></span></a></th>
<th><a href="/workbenches/#{workbench.id}?direction=desc&amp;sort=created_at">Créé le<span class="orderers"><span class="fa fa-sort-asc active"></span><span class="fa fa-sort-desc "></span></span></a></th>
<th><a href="/workbenches/#{workbench.id}?direction=desc&amp;sort=updated_at">Edité le<span class="orderers"><span class="fa fa-sort-asc active"></span><span class="fa fa-sort-desc "></span></span></a></th>
- <th><a href="/workbenches/#{workbench.id}?direction=desc&amp;sort=published_at">Intégré le<span class="orderers"><span class="fa fa-sort-asc active"></span><span class="fa fa-sort-desc "></span></span></a></th>
+ <th><a href="/workbenches/#{workbench.id}?direction=desc&amp;sort=merged_at">Finalisé le<span class="orderers"><span class="fa fa-sort-asc active"></span><span class="fa fa-sort-desc "></span></span></a></th>
<th></th>
</tr>
</thead>
@@ -144,7 +144,7 @@ describe TableBuilderHelper, type: :helper do
attribute: Proc.new {|w| l(w.updated_at, format: :short)}
),
TableBuilderHelper::Column.new(
- key: :published_at,
+ key: :merged_at,
attribute: ''
)
],
diff --git a/spec/javascript/vehicle_journeys/components/CustomFieldsInputs_spec.js b/spec/javascript/vehicle_journeys/components/CustomFieldsInputs_spec.js
new file mode 100644
index 000000000..786b74cc7
--- /dev/null
+++ b/spec/javascript/vehicle_journeys/components/CustomFieldsInputs_spec.js
@@ -0,0 +1,42 @@
+import React, { Component } from 'react'
+import CustomFieldsInputs from '../../../../app/javascript/vehicle_journeys/components/tools/CustomFieldsInputs'
+import renderer from 'react-test-renderer'
+require('select2')
+console.log($().jquery)
+
+describe('CustomFieldsInputs', () => {
+ set('values', () => {
+ return {}
+ })
+
+ set('component', () => {
+ let inputs = renderer.create(
+ <CustomFieldsInputs
+ values={values}
+ disabled={false}
+ onUpdate={()=>{}}
+ />
+ ).toJSON()
+
+ return inputs
+ })
+
+ it('should match the snapshot', () => {
+ expect(component).toMatchSnapshot()
+ })
+
+ // context('with fields', () => {
+ // set('values', () => {
+ // return {
+ // foo: {
+ // options: { list_values: ["", "1", "2"] },
+ // field_type: "list",
+ // name: "test"
+ // }
+ // }
+ // })
+ // it('should match the snapshot', () => {
+ // expect(component).toMatchSnapshot()
+ // })
+ // })
+})
diff --git a/spec/javascript/vehicle_journeys/components/__snapshots__/CustomFieldsInputs_spec.js.snap b/spec/javascript/vehicle_journeys/components/__snapshots__/CustomFieldsInputs_spec.js.snap
new file mode 100644
index 000000000..c93ec0097
--- /dev/null
+++ b/spec/javascript/vehicle_journeys/components/__snapshots__/CustomFieldsInputs_spec.js.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`CustomFieldsInputs should match the snapshot 1`] = `<div />`;
diff --git a/spec/javascript/vehicle_journeys/reducers/vehicleJourneys_spec.js b/spec/javascript/vehicle_journeys/reducers/vehicleJourneys_spec.js
index 44e11aadf..044e95799 100644
--- a/spec/javascript/vehicle_journeys/reducers/vehicleJourneys_spec.js
+++ b/spec/javascript/vehicle_journeys/reducers/vehicleJourneys_spec.js
@@ -89,7 +89,12 @@ describe('vehicleJourneys reducer', () => {
}]
let fakeData = {
published_journey_name: {value: 'test'},
- published_journey_identifier: {value : ''}
+ published_journey_identifier: {value : ''},
+ custom_fields: {
+ foo: {
+ value: 12
+ }
+ }
}
let fakeSelectedJourneyPattern = {id: "1"}
let fakeSelectedCompany = {name: "ALBATRANS"}
@@ -115,7 +120,12 @@ describe('vehicleJourneys reducer', () => {
selected: false,
deletable: false,
transport_mode: 'undefined',
- transport_submode: 'undefined'
+ transport_submode: 'undefined',
+ custom_fields: {
+ foo: {
+ value: 12
+ }
+ }
}, ...state])
})
@@ -345,12 +355,18 @@ describe('vehicleJourneys reducer', () => {
})
it('should handle EDIT_VEHICLEJOURNEY', () => {
+ let custom_fields = {
+ foo: {
+ value: 12
+ }
+ }
let fakeData = {
published_journey_name: {value : 'test'},
- published_journey_identifier: {value: 'test'}
+ published_journey_identifier: {value: 'test'},
+ custom_fields: {foo: {value: 12}}
}
let fakeSelectedCompany : {name : 'ALBATRANS'}
- let newVJ = Object.assign({}, state[0], {company: fakeSelectedCompany, published_journey_name: fakeData.published_journey_name.value, published_journey_identifier: fakeData.published_journey_identifier.value})
+ let newVJ = Object.assign({}, state[0], {company: fakeSelectedCompany, published_journey_name: fakeData.published_journey_name.value, published_journey_identifier: fakeData.published_journey_identifier.value, custom_fields})
expect(
vjReducer(state, {
type: 'EDIT_VEHICLEJOURNEY',
diff --git a/spec/models/chouette/vehicle_journey_at_stop_spec.rb b/spec/models/chouette/vehicle_journey_at_stop_spec.rb
index df8a630fe..4d4a1794e 100644
--- a/spec/models/chouette/vehicle_journey_at_stop_spec.rb
+++ b/spec/models/chouette/vehicle_journey_at_stop_spec.rb
@@ -40,6 +40,30 @@ RSpec.describe Chouette::VehicleJourneyAtStop, type: :model do
end
end
+ context "the different times" do
+ let (:at_stop) { build_stubbed(:vehicle_journey_at_stop) }
+
+ describe "without a TimeZone" do
+ it "should not offset times" do
+ expect(at_stop.departure).to eq at_stop.departure_local
+ expect(at_stop.arrival).to eq at_stop.arrival_local
+ end
+ end
+
+
+ describe "with a TimeZone" do
+ before(:each) do
+ stop = at_stop.stop_point.stop_area
+ stop.time_zone = "Mexico City"
+ end
+
+ it "should offset times" do
+ expect(at_stop.departure_local).to eq at_stop.send(:format_time, at_stop.departure_time - 6.hours)
+ expect(at_stop.arrival_local).to eq at_stop.send(:format_time, at_stop.arrival_time - 6.hours)
+ end
+ end
+ end
+
describe "#validate" do
it "displays the proper error message when day offset exceeds the max" do
bad_offset = Chouette::VehicleJourneyAtStop::DAY_OFFSET_MAX + 1
diff --git a/spec/models/chouette/vehicle_journey_spec.rb b/spec/models/chouette/vehicle_journey_spec.rb
index 06cac6bc7..2a88ac3ce 100644
--- a/spec/models/chouette/vehicle_journey_spec.rb
+++ b/spec/models/chouette/vehicle_journey_spec.rb
@@ -64,10 +64,12 @@ describe Chouette::VehicleJourney, :type => :model do
at_stop[att.to_s] = vjas.send(att) unless vjas.send(att).nil?
end
- [:arrival_time, :departure_time].map do |att|
- at_stop[att.to_s] = {
- 'hour' => vjas.send(att).strftime('%H'),
- 'minute' => vjas.send(att).strftime('%M'),
+ at_stop["stop_point_objectid"] = vjas&.stop_point&.objectid
+
+ [:arrival, :departure].map do |att|
+ at_stop["#{att}_time"] = {
+ 'hour' => vjas.send("#{att}_local_time").strftime('%H'),
+ 'minute' => vjas.send("#{att}_local_time").strftime('%M'),
}
end
at_stop
@@ -80,6 +82,7 @@ describe Chouette::VehicleJourney, :type => :model do
item['purchase_windows'] = []
item['footnotes'] = []
item['purchase_windows'] = []
+ item['custom_fields'] = vj.custom_fields
vj.vehicle_journey_at_stops.each do |vjas|
item['vehicle_journey_at_stops'] << vehicle_journey_at_stop_to_state(vjas)
@@ -94,7 +97,8 @@ describe Chouette::VehicleJourney, :type => :model do
let(:collection) { [state] }
it 'should create new vj from state' do
- new_vj = build(:vehicle_journey, objectid: nil, published_journey_name: 'dummy', route: route, journey_pattern: journey_pattern)
+ create(:custom_field, code: :energy)
+ new_vj = build(:vehicle_journey, objectid: nil, published_journey_name: 'dummy', route: route, journey_pattern: journey_pattern, custom_field_values: {energy: 99})
collection << vehicle_journey_to_state(new_vj)
expect {
Chouette::VehicleJourney.state_update(route, collection)
@@ -110,6 +114,27 @@ describe Chouette::VehicleJourney, :type => :model do
expect(collection.last['objectid']).to eq obj.objectid
expect(obj.published_journey_name).to eq 'dummy'
+ expect(obj.custom_fields["energy"]["value"]).to eq 99
+ end
+
+ it 'should expect local times' do
+ new_vj = build(:vehicle_journey, objectid: nil, published_journey_name: 'dummy', route: route, journey_pattern: journey_pattern)
+ stop_area = create(:stop_area, time_zone: "Mexico City")
+ stop_point = create(:stop_point, stop_area: stop_area)
+ new_vj.vehicle_journey_at_stops << build(:vehicle_journey_at_stop, vehicle_journey: vehicle_journey, stop_point: stop_point)
+ data = vehicle_journey_to_state(new_vj)
+ data['vehicle_journey_at_stops'][0]["departure_time"]["hour"] = "15"
+ data['vehicle_journey_at_stops'][0]["arrival_time"]["hour"] = "12"
+ collection << data
+ expect {
+ Chouette::VehicleJourney.state_update(route, collection)
+ }.to change {Chouette::VehicleJourney.count}.by(1)
+ created = Chouette::VehicleJourney.last.vehicle_journey_at_stops.last
+ expect(created.stop_point).to eq stop_point
+ expect(created.departure_local_time.hour).to_not eq created.departure_time.hour
+ expect(created.arrival_local_time.hour).to_not eq created.arrival_time.hour
+ expect(created.departure_local_time.hour).to eq 15
+ expect(created.arrival_local_time.hour).to eq 12
end
it 'should save vehicle_journey_at_stops of newly created vj' do
@@ -209,11 +234,13 @@ describe Chouette::VehicleJourney, :type => :model do
it 'should update vj attributes from state' do
state['published_journey_name'] = 'edited_name'
state['published_journey_identifier'] = 'edited_identifier'
+ state['custom_fields'] = {energy: {value: 99}}
Chouette::VehicleJourney.state_update(route, collection)
expect(state['errors']).to be_nil
expect(vehicle_journey.reload.published_journey_name).to eq state['published_journey_name']
expect(vehicle_journey.reload.published_journey_identifier).to eq state['published_journey_identifier']
+ expect(vehicle_journey.reload.custom_field_value("energy")).to eq 99
end
it 'should return errors when validation failed' do
diff --git a/spec/models/custom_field_spec.rb b/spec/models/custom_field_spec.rb
index 80873683c..6ebf994db 100644
--- a/spec/models/custom_field_spec.rb
+++ b/spec/models/custom_field_spec.rb
@@ -17,8 +17,15 @@ RSpec.describe CustomField, type: :model do
context "custom fields for a resource" do
- let!( :fields ){ (1..2).map{ create :custom_field } }
- it { expect(vj.custom_fields).to eq(fields) }
+ let!( :fields ){ [create(:custom_field), create(:custom_field, code: :energy)] }
+ let!( :instance_fields ){
+ {
+ fields[0].code => fields[0].slice(:code, :name, :field_type, :options).update(value: nil),
+ "energy" => fields[1].slice(:code, :name, :field_type, :options).update(value: 99)
+ }
+ }
+ it { expect(Chouette::VehicleJourney.custom_fields).to eq(fields) }
+ it { expect(vj.custom_fields).to eq(instance_fields) }
end
context "custom field_values for a resource" do
diff --git a/spec/policies/referential_policy_spec.rb b/spec/policies/referential_policy_spec.rb
index 8540d3ce9..778e14901 100644
--- a/spec/policies/referential_policy_spec.rb
+++ b/spec/policies/referential_policy_spec.rb
@@ -1,3 +1,4 @@
+# coding: utf-8
RSpec.describe ReferentialPolicy, type: :policy do
let( :record ){ build_stubbed :referential }
@@ -45,9 +46,9 @@ RSpec.describe ReferentialPolicy, type: :policy do
# Custom Permissions
# ------------------
- permissions :clone? do
- it_behaves_like 'permitted policy', 'referentials.create', archived_and_finalised: true
- end
+ # permissions :clone? do
+ # it_behaves_like 'permitted policy', 'referentials.create', archived_and_finalised: true
+ # end
permissions :archive? do