aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/assets/stylesheets/components/_main_nav.sass5
-rw-r--r--app/controllers/application_controller.rb9
-rw-r--r--app/controllers/chouette_controller.rb1
-rw-r--r--app/controllers/companies_controller.rb14
-rw-r--r--app/controllers/compliance_control_blocks_controller.rb13
-rw-r--r--app/controllers/concerns/metadata_controller_support.rb26
-rw-r--r--app/controllers/concerns/paper_trail_support.rb11
-rw-r--r--app/controllers/exports_controller.rb3
-rw-r--r--app/controllers/journey_patterns_collections_controller.rb1
-rw-r--r--app/controllers/referential_companies_controller.rb11
-rw-r--r--app/controllers/referentials_controller.rb2
-rw-r--r--app/controllers/routes_controller.rb3
-rw-r--r--app/controllers/stop_areas_controller.rb5
-rw-r--r--app/decorators/route_decorator.rb17
-rw-r--r--app/helpers/application_helper.rb12
-rw-r--r--app/helpers/compliance_controls_helper.rb4
-rw-r--r--app/helpers/stop_areas_helper.rb6
-rw-r--r--app/javascript/journey_patterns/actions/index.js2
-rw-r--r--app/javascript/journey_patterns/components/CreateModal.js4
-rw-r--r--app/javascript/journey_patterns/components/JourneyPattern.js2
-rw-r--r--app/javascript/journey_patterns/reducers/journeyPatterns.js2
-rw-r--r--app/javascript/time_tables/actions/index.js6
-rw-r--r--app/javascript/time_tables/components/ConfirmModal.js8
-rw-r--r--app/javascript/time_tables/components/ErrorModal.js8
-rw-r--r--app/javascript/time_tables/components/Metas.js8
-rw-r--r--app/javascript/time_tables/components/PeriodForm.js8
-rw-r--r--app/javascript/time_tables/components/PeriodManager.js8
-rw-r--r--app/javascript/time_tables/components/TagsSelect2.js6
-rw-r--r--app/javascript/time_tables/components/Timetable.js14
-rw-r--r--app/javascript/time_tables/containers/App.js1
-rw-r--r--app/javascript/vehicle_journeys/actions/index.js9
-rw-r--r--app/javascript/vehicle_journeys/components/Filters.js4
-rw-r--r--app/javascript/vehicle_journeys/components/tools/CustomFieldsInputs.js13
-rw-r--r--app/javascript/vehicle_journeys/components/tools/TimetablesEditVehicleJourney.js2
-rw-r--r--app/javascript/vehicle_journeys/components/tools/select2s/CompanySelect2.js2
-rw-r--r--app/javascript/vehicle_journeys/components/tools/select2s/MissionSelect2.js2
-rw-r--r--app/javascript/vehicle_journeys/components/tools/select2s/TimetableSelect2.js2
-rw-r--r--app/javascript/vehicle_journeys/components/tools/select2s/VJSelect2.js2
-rw-r--r--app/javascript/vehicle_journeys/components/tools/select2s/fr.js9
-rw-r--r--app/javascript/vehicle_journeys/components/tools/select2s/language.js9
-rw-r--r--app/models/api/v1/api_key.rb6
-rw-r--r--app/models/application_model.rb5
-rw-r--r--app/models/calendar.rb4
-rw-r--r--app/models/calendar/date_value.rb2
-rw-r--r--app/models/calendar/period.rb2
-rw-r--r--app/models/chouette/access_link.rb2
-rw-r--r--app/models/chouette/access_point.rb2
-rw-r--r--app/models/chouette/active_record.rb3
-rw-r--r--app/models/chouette/company.rb4
-rw-r--r--app/models/chouette/connection_link.rb2
-rw-r--r--app/models/chouette/for_alighting_enumerations.rb2
-rw-r--r--app/models/chouette/for_boarding_enumerations.rb2
-rw-r--r--app/models/chouette/group_of_line.rb2
-rw-r--r--app/models/chouette/journey_pattern.rb2
-rw-r--r--app/models/chouette/line.rb10
-rw-r--r--app/models/chouette/network.rb2
-rw-r--r--app/models/chouette/pt_link.rb2
-rw-r--r--app/models/chouette/purchase_window.rb2
-rw-r--r--app/models/chouette/route.rb28
-rw-r--r--app/models/chouette/routing_constraint_zone.rb2
-rw-r--r--app/models/chouette/stop_area.rb7
-rw-r--r--app/models/chouette/stop_point.rb5
-rw-r--r--app/models/chouette/time_table.rb2
-rw-r--r--app/models/chouette/timeband.rb2
-rw-r--r--app/models/chouette/vehicle_journey.rb29
-rw-r--r--app/models/clean_up.rb2
-rw-r--r--app/models/clean_up_result.rb2
-rw-r--r--app/models/compliance_check.rb2
-rw-r--r--app/models/compliance_check_block.rb2
-rw-r--r--app/models/compliance_check_message.rb2
-rw-r--r--app/models/compliance_check_resource.rb2
-rw-r--r--app/models/compliance_check_set.rb5
-rw-r--r--app/models/compliance_control.rb2
-rw-r--r--app/models/compliance_control_block.rb4
-rw-r--r--app/models/compliance_control_set.rb5
-rw-r--r--app/models/concerns/custom_fields_support.rb41
-rw-r--r--app/models/concerns/metadata_support.rb107
-rw-r--r--app/models/custom_field.rb204
-rw-r--r--app/models/export/base.rb20
-rw-r--r--app/models/export/message.rb2
-rw-r--r--app/models/export/resource.rb2
-rw-r--r--app/models/export/simple_exporter/base.rb4
-rw-r--r--app/models/import/base.rb2
-rw-r--r--app/models/import/message.rb2
-rw-r--r--app/models/import/resource.rb2
-rw-r--r--app/models/line_referential.rb6
-rw-r--r--app/models/line_referential_membership.rb4
-rw-r--r--app/models/line_referential_sync.rb2
-rw-r--r--app/models/line_referential_sync_message.rb2
-rw-r--r--app/models/merge.rb18
-rw-r--r--app/models/organisation.rb6
-rw-r--r--app/models/public_version.rb4
-rw-r--r--app/models/referential.rb6
-rw-r--r--app/models/referential_cloning.rb2
-rw-r--r--app/models/referential_metadata.rb6
-rw-r--r--app/models/referential_suite.rb2
-rw-r--r--app/models/simple_exporter.rb2
-rw-r--r--app/models/simple_interface.rb2
-rw-r--r--app/models/stop_area_referential.rb4
-rw-r--r--app/models/stop_area_referential_membership.rb4
-rw-r--r--app/models/stop_area_referential_sync.rb2
-rw-r--r--app/models/stop_area_referential_sync_message.rb2
-rw-r--r--app/models/user.rb2
-rw-r--r--app/models/workbench.rb2
-rw-r--r--app/models/workgroup.rb2
-rw-r--r--app/policies/route_policy.rb4
-rw-r--r--app/services/route_way_cost_calculator.rb2
-rw-r--r--app/uploaders/custom_field_attachment_uploader.rb12
-rw-r--r--app/views/autocomplete_purchase_windows/index.rabl13
-rw-r--r--app/views/calendars/show.html.slim7
-rw-r--r--app/views/companies/_form.html.slim4
-rw-r--r--app/views/companies/show.html.slim13
-rw-r--r--app/views/compliance_control_blocks/edit.html.slim1
-rw-r--r--app/views/compliance_control_blocks/new.html.slim2
-rw-r--r--app/views/lines/_filters.html.slim4
-rw-r--r--app/views/referential_companies/_form.html.slim37
-rw-r--r--app/views/referential_companies/edit.html.slim4
-rw-r--r--app/views/referential_companies/new.html.slim6
-rw-r--r--app/views/referential_companies/show.html.slim13
-rw-r--r--app/views/referential_lines/_filters.html.slim6
-rw-r--r--app/views/referential_vehicle_journeys/_filters.html.slim4
-rw-r--r--app/views/referentials/_form.html.slim2
-rw-r--r--app/views/referentials/select_compliance_control_set.html.slim4
-rw-r--r--app/views/routes/show.html.slim2
-rw-r--r--app/views/shared/custom_fields/_attachment.html.slim4
-rw-r--r--app/views/shared/iev_interfaces/_messages.html.slim2
-rw-r--r--app/views/stop_areas/_filters.html.slim4
-rw-r--r--app/views/stop_areas/_form.html.slim8
-rw-r--r--app/views/stop_areas/index.html.slim2
-rw-r--r--app/views/stop_areas/show.html.slim2
-rw-r--r--app/views/vehicle_journeys/index.html.slim3
-rw-r--r--app/views/workbench_outputs/show.html.slim3
-rw-r--r--app/views/workbenches/show.html.slim5
133 files changed, 780 insertions, 292 deletions
diff --git a/app/assets/stylesheets/components/_main_nav.sass b/app/assets/stylesheets/components/_main_nav.sass
index 8e164fa01..ef3f14762 100644
--- a/app/assets/stylesheets/components/_main_nav.sass
+++ b/app/assets/stylesheets/components/_main_nav.sass
@@ -346,6 +346,7 @@ $menuW: 300px
flex: 1 1
height: $menuH
position: relative
+ margin-right: 2em
h1
position: absolute
@@ -355,8 +356,8 @@ $menuW: 300px
line-height: 1.1
white-space: nowrap
max-height: 1.1em
- margin: 0 -1.4em 0 0
- padding: 0 1.4em 5px 0
+ margin: 0
+ padding: 0 0 5px 0
overflow: hidden
text-overflow: ellipsis
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index c4961123d..8b66e6097 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -1,5 +1,5 @@
class ApplicationController < ActionController::Base
- include PaperTrailSupport
+ include MetadataControllerSupport
include Pundit
include FeatureChecker
@@ -10,7 +10,6 @@ class ApplicationController < ActionController::Base
before_action :authenticate_user!
before_action :set_locale
-
# Load helpers in rails engine
helper LanguageEngine::Engine.helpers
@@ -36,12 +35,6 @@ class ApplicationController < ActionController::Base
end
helper_method :current_organisation
- def current_functional_scope
- functional_scope = current_organisation.sso_attributes.try(:[], "functional_scope") if current_organisation
- JSON.parse(functional_scope) if functional_scope
- end
- helper_method :current_functional_scope
-
def collection_name
self.class.name.split("::").last.gsub('Controller', '').underscore
end
diff --git a/app/controllers/chouette_controller.rb b/app/controllers/chouette_controller.rb
index 3e4f3af27..e6e7c0a8a 100644
--- a/app/controllers/chouette_controller.rb
+++ b/app/controllers/chouette_controller.rb
@@ -1,4 +1,3 @@
class ChouetteController < InheritedResources::Base
- include PaperTrailSupport
include ApplicationHelper
end
diff --git a/app/controllers/companies_controller.rb b/app/controllers/companies_controller.rb
index 4afd12be1..a09cab783 100644
--- a/app/controllers/companies_controller.rb
+++ b/app/controllers/companies_controller.rb
@@ -38,12 +38,14 @@ class CompaniesController < ChouetteController
protected
def collection
- @q = line_referential.companies.search(params[:q])
-
+ scope = line_referential.companies
+ @q = scope.search(params[:q])
+ ids = @q.result(:distinct => true).pluck(:id)
+ scope = scope.where(id: ids)
if sort_column && sort_direction
- @companies ||= @q.result(:distinct => true).order(sort_column + ' ' + sort_direction).paginate(:page => params[:page])
+ @companies ||= scope.order(sort_column + ' ' + sort_direction).paginate(:page => params[:page])
else
- @companies ||= @q.result(:distinct => true).order(:name).paginate(:page => params[:page])
+ @companies ||= scope.order(:name).paginate(:page => params[:page])
end
end
@@ -69,7 +71,9 @@ class CompaniesController < ChouetteController
end
def company_params
- params.require(:company).permit( :objectid, :object_version, :name, :short_name, :organizational_unit, :operating_department_name, :code, :phone, :fax, :email, :registration_number, :url, :time_zone )
+ fields = [:objectid, :object_version, :name, :short_name, :organizational_unit, :operating_department_name, :code, :phone, :fax, :email, :registration_number, :url, :time_zone]
+ fields += permitted_custom_fields_params(Chouette::Company.custom_fields(line_referential.workgroup))
+ params.require(:company).permit( fields )
end
private
diff --git a/app/controllers/compliance_control_blocks_controller.rb b/app/controllers/compliance_control_blocks_controller.rb
index 9eee8dfaf..1173a548a 100644
--- a/app/controllers/compliance_control_blocks_controller.rb
+++ b/app/controllers/compliance_control_blocks_controller.rb
@@ -4,10 +4,23 @@ class ComplianceControlBlocksController < ChouetteController
belongs_to :compliance_control_set
actions :all, :except => [:show, :index]
+ after_action :display_errors, only: [:create, :update]
+
+ def display_errors
+ unless @compliance_control_block.errors[:condition_attributes].empty?
+ flash[:error] = @compliance_control_block.errors[:condition_attributes].join(', ')
+ end
+ end
+
private
def compliance_control_block_params
params.require(:compliance_control_block).permit(:transport_mode, :transport_submode)
end
+ protected
+
+ alias_method :compliance_control_set, :parent
+ helper_method :compliance_control_set
+
end
diff --git a/app/controllers/concerns/metadata_controller_support.rb b/app/controllers/concerns/metadata_controller_support.rb
new file mode 100644
index 000000000..db83e79ae
--- /dev/null
+++ b/app/controllers/concerns/metadata_controller_support.rb
@@ -0,0 +1,26 @@
+module MetadataControllerSupport
+ extend ActiveSupport::Concern
+
+ included do
+ after_action :set_creator_metadata, only: :create
+ after_action :set_modifier_metadata, only: :update
+ end
+
+ def user_for_metadata
+ current_user ? current_user.username : ''
+ end
+
+ def set_creator_metadata
+ if resource.valid?
+ resource.try(:set_metadata!, :creator_username, user_for_metadata)
+ resource.try(:set_metadata!, :modifier_username, user_for_metadata)
+ end
+ end
+
+ def set_modifier_metadata
+ _resource = @resources || [resource]
+ _resource.flatten.each do |r|
+ r.try :set_metadata!, :modifier_username, user_for_metadata
+ end
+ end
+end
diff --git a/app/controllers/concerns/paper_trail_support.rb b/app/controllers/concerns/paper_trail_support.rb
deleted file mode 100644
index 4b0b1a7c7..000000000
--- a/app/controllers/concerns/paper_trail_support.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-module PaperTrailSupport
- extend ActiveSupport::Concern
-
- included do
- before_action :set_paper_trail_whodunnit
-
- def user_for_paper_trail
- current_user ? current_user.name : ''
- end
- end
-end
diff --git a/app/controllers/exports_controller.rb b/app/controllers/exports_controller.rb
index a5282a514..c89da5000 100644
--- a/app/controllers/exports_controller.rb
+++ b/app/controllers/exports_controller.rb
@@ -3,13 +3,14 @@ class ExportsController < ChouetteController
include RansackDateFilter
include IevInterfaces
skip_before_action :authenticate_user!, only: [:upload]
+ skip_before_action :verify_authenticity_token, only: [:upload]
defaults resource_class: Export::Base, collection_name: 'exports', instance_name: 'export'
def upload
if params[:token] == resource.token_upload
resource.file = params[:file]
resource.save!
- redirect_to [resource.workbench, resource]
+ render json: {status: :ok}
else
user_not_authorized
end
diff --git a/app/controllers/journey_patterns_collections_controller.rb b/app/controllers/journey_patterns_collections_controller.rb
index da567779e..db92d48f3 100644
--- a/app/controllers/journey_patterns_collections_controller.rb
+++ b/app/controllers/journey_patterns_collections_controller.rb
@@ -74,6 +74,7 @@ class JourneyPatternsCollectionsController < ChouetteController
def update
state = JSON.parse request.raw_post
Chouette::JourneyPattern.state_update route, state
+ @resources = route.journey_patterns
errors = state.any? {|item| item['errors']}
respond_to do |format|
diff --git a/app/controllers/referential_companies_controller.rb b/app/controllers/referential_companies_controller.rb
index 806a70c8f..200e56a89 100644
--- a/app/controllers/referential_companies_controller.rb
+++ b/app/controllers/referential_companies_controller.rb
@@ -40,11 +40,12 @@ class ReferentialCompaniesController < ChouetteController
end
@q = scope.search(params[:q])
-
+ ids = @q.result(:distinct => true).pluck(:id)
+ scope = scope.where(id: ids)
if sort_column && sort_direction
- @companies ||= @q.result(:distinct => true).order(sort_column + ' ' + sort_direction).paginate(:page => params[:page])
+ @companies ||= scope.order(sort_column + ' ' + sort_direction).paginate(:page => params[:page])
else
- @companies ||= @q.result(:distinct => true).order(:name).paginate(:page => params[:page])
+ @companies ||= scope.order(:name).paginate(:page => params[:page])
end
end
@@ -57,7 +58,9 @@ class ReferentialCompaniesController < ChouetteController
end
def company_params
- params.require(:company).permit( :objectid, :object_version, :name, :short_name, :organizational_unit, :operating_department_name, :code, :phone, :fax, :email, :registration_number, :url, :time_zone )
+ fields = [:objectid, :object_version, :name, :short_name, :organizational_unit, :operating_department_name, :code, :phone, :fax, :email, :registration_number, :url, :time_zone]
+ fields += permitted_custom_fields_params(Chouette::Company.custom_fields(@referential.workgroup))
+ params.require(:company).permit( fields )
end
private
diff --git a/app/controllers/referentials_controller.rb b/app/controllers/referentials_controller.rb
index 6e3694547..fe661651e 100644
--- a/app/controllers/referentials_controller.rb
+++ b/app/controllers/referentials_controller.rb
@@ -143,7 +143,7 @@ class ReferentialsController < ChouetteController
def build_referential
if params[:from]
source_referential = Referential.find(params[:from])
- @referential = Referential.new_from(source_referential, current_functional_scope)
+ @referential = Referential.new_from(source_referential, current_organisation)
end
@referential.data_format = current_organisation.data_format
diff --git a/app/controllers/routes_controller.rb b/app/controllers/routes_controller.rb
index 96a23c938..ac243c8eb 100644
--- a/app/controllers/routes_controller.rb
+++ b/app/controllers/routes_controller.rb
@@ -63,7 +63,8 @@ class RoutesController < ChouetteController
end
def duplicate
- route = Chouette::Route.find(params[:id]).duplicate
+ source = Chouette::Route.find(params[:id])
+ route = source.duplicate params[:opposite]
flash[:notice] = t('routes.duplicate.success')
redirect_to referential_line_path(@referential, route.line)
end
diff --git a/app/controllers/stop_areas_controller.rb b/app/controllers/stop_areas_controller.rb
index d0d9f652d..b2634467d 100644
--- a/app/controllers/stop_areas_controller.rb
+++ b/app/controllers/stop_areas_controller.rb
@@ -161,7 +161,7 @@ class StopAreasController < ChouetteController
helper_method :current_referential
def stop_area_params
- params.require(:stop_area).permit(
+ fields = [
:area_type,
:children_ids,
:city_name,
@@ -192,7 +192,8 @@ class StopAreasController < ChouetteController
:kind,
:status,
localized_names: Chouette::StopArea::AVAILABLE_LOCALIZATIONS
- )
+ ] + permitted_custom_fields_params(Chouette::StopArea.custom_fields) # XXX filter on the workgroup
+ params.require(:stop_area).permit(fields)
end
# Fake ransack filter
diff --git a/app/decorators/route_decorator.rb b/app/decorators/route_decorator.rb
index fa6367924..4a173cbb9 100644
--- a/app/decorators/route_decorator.rb
+++ b/app/decorators/route_decorator.rb
@@ -71,6 +71,23 @@ class RouteDecorator < AF83::Decorator
end
end
+ instance_decorator.action_link(
+ secondary: :show,
+ policy: :create_opposite,
+ if: ->{h.has_feature?(:create_opposite_routes) && object.opposite_route.nil?}
+ ) do |l|
+ l.content h.t('routes.create_opposite.title')
+ l.method :post
+ l.href do
+ h.duplicate_referential_line_route_path(
+ context[:referential],
+ context[:line],
+ object,
+ opposite: true
+ )
+ end
+ end
+
instance_decorator.destroy_action_link do |l|
l.data confirm: h.t('routes.actions.destroy_confirm')
end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 479b661c8..702ca0ffc 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -14,7 +14,7 @@ module ApplicationHelper
def page_header_title(object)
# Unwrap from decorator, we want to know the object model name
object = object.object if object.try(:object)
-
+
if Referential === object
return object.full_name
end
@@ -36,8 +36,8 @@ module ApplicationHelper
display = policy(object).synchronize? if policy(object).respond_to?(:synchronize?) rescue false
if display
info = t('last_update', time: l(object.updated_at, format: :short))
- if object.try(:versions)
- author = object.versions.try(:last).try(:whodunnit) || t('default_whodunnit')
+ if object.has_metadata?
+ author = object.metadata.modifier_username || t('default_whodunnit')
info = "#{info} <br/> #{t('whodunnit', author: author)}"
end
out += content_tag :div, info.html_safe, class: 'small last-update'
@@ -136,5 +136,9 @@ module ApplicationHelper
url_for(:controller => "/help", :action => "show") + '/' + target
end
-
+ def permitted_custom_fields_params custom_fields
+ [{
+ custom_field_values: custom_fields.map(&:code)
+ }]
+ end
end
diff --git a/app/helpers/compliance_controls_helper.rb b/app/helpers/compliance_controls_helper.rb
index 297ae3afa..abf909929 100644
--- a/app/helpers/compliance_controls_helper.rb
+++ b/app/helpers/compliance_controls_helper.rb
@@ -11,7 +11,7 @@ module ComplianceControlsHelper
def compliance_control_metadatas(compliance_control)
attributes = resource.class.dynamic_attributes
- attributes.push(*resource.control_attributes.keys) if resource.respond_to? :control_attributes
+ attributes.push(*resource.control_attributes.keys) if resource&.control_attributes&.keys
{}.tap do |hash|
attributes.each do |attribute|
@@ -19,4 +19,4 @@ module ComplianceControlsHelper
end
end
end
-end
+end
diff --git a/app/helpers/stop_areas_helper.rb b/app/helpers/stop_areas_helper.rb
index 1c9d974a1..032f68494 100644
--- a/app/helpers/stop_areas_helper.rb
+++ b/app/helpers/stop_areas_helper.rb
@@ -68,7 +68,11 @@ module StopAreasHelper
end
def stop_area_registration_number_value stop_area
- stop_area&.registration_number || stop_area&.stop_area_referential&.generate_registration_number
+ stop_area&.registration_number
+ end
+
+ def stop_area_registration_number_hint
+ t "formtastic.hints.stop_area.registration_number"
end
def stop_area_status(stop_area)
diff --git a/app/javascript/journey_patterns/actions/index.js b/app/javascript/journey_patterns/actions/index.js
index 666157ea4..ea54f4e05 100644
--- a/app/javascript/journey_patterns/actions/index.js
+++ b/app/javascript/journey_patterns/actions/index.js
@@ -43,7 +43,7 @@ const actions = {
}),
updateCheckboxValue : (e, index) => ({
type : 'UPDATE_CHECKBOX_VALUE',
- id : e.currentTarget.id,
+ position : e.currentTarget.id,
index
}),
checkConfirmModal : (event, callback, stateChanged,dispatch) => {
diff --git a/app/javascript/journey_patterns/components/CreateModal.js b/app/javascript/journey_patterns/components/CreateModal.js
index 36b5740dc..946c13d9c 100644
--- a/app/javascript/journey_patterns/components/CreateModal.js
+++ b/app/javascript/journey_patterns/components/CreateModal.js
@@ -57,7 +57,7 @@ export default class CreateModal extends Component {
<div className='row'>
<div className='col-lg-6 col-md-6 col-sm-6 col-xs-6'>
<div className='form-group'>
- <label className='control-label is-required'>{I18n.attribute_name('journey_pattern', 'published_name')}c</label>
+ <label className='control-label is-required'>{I18n.attribute_name('journey_pattern', 'published_name')}</label>
<input
type='text'
ref='published_name'
@@ -120,4 +120,4 @@ CreateModal.propTypes = {
onOpenCreateModal: PropTypes.func.isRequired,
onModalClose: PropTypes.func.isRequired,
onAddJourneyPattern: PropTypes.func.isRequired
-} \ No newline at end of file
+}
diff --git a/app/javascript/journey_patterns/components/JourneyPattern.js b/app/javascript/journey_patterns/components/JourneyPattern.js
index d381b0d50..4eba80030 100644
--- a/app/javascript/journey_patterns/components/JourneyPattern.js
+++ b/app/javascript/journey_patterns/components/JourneyPattern.js
@@ -45,7 +45,7 @@ export default class JourneyPattern extends Component{
<input
onChange = {(e) => this.props.onCheckboxChange(e)}
type='checkbox'
- id={sp.id}
+ id={sp.position}
checked={sp.checked}
disabled={(this.props.value.deletable || this.props.status.policy['journey_patterns.update'] == false || this.props.editMode == false) ? 'disabled' : ''}
>
diff --git a/app/javascript/journey_patterns/reducers/journeyPatterns.js b/app/javascript/journey_patterns/reducers/journeyPatterns.js
index 6c38e9288..b046f2b38 100644
--- a/app/javascript/journey_patterns/reducers/journeyPatterns.js
+++ b/app/javascript/journey_patterns/reducers/journeyPatterns.js
@@ -22,7 +22,7 @@ const journeyPattern = (state = {}, action) =>{
}
case 'UPDATE_CHECKBOX_VALUE':
var updatedStopPoints = state.stop_points.map((s) => {
- if (String(s.id) == action.id) {
+ if (String(s.position) == action.position) {
return _.assign({}, s, {checked : !s.checked})
}else {
return s
diff --git a/app/javascript/time_tables/actions/index.js b/app/javascript/time_tables/actions/index.js
index 98b9eab4b..7c79dfe52 100644
--- a/app/javascript/time_tables/actions/index.js
+++ b/app/javascript/time_tables/actions/index.js
@@ -4,7 +4,6 @@ import reject from 'lodash/reject'
import some from 'lodash/some'
import every from 'lodash/every'
import clone from '../../helpers/clone'
-const I18n = clone(window, "I18n")
const actions = {
weekDays: (index) => {
@@ -307,10 +306,11 @@ const actions = {
})
},
errorModalKey: (periods, dayTypes) => {
- const withoutPeriodsWithDaysTypes = reject(periods, 'deleted').length == 0 && some(dayTypes) && "withoutPeriodsWithDaysTypes"
+ // const withoutPeriodsWithDaysTypes = reject(periods, 'deleted').length == 0 && some(dayTypes) && "withoutPeriodsWithDaysTypes"
const withPeriodsWithoutDayTypes = reject(periods, 'deleted').length > 0 && every(dayTypes, dt => dt == false) && "withPeriodsWithoutDayTypes"
- return (withoutPeriodsWithDaysTypes || withPeriodsWithoutDayTypes) && (withoutPeriodsWithDaysTypes ? "withoutPeriodsWithDaysTypes" : "withPeriodsWithoutDayTypes")
+ // return (withoutPeriodsWithDaysTypes || withPeriodsWithoutDayTypes) && (withoutPeriodsWithDaysTypes ? "withoutPeriodsWithDaysTypes" : "withPeriodsWithoutDayTypes")
+ return withPeriodsWithoutDayTypes
},
errorModalMessage: (errorKey) => {
diff --git a/app/javascript/time_tables/components/ConfirmModal.js b/app/javascript/time_tables/components/ConfirmModal.js
index 4e8583bc0..e4219348d 100644
--- a/app/javascript/time_tables/components/ConfirmModal.js
+++ b/app/javascript/time_tables/components/ConfirmModal.js
@@ -2,7 +2,7 @@ import React from 'react'
import PropTypes from 'prop-types'
-export default function ConfirmModal({dispatch, modal, onModalAccept, onModalCancel, timetable, metas}, {I18n}) {
+export default function ConfirmModal({dispatch, modal, onModalAccept, onModalCancel, timetable, metas}) {
return (
<div className={'modal fade ' + ((modal.type == 'confirm') ? 'in' : '')} id='ConfirmModal'>
<div className='modal-container'>
@@ -45,8 +45,4 @@ ConfirmModal.propTypes = {
modal: PropTypes.object.isRequired,
onModalAccept: PropTypes.func.isRequired,
onModalCancel: PropTypes.func.isRequired
-}
-
-ConfirmModal.contextTypes = {
- I18n: PropTypes.object
-}
+} \ No newline at end of file
diff --git a/app/javascript/time_tables/components/ErrorModal.js b/app/javascript/time_tables/components/ErrorModal.js
index 8af12f1d1..a512d28fd 100644
--- a/app/javascript/time_tables/components/ErrorModal.js
+++ b/app/javascript/time_tables/components/ErrorModal.js
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
import actions from '../actions'
-export default function ErrorModal({dispatch, modal, onModalClose}, {I18n}) {
+export default function ErrorModal({dispatch, modal, onModalClose}) {
return (
<div className={'modal fade ' + ((modal.type == 'error') ? 'in' : '')} id='ErrorModal'>
<div className='modal-container'>
@@ -37,8 +37,4 @@ export default function ErrorModal({dispatch, modal, onModalClose}, {I18n}) {
ErrorModal.propTypes = {
modal: PropTypes.object.isRequired,
onModalClose: PropTypes.func.isRequired
-}
-
-ErrorModal.contextTypes = {
- I18n: PropTypes.object
-}
+} \ No newline at end of file
diff --git a/app/javascript/time_tables/components/Metas.js b/app/javascript/time_tables/components/Metas.js
index 08a6e26fe..d9746a379 100644
--- a/app/javascript/time_tables/components/Metas.js
+++ b/app/javascript/time_tables/components/Metas.js
@@ -4,7 +4,7 @@ import PropTypes from 'prop-types'
import actions from '../actions'
import TagsSelect2 from './TagsSelect2'
-export default function Metas({metas, onUpdateDayTypes, onUpdateComment, onUpdateColor, onSelect2Tags, onUnselect2Tags}, {I18n}) {
+export default function Metas({metas, onUpdateDayTypes, onUpdateComment, onUpdateColor, onSelect2Tags, onUnselect2Tags}) {
let colorList = ["", "#9B9B9B", "#FFA070", "#C67300", "#7F551B", "#41CCE3", "#09B09C", "#3655D7", "#6321A0", "#E796C6", "#DD2DAA"]
return (
<div className='form-horizontal'>
@@ -134,8 +134,4 @@ Metas.propTypes = {
onUpdateColor: PropTypes.func.isRequired,
onSelect2Tags: PropTypes.func.isRequired,
onUnselect2Tags: PropTypes.func.isRequired
-}
-
-Metas.contextTypes = {
- I18n: PropTypes.object
-}
+} \ No newline at end of file
diff --git a/app/javascript/time_tables/components/PeriodForm.js b/app/javascript/time_tables/components/PeriodForm.js
index d17a246f7..36ed6cfdf 100644
--- a/app/javascript/time_tables/components/PeriodForm.js
+++ b/app/javascript/time_tables/components/PeriodForm.js
@@ -33,7 +33,7 @@ const makeYearsOptions = (yearSelected) => {
return arr
}
-export default function PeriodForm({modal, timetable, metas, onOpenAddPeriodForm, onClosePeriodForm, onUpdatePeriodForm, onValidatePeriodForm}, {I18n}) {
+export default function PeriodForm({modal, timetable, metas, onOpenAddPeriodForm, onClosePeriodForm, onUpdatePeriodForm, onValidatePeriodForm}) {
return (
<div className="container-fluid">
<div className="row">
@@ -143,8 +143,4 @@ PeriodForm.propTypes = {
onUpdatePeriodForm: PropTypes.func.isRequired,
onValidatePeriodForm: PropTypes.func.isRequired,
timetable: PropTypes.object.isRequired
-}
-
-PeriodForm.contextTypes = {
- I18n: PropTypes.object
-}
+} \ No newline at end of file
diff --git a/app/javascript/time_tables/components/PeriodManager.js b/app/javascript/time_tables/components/PeriodManager.js
index 6b817fe73..6871d0b9b 100644
--- a/app/javascript/time_tables/components/PeriodManager.js
+++ b/app/javascript/time_tables/components/PeriodManager.js
@@ -55,7 +55,7 @@ export default class PeriodManager extends Component {
type='button'
onClick={() => this.props.onOpenEditPeriodForm(this.props.value, this.props.index)}
>
- Modifier
+ {I18n.t('actions.edit')}
</button>
</li>
<li className='delete-action'>
@@ -64,7 +64,7 @@ export default class PeriodManager extends Component {
onClick={() => this.props.onDeletePeriod(this.props.index, this.props.metas.day_types)}
>
<span className='fa fa-trash'></span>
- Supprimer
+ {I18n.t('actions.destroy')}
</button>
</li>
</ul>
@@ -79,8 +79,4 @@ PeriodManager.propTypes = {
currentDate: PropTypes.object.isRequired,
onDeletePeriod: PropTypes.func.isRequired,
onOpenEditPeriodForm: PropTypes.func.isRequired
-}
-
-PeriodManager.contextTypes = {
- I18n: PropTypes.object
} \ No newline at end of file
diff --git a/app/javascript/time_tables/components/TagsSelect2.js b/app/javascript/time_tables/components/TagsSelect2.js
index 43cf59fdf..dd8d6e9c0 100644
--- a/app/javascript/time_tables/components/TagsSelect2.js
+++ b/app/javascript/time_tables/components/TagsSelect2.js
@@ -40,7 +40,7 @@ export default class TagsSelect2 extends Component {
allowClear: true,
theme: 'bootstrap',
width: '100%',
- placeholder: this.context.I18n.t('time_tables.edit.select2.tag.placeholder'),
+ placeholder: I18n.t('time_tables.edit.select2.tag.placeholder'),
ajax: {
url: origin + path + '/tags.json',
dataType: 'json',
@@ -74,8 +74,4 @@ export default class TagsSelect2 extends Component {
const formatRepo = (props) => {
if(props.name) return props.name
-}
-
-TagsSelect2.contextTypes = {
- I18n: PropTypes.object
} \ No newline at end of file
diff --git a/app/javascript/time_tables/components/Timetable.js b/app/javascript/time_tables/components/Timetable.js
index 991f31435..3779fa2d0 100644
--- a/app/javascript/time_tables/components/Timetable.js
+++ b/app/javascript/time_tables/components/Timetable.js
@@ -31,11 +31,11 @@ export default class Timetable extends Component {
<div className="table table-2entries mb-sm">
<div className="t2e-head w20">
<div className="th">
- <div className="strong">{this.context.I18n.t('time_tables.edit.synthesis')}</div>
+ <div className="strong">{I18n.t('time_tables.edit.synthesis')}</div>
</div>
- <div className="td"><span>{this.context.I18n.t('time_tables.edit.day_types')}</span></div>
- <div className="td"><span>{this.context.I18n.t('time_tables.edit.periods')}</span></div>
- <div className="td"><span>{this.context.I18n.t('time_tables.edit.exceptions')}</span></div>
+ <div className="td"><span>{I18n.t('time_tables.edit.day_types')}</span></div>
+ <div className="td"><span>{I18n.t('time_tables.edit.periods')}</span></div>
+ <div className="td"><span>{I18n.t('time_tables.edit.exceptions')}</span></div>
</div>
<div className="t2e-item-list w80">
<div>
@@ -109,8 +109,4 @@ Timetable.propTypes = {
onDeletePeriod: PropTypes.func.isRequired,
onExcludeDateFromPeriod: PropTypes.func.isRequired,
onIncludeDateInPeriod: PropTypes.func.isRequired
-}
-
-Timetable.contextTypes = {
- I18n: PropTypes.object
-}
+} \ No newline at end of file
diff --git a/app/javascript/time_tables/containers/App.js b/app/javascript/time_tables/containers/App.js
index 5963f8f1d..c12e33ef5 100644
--- a/app/javascript/time_tables/containers/App.js
+++ b/app/javascript/time_tables/containers/App.js
@@ -10,7 +10,6 @@ import SaveTimetable from './SaveTimetable'
import ConfirmModal from './ConfirmModal'
import ErrorModal from './ErrorModal'
import clone from '../../helpers/clone'
-const I18n = clone(window, "I18n", true)
class App extends Component {
componentDidMount(){
diff --git a/app/javascript/vehicle_journeys/actions/index.js b/app/javascript/vehicle_journeys/actions/index.js
index e00e9b1b0..537dcfc06 100644
--- a/app/javascript/vehicle_journeys/actions/index.js
+++ b/app/javascript/vehicle_journeys/actions/index.js
@@ -113,14 +113,9 @@ const actions = {
type : 'EDIT_PURCHASE_WINDOWS_VEHICLEJOURNEY_MODAL',
vehicleJourneys
}),
- selectPurchaseWindowsModal: (selectedWindow) =>({
+ selectPurchaseWindowsModal: (selectedItem) =>({
type: 'SELECT_PURCHASE_WINDOW_MODAL',
- selectedItem:{
- id: selectedWindow.id,
- name: selectedWindow.name,
- color: selectedWindow.color,
- objectid: selectedWindow.objectid
- }
+ selectedItem
}),
addSelectedPurchaseWindow: () => ({
type: 'ADD_SELECTED_PURCHASE_WINDOW'
diff --git a/app/javascript/vehicle_journeys/components/Filters.js b/app/javascript/vehicle_journeys/components/Filters.js
index ae3ab3476..93fe015a8 100644
--- a/app/javascript/vehicle_journeys/components/Filters.js
+++ b/app/javascript/vehicle_journeys/components/Filters.js
@@ -145,12 +145,12 @@ export default function Filters({filters, pagination, missions, onFilter, onRese
<span
className='btn btn-link'
onClick={(e) => onResetFilters(e, pagination)}>
- Effacer
+ {I18n.t('actions.erase')}
</span>
<span
className='btn btn-default'
onClick={(e) => onFilter(e, pagination)}>
- Filtrer
+ {I18n.t('actions.filter')}
</span>
</div>
</div>
diff --git a/app/javascript/vehicle_journeys/components/tools/CustomFieldsInputs.js b/app/javascript/vehicle_journeys/components/tools/CustomFieldsInputs.js
index 90d72a801..827c36b76 100644
--- a/app/javascript/vehicle_journeys/components/tools/CustomFieldsInputs.js
+++ b/app/javascript/vehicle_journeys/components/tools/CustomFieldsInputs.js
@@ -27,6 +27,19 @@ export default class CustomFieldsInputs extends Component {
)
}
+ stringInput(cf){
+ return(
+ <input
+ type='text'
+ ref={'custom_fields.' + cf.code}
+ className='form-control'
+ disabled={this.props.disabled}
+ defaultValue={cf.value}
+ onChange={(e) => this.props.onUpdate(cf.code, e.target.value) }
+ />
+ )
+ }
+
render() {
return (
<div>
diff --git a/app/javascript/vehicle_journeys/components/tools/TimetablesEditVehicleJourney.js b/app/javascript/vehicle_journeys/components/tools/TimetablesEditVehicleJourney.js
index 7a2686c13..9ee2e1849 100644
--- a/app/javascript/vehicle_journeys/components/tools/TimetablesEditVehicleJourney.js
+++ b/app/javascript/vehicle_journeys/components/tools/TimetablesEditVehicleJourney.js
@@ -58,7 +58,7 @@ export default class TimetablesEditVehicleJourney extends Component {
<div className='wrapper'>
<div>
<div className='form-group'>
- <label className='control-label'>{this.props.modal.modalProps.timetables.length == 0 ? I18n.t('vehicle_journeys.vehicle_journeys_matrix.no_associated_timetables'): I18n.t('vehicle_journeys.form.timetables')}</label>
+ <label className='control-label'>{this.props.modal.modalProps.timetables.length == 0 ? I18n.t('vehicle_journeys.vehicle_journeys_matrix.no_associated_timetables'): I18n.t('vehicle_journeys.form.time_tables')}</label>
</div>
</div>
<div></div>
diff --git a/app/javascript/vehicle_journeys/components/tools/select2s/CompanySelect2.js b/app/javascript/vehicle_journeys/components/tools/select2s/CompanySelect2.js
index b7e9691c1..60ad439b8 100644
--- a/app/javascript/vehicle_journeys/components/tools/select2s/CompanySelect2.js
+++ b/app/javascript/vehicle_journeys/components/tools/select2s/CompanySelect2.js
@@ -31,7 +31,7 @@ export default class BSelect4 extends Component {
theme: 'bootstrap',
width: '100%',
placeholder: I18n.t('vehicle_journeys.vehicle_journeys_matrix.affect_company'),
- language: require('./fr'),
+ language: require('./language'),
ajax: {
url: origin + path + '/companies.json' + '?line_id=' + line,
dataType: 'json',
diff --git a/app/javascript/vehicle_journeys/components/tools/select2s/MissionSelect2.js b/app/javascript/vehicle_journeys/components/tools/select2s/MissionSelect2.js
index 96b34125d..cec39ab4e 100644
--- a/app/javascript/vehicle_journeys/components/tools/select2s/MissionSelect2.js
+++ b/app/javascript/vehicle_journeys/components/tools/select2s/MissionSelect2.js
@@ -75,7 +75,7 @@ export default class BSelect4 extends Component {
escapeMarkup: function (markup) { return markup; },
templateResult: formatRepo,
placeholder: I18n.t('vehicle_journeys.vehicle_journeys_matrix.filters.journey_pattern'),
- language: require('./fr'),
+ language: require('./language'),
allowClear: false,
escapeMarkup: function (markup) { return markup; },
}
diff --git a/app/javascript/vehicle_journeys/components/tools/select2s/TimetableSelect2.js b/app/javascript/vehicle_journeys/components/tools/select2s/TimetableSelect2.js
index 9a345b464..d5aad20d0 100644
--- a/app/javascript/vehicle_journeys/components/tools/select2s/TimetableSelect2.js
+++ b/app/javascript/vehicle_journeys/components/tools/select2s/TimetableSelect2.js
@@ -27,7 +27,7 @@ export default class BSelect4 extends Component {
theme: 'bootstrap',
width: '100%',
placeholder: I18n.t('vehicle_journeys.vehicle_journeys_matrix.filters.timetable'),
- language: require('./fr'),
+ language: require('./language'),
ajax: {
url: origin + path + this.props.chunkURL,
dataType: 'json',
diff --git a/app/javascript/vehicle_journeys/components/tools/select2s/VJSelect2.js b/app/javascript/vehicle_journeys/components/tools/select2s/VJSelect2.js
index f5881cef7..50a941b6d 100644
--- a/app/javascript/vehicle_journeys/components/tools/select2s/VJSelect2.js
+++ b/app/javascript/vehicle_journeys/components/tools/select2s/VJSelect2.js
@@ -27,7 +27,7 @@ export default class BSelect4b extends Component {
theme: 'bootstrap',
placeholder: I18n.t('vehicle_journeys.vehicle_journeys_matrix.filters.id'),
width: '100%',
- language: require('./fr'),
+ language: require('./language'),
ajax: {
url: origin + path + '/vehicle_journeys.json',
dataType: 'json',
diff --git a/app/javascript/vehicle_journeys/components/tools/select2s/fr.js b/app/javascript/vehicle_journeys/components/tools/select2s/fr.js
deleted file mode 100644
index 20154d412..000000000
--- a/app/javascript/vehicle_journeys/components/tools/select2s/fr.js
+++ /dev/null
@@ -1,9 +0,0 @@
-module.exports = {
- errorLoading:function(){return"Les rĂ©sultats ne peuvent pas Ăªtre chargĂ©s."},
- inputTooLong:function(e){var t=e.input.length-e.maximum,n="Supprimez "+t+" caractère";return t!==1&&(n+="s"),n},
- inputTooShort:function(e){var t=e.minimum-e.input.length,n="Saisissez "+t+" caractère";return t!==1&&(n+="s"),n},
- loadingMore:function(){return"Chargement de résultats supplémentaires…"},
- maximumSelected:function(e){var t="Vous pouvez seulement sélectionner "+e.maximum+" élément";return e.maximum!==1&&(t+="s"),t},
- noResults:function(){return"Aucun résultat trouvé"},
- searching:function(){return"Recherche en cours…"}
-}
diff --git a/app/javascript/vehicle_journeys/components/tools/select2s/language.js b/app/javascript/vehicle_journeys/components/tools/select2s/language.js
new file mode 100644
index 000000000..9d587f96e
--- /dev/null
+++ b/app/javascript/vehicle_journeys/components/tools/select2s/language.js
@@ -0,0 +1,9 @@
+module.exports = {
+ errorLoading: () => I18n.t('select2.error_loading'),
+ inputTooLong: (e) => I18n.t('select2.input_too_short', { count: e.input.length - e.maximum}),
+ inputTooShort: (e) => I18n.t('select2.input_too_long', { count: e.minimum - e.input.length }),
+ loadingMore: () => I18n.t('select2.loading_more'),
+ maximumSelected: (e) => I18n.t('select2.maximum_selected', {count: e.maximum}),
+ noResults: () => I18n.t('select2.no_results'),
+ searching: () => I18n.t('select2.searching')
+}
diff --git a/app/models/api/v1/api_key.rb b/app/models/api/v1/api_key.rb
index 09c6f77ac..e6ceb977a 100644
--- a/app/models/api/v1/api_key.rb
+++ b/app/models/api/v1/api_key.rb
@@ -1,7 +1,8 @@
module Api
module V1
- class ApiKey < ::ActiveRecord::Base
- has_paper_trail
+ class ApiKey < ::ApplicationModel
+ has_metadata
+
before_create :generate_access_token
belongs_to :referential, :class_name => '::Referential'
belongs_to :organisation, :class_name => '::Organisation'
@@ -47,4 +48,3 @@ module Api
end
end
end
-
diff --git a/app/models/application_model.rb b/app/models/application_model.rb
new file mode 100644
index 000000000..1a2a5099d
--- /dev/null
+++ b/app/models/application_model.rb
@@ -0,0 +1,5 @@
+class ApplicationModel < ::ActiveRecord::Base
+ include MetadataSupport
+
+ self.abstract_class = true
+end
diff --git a/app/models/calendar.rb b/app/models/calendar.rb
index 32eedf9ea..39e2b2cff 100644
--- a/app/models/calendar.rb
+++ b/app/models/calendar.rb
@@ -2,13 +2,13 @@ require 'range_ext'
require_relative 'calendar/date_value'
require_relative 'calendar/period'
-class Calendar < ActiveRecord::Base
+class Calendar < ApplicationModel
include DateSupport
include PeriodSupport
include ApplicationDaysSupport
include TimetableSupport
- has_paper_trail class_name: 'PublicVersion'
+ has_metadata
belongs_to :organisation
belongs_to :workgroup
diff --git a/app/models/calendar/date_value.rb b/app/models/calendar/date_value.rb
index a4a405d43..f50b4237c 100644
--- a/app/models/calendar/date_value.rb
+++ b/app/models/calendar/date_value.rb
@@ -1,4 +1,4 @@
-class Calendar < ActiveRecord::Base
+class Calendar < ApplicationModel
class DateValue
include ActiveAttr::Model
diff --git a/app/models/calendar/period.rb b/app/models/calendar/period.rb
index 8b3e4109b..07926e818 100644
--- a/app/models/calendar/period.rb
+++ b/app/models/calendar/period.rb
@@ -1,4 +1,4 @@
-class Calendar < ActiveRecord::Base
+class Calendar < ApplicationModel
class Period
include ActiveAttr::Model
diff --git a/app/models/chouette/access_link.rb b/app/models/chouette/access_link.rb
index 6b08443be..7ab8ca715 100644
--- a/app/models/chouette/access_link.rb
+++ b/app/models/chouette/access_link.rb
@@ -1,6 +1,6 @@
module Chouette
class AccessLink < Chouette::TridentActiveRecord
- has_paper_trail
+ has_metadata
include ObjectidSupport
attr_accessor :access_link_type, :link_orientation_type, :link_key
diff --git a/app/models/chouette/access_point.rb b/app/models/chouette/access_point.rb
index ac6580015..884460881 100644
--- a/app/models/chouette/access_point.rb
+++ b/app/models/chouette/access_point.rb
@@ -4,7 +4,7 @@ require 'geo_ruby'
module Chouette
class AccessPoint < Chouette::ActiveRecord
- has_paper_trail
+ has_metadata
include Geokit::Mappable
include ProjectionFields
diff --git a/app/models/chouette/active_record.rb b/app/models/chouette/active_record.rb
index c2aab9d50..27f5426b3 100644
--- a/app/models/chouette/active_record.rb
+++ b/app/models/chouette/active_record.rb
@@ -1,7 +1,8 @@
#require "active_record"
require 'deep_cloneable'
module Chouette
- class ActiveRecord < ::ActiveRecord::Base
+ class ActiveRecord < ::ApplicationModel
+
self.abstract_class = true
before_save :nil_if_blank, :set_data_source_ref
diff --git a/app/models/chouette/company.rb b/app/models/chouette/company.rb
index f5ed4e0f8..9d5737a6c 100644
--- a/app/models/chouette/company.rb
+++ b/app/models/chouette/company.rb
@@ -1,9 +1,11 @@
module Chouette
class Company < Chouette::ActiveRecord
+ has_metadata
+
include CompanyRestrictions
include LineReferentialSupport
include ObjectidSupport
- has_paper_trail class_name: 'PublicVersion'
+ include CustomFieldsSupport
has_many :lines
diff --git a/app/models/chouette/connection_link.rb b/app/models/chouette/connection_link.rb
index c53d6f5f1..fb93e5f90 100644
--- a/app/models/chouette/connection_link.rb
+++ b/app/models/chouette/connection_link.rb
@@ -1,6 +1,6 @@
module Chouette
class ConnectionLink < Chouette::TridentActiveRecord
- has_paper_trail
+ has_metadata
include ObjectidSupport
include ConnectionLinkRestrictions
diff --git a/app/models/chouette/for_alighting_enumerations.rb b/app/models/chouette/for_alighting_enumerations.rb
index ab07a670d..2e15fcb58 100644
--- a/app/models/chouette/for_alighting_enumerations.rb
+++ b/app/models/chouette/for_alighting_enumerations.rb
@@ -3,6 +3,6 @@ module Chouette
extend Enumerize
extend ActiveModel::Naming
- enumerize :for_alighting, in: %w[normal forbidden request_stop is_flexible]
+ enumerize :for_alighting, in: %w[normal forbidden request_stop is_flexible], default: :normal
end
end
diff --git a/app/models/chouette/for_boarding_enumerations.rb b/app/models/chouette/for_boarding_enumerations.rb
index 48f8762c2..0190bf805 100644
--- a/app/models/chouette/for_boarding_enumerations.rb
+++ b/app/models/chouette/for_boarding_enumerations.rb
@@ -3,6 +3,6 @@ module Chouette
extend Enumerize
extend ActiveModel::Naming
- enumerize :for_boarding, in: %w[normal forbidden request_stop is_flexible]
+ enumerize :for_boarding, in: %w[normal forbidden request_stop is_flexible], default: :normal
end
end
diff --git a/app/models/chouette/group_of_line.rb b/app/models/chouette/group_of_line.rb
index 3b6a7cea7..a30c34ce7 100644
--- a/app/models/chouette/group_of_line.rb
+++ b/app/models/chouette/group_of_line.rb
@@ -1,6 +1,6 @@
module Chouette
class GroupOfLine < Chouette::ActiveRecord
- has_paper_trail
+ has_metadata
include ObjectidSupport
include GroupOfLineRestrictions
include LineReferentialSupport
diff --git a/app/models/chouette/journey_pattern.rb b/app/models/chouette/journey_pattern.rb
index 5a5132200..830a6a808 100644
--- a/app/models/chouette/journey_pattern.rb
+++ b/app/models/chouette/journey_pattern.rb
@@ -1,6 +1,6 @@
module Chouette
class JourneyPattern < Chouette::TridentActiveRecord
- has_paper_trail
+ has_metadata
include ChecksumSupport
include JourneyPatternRestrictions
include ObjectidSupport
diff --git a/app/models/chouette/line.rb b/app/models/chouette/line.rb
index 9f05b611a..4b5d1a68d 100644
--- a/app/models/chouette/line.rb
+++ b/app/models/chouette/line.rb
@@ -1,6 +1,6 @@
module Chouette
class Line < Chouette::ActiveRecord
- has_paper_trail class_name: 'PublicVersion'
+ has_metadata
include LineRestrictions
include LineReferentialSupport
include ObjectidSupport
@@ -51,6 +51,14 @@ module Chouette
)
}
+ scope :for_organisation, ->(organisation){
+ if objectids = organisation&.lines_scope
+ where(objectid: objectids)
+ else
+ all
+ end
+ }
+
def self.nullable_attributes
[:published_name, :number, :comment, :url, :color, :text_color, :stable_id]
end
diff --git a/app/models/chouette/network.rb b/app/models/chouette/network.rb
index 942fc5d67..4802d7592 100644
--- a/app/models/chouette/network.rb
+++ b/app/models/chouette/network.rb
@@ -1,6 +1,6 @@
module Chouette
class Network < Chouette::ActiveRecord
- has_paper_trail class_name: 'PublicVersion'
+ has_metadata
include NetworkRestrictions
include LineReferentialSupport
include ObjectidSupport
diff --git a/app/models/chouette/pt_link.rb b/app/models/chouette/pt_link.rb
index 399539d44..680632a14 100644
--- a/app/models/chouette/pt_link.rb
+++ b/app/models/chouette/pt_link.rb
@@ -2,7 +2,7 @@ require 'geokit'
module Chouette
class PtLink < Chouette::ActiveRecord
- has_paper_trail
+ has_metadata
include Geokit::Mappable
def geometry
diff --git a/app/models/chouette/purchase_window.rb b/app/models/chouette/purchase_window.rb
index 4c8014780..e10b106ec 100644
--- a/app/models/chouette/purchase_window.rb
+++ b/app/models/chouette/purchase_window.rb
@@ -11,7 +11,7 @@ module Chouette
enumerize :color, in: %w(#9B9B9B #FFA070 #C67300 #7F551B #41CCE3 #09B09C #3655D7 #6321A0 #E796C6 #DD2DAA)
- has_paper_trail
+ has_metadata
belongs_to :referential
has_and_belongs_to_many :vehicle_journeys, :class_name => 'Chouette::VehicleJourney'
diff --git a/app/models/chouette/route.rb b/app/models/chouette/route.rb
index 13288bc6b..9c7a3e6d9 100644
--- a/app/models/chouette/route.rb
+++ b/app/models/chouette/route.rb
@@ -1,6 +1,7 @@
module Chouette
class Route < Chouette::TridentActiveRecord
- has_paper_trail
+ has_metadata
+
include RouteRestrictions
include ChecksumSupport
include ObjectidSupport
@@ -9,7 +10,6 @@ module Chouette
enumerize :direction, in: %i(straight_forward backward clockwise counter_clockwise north north_west west south_west south south_east east north_east)
enumerize :wayback, in: %i(outbound inbound), default: :outbound
-
def self.nullable_attributes
[:published_name, :comment, :number, :name, :direction, :wayback]
end
@@ -68,28 +68,34 @@ module Chouette
validates_presence_of :published_name
validates_presence_of :line
validates :wayback, inclusion: { in: self.wayback.values }
-
after_save :calculate_costs!, if: ->() { TomTom.enabled? }
-
- def duplicate
+
+ def duplicate opposite=false
overrides = {
'opposite_route_id' => nil,
'name' => I18n.t('activerecord.copy', name: self.name)
}
+ keys_for_create = attributes.keys - %w{id objectid created_at updated_at}
atts_for_create = attributes
- .slice!(*%w{id objectid created_at updated_at})
+ .slice(*keys_for_create)
.merge(overrides)
+ if opposite
+ atts_for_create[:wayback] = self.opposite_wayback
+ atts_for_create[:name] = I18n.t('routes.opposite', name: self.name)
+ atts_for_create[:published_name] = atts_for_create[:name]
+ atts_for_create[:opposite_route_id] = self.id
+ end
new_route = self.class.create!(atts_for_create)
- duplicate_stop_points(for_route: new_route)
+ duplicate_stop_points(for_route: new_route, opposite: opposite)
new_route
end
- def duplicate_stop_points(for_route:)
- stop_points.each(&duplicate_stop_point(for_route: for_route))
+ def duplicate_stop_points(for_route:, opposite: false)
+ stop_points.each(&duplicate_stop_point(for_route: for_route, opposite: opposite))
end
- def duplicate_stop_point(for_route:)
+ def duplicate_stop_point(for_route:, opposite: false)
-> stop_point do
- stop_point.duplicate(for_route: for_route)
+ stop_point.duplicate(for_route: for_route, opposite: opposite)
end
end
diff --git a/app/models/chouette/routing_constraint_zone.rb b/app/models/chouette/routing_constraint_zone.rb
index 58703598e..886eadc6c 100644
--- a/app/models/chouette/routing_constraint_zone.rb
+++ b/app/models/chouette/routing_constraint_zone.rb
@@ -1,6 +1,6 @@
module Chouette
class RoutingConstraintZone < Chouette::TridentActiveRecord
- has_paper_trail
+ has_metadata
include ChecksumSupport
include ObjectidSupport
diff --git a/app/models/chouette/stop_area.rb b/app/models/chouette/stop_area.rb
index 5f2c92acb..4ddc7403b 100644
--- a/app/models/chouette/stop_area.rb
+++ b/app/models/chouette/stop_area.rb
@@ -2,11 +2,12 @@ require 'geokit'
require 'geo_ruby'
module Chouette
class StopArea < Chouette::ActiveRecord
- has_paper_trail class_name: 'PublicVersion'
+ has_metadata
include ProjectionFields
include StopAreaRestrictions
include StopAreaReferentialSupport
include ObjectidSupport
+ include CustomFieldsSupport
extend Enumerize
enumerize :area_type, in: Chouette::AreaType::ALL
@@ -49,7 +50,7 @@ module Chouette
validate :registration_number_is_set
before_validation do
- self.registration_number ||= self.stop_area_referential.generate_registration_number
+ self.registration_number = self.stop_area_referential.generate_registration_number unless self.registration_number.present?
end
def self.nullable_attributes
@@ -90,7 +91,7 @@ module Chouette
end
unless self.stop_area_referential.validates_registration_number(self.registration_number)
- errors.add(:registration_number, I18n.t('stop_areas.errors.registration_number.invalid'))
+ errors.add(:registration_number, I18n.t('stop_areas.errors.registration_number.invalid', mask: self.stop_area_referential.registration_number_format))
end
end
diff --git a/app/models/chouette/stop_point.rb b/app/models/chouette/stop_point.rb
index 6b363cd93..1df1a664a 100644
--- a/app/models/chouette/stop_point.rb
+++ b/app/models/chouette/stop_point.rb
@@ -1,6 +1,6 @@
module Chouette
class StopPoint < Chouette::TridentActiveRecord
- has_paper_trail
+ has_metadata
def self.policy_class
RoutePolicy
end
@@ -39,11 +39,12 @@ module Chouette
end
end
- def duplicate(for_route:)
+ def duplicate(for_route:, opposite: false)
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)
+ atts_for_create["position"] = self.route.stop_points.size - atts_for_create["position"] if opposite
self.class.create!(atts_for_create)
end
diff --git a/app/models/chouette/time_table.rb b/app/models/chouette/time_table.rb
index 506e498b8..b59c95665 100644
--- a/app/models/chouette/time_table.rb
+++ b/app/models/chouette/time_table.rb
@@ -1,6 +1,6 @@
module Chouette
class TimeTable < Chouette::TridentActiveRecord
- has_paper_trail
+ has_metadata
include ChecksumSupport
include TimeTableRestrictions
include ObjectidSupport
diff --git a/app/models/chouette/timeband.rb b/app/models/chouette/timeband.rb
index 5a4e17b98..38260b755 100644
--- a/app/models/chouette/timeband.rb
+++ b/app/models/chouette/timeband.rb
@@ -9,7 +9,7 @@ module Chouette
class Timeband < Chouette::TridentActiveRecord
include ObjectidSupport
- has_paper_trail
+ has_metadata
validates :start_time, :end_time, presence: true
validates_with Chouette::TimebandValidator
diff --git a/app/models/chouette/vehicle_journey.rb b/app/models/chouette/vehicle_journey.rb
index 525036077..54aad290c 100644
--- a/app/models/chouette/vehicle_journey.rb
+++ b/app/models/chouette/vehicle_journey.rb
@@ -1,7 +1,7 @@
# coding: utf-8
module Chouette
class VehicleJourney < Chouette::TridentActiveRecord
- has_paper_trail
+ has_metadata
include ChecksumSupport
include CustomFieldsSupport
include VehicleJourneyRestrictions
@@ -346,6 +346,33 @@ module Chouette
end
end
+ def fill_passing_time_at_borders
+ encountered_borders = []
+ previous_stop = nil
+ vehicle_journey_at_stops.each do |vjas|
+ sp = vjas.stop_point
+ if sp.stop_area.area_type == "border"
+ encountered_borders << vjas
+ else
+ if encountered_borders.any?
+ before_cost = journey_pattern.costs_between previous_stop.stop_point, encountered_borders.first.stop_point
+ after_cost = journey_pattern.costs_between encountered_borders.last.stop_point, sp
+ if before_cost && before_cost[:distance] && after_cost && after_cost[:distance]
+ before_distance = before_cost[:distance].to_f
+ after_distance = after_cost[:distance].to_f
+ time = previous_stop.departure_time + before_distance / (before_distance+after_distance) * (vjas.arrival_time - previous_stop.departure_time)
+ encountered_borders.each do |b|
+ b.update_attribute :arrival_time, time
+ b.update_attribute :departure_time, time
+ end
+ end
+ encountered_borders = []
+ end
+ previous_stop = vjas
+ end
+ end
+ end
+
def self.matrix(vehicle_journeys)
Hash[*VehicleJourneyAtStop.where(vehicle_journey_id: vehicle_journeys.pluck(:id)).map do |vjas|
[ "#{vjas.vehicle_journey_id}-#{vjas.stop_point_id}", vjas]
diff --git a/app/models/clean_up.rb b/app/models/clean_up.rb
index 7aab7f32e..ec47489e9 100644
--- a/app/models/clean_up.rb
+++ b/app/models/clean_up.rb
@@ -1,4 +1,4 @@
-class CleanUp < ActiveRecord::Base
+class CleanUp < ApplicationModel
extend Enumerize
include AASM
belongs_to :referential
diff --git a/app/models/clean_up_result.rb b/app/models/clean_up_result.rb
index 24d262deb..dff4f5acd 100644
--- a/app/models/clean_up_result.rb
+++ b/app/models/clean_up_result.rb
@@ -1,3 +1,3 @@
-class CleanUpResult < ActiveRecord::Base
+class CleanUpResult < ApplicationModel
belongs_to :clean_up
end
diff --git a/app/models/compliance_check.rb b/app/models/compliance_check.rb
index 9d817e146..4ef6170e9 100644
--- a/app/models/compliance_check.rb
+++ b/app/models/compliance_check.rb
@@ -1,4 +1,4 @@
-class ComplianceCheck < ActiveRecord::Base
+class ComplianceCheck < ApplicationModel
include ComplianceItemSupport
self.inheritance_column = nil
diff --git a/app/models/compliance_check_block.rb b/app/models/compliance_check_block.rb
index 059547e1b..e4f4c1c37 100644
--- a/app/models/compliance_check_block.rb
+++ b/app/models/compliance_check_block.rb
@@ -1,4 +1,4 @@
-class ComplianceCheckBlock < ActiveRecord::Base
+class ComplianceCheckBlock < ApplicationModel
include StifTransportModeEnumerations
include StifTransportSubmodeEnumerations
diff --git a/app/models/compliance_check_message.rb b/app/models/compliance_check_message.rb
index 738bd4a4b..a4b1062f6 100644
--- a/app/models/compliance_check_message.rb
+++ b/app/models/compliance_check_message.rb
@@ -1,4 +1,4 @@
-class ComplianceCheckMessage < ActiveRecord::Base
+class ComplianceCheckMessage < ApplicationModel
extend Enumerize
belongs_to :compliance_check_set
diff --git a/app/models/compliance_check_resource.rb b/app/models/compliance_check_resource.rb
index 777254aaf..d2f782e2b 100644
--- a/app/models/compliance_check_resource.rb
+++ b/app/models/compliance_check_resource.rb
@@ -1,4 +1,4 @@
-class ComplianceCheckResource < ActiveRecord::Base
+class ComplianceCheckResource < ApplicationModel
extend Enumerize
belongs_to :compliance_check_set
diff --git a/app/models/compliance_check_set.rb b/app/models/compliance_check_set.rb
index 49d324c53..8b1dbdd68 100644
--- a/app/models/compliance_check_set.rb
+++ b/app/models/compliance_check_set.rb
@@ -1,6 +1,7 @@
-class ComplianceCheckSet < ActiveRecord::Base
+class ComplianceCheckSet < ApplicationModel
extend Enumerize
- has_paper_trail class_name: 'PublicVersion'
+
+ has_metadata
belongs_to :referential
belongs_to :compliance_control_set
diff --git a/app/models/compliance_control.rb b/app/models/compliance_control.rb
index 1cc06f927..672fb128c 100644
--- a/app/models/compliance_control.rb
+++ b/app/models/compliance_control.rb
@@ -1,4 +1,4 @@
-class ComplianceControl < ActiveRecord::Base
+class ComplianceControl < ApplicationModel
include ComplianceItemSupport
class << self
diff --git a/app/models/compliance_control_block.rb b/app/models/compliance_control_block.rb
index d7d84fd06..6a3c8a34e 100644
--- a/app/models/compliance_control_block.rb
+++ b/app/models/compliance_control_block.rb
@@ -1,4 +1,4 @@
-class ComplianceControlBlock < ActiveRecord::Base
+class ComplianceControlBlock < ApplicationModel
include StifTransportModeEnumerations
include StifTransportSubmodeEnumerations
@@ -12,6 +12,8 @@ class ComplianceControlBlock < ActiveRecord::Base
validates :transport_mode, presence: true
validates :compliance_control_set, presence: true
+ validates_uniqueness_of :condition_attributes, scope: :compliance_control_set_id
+
def name
ApplicationController.helpers.transport_mode_text(self)
end
diff --git a/app/models/compliance_control_set.rb b/app/models/compliance_control_set.rb
index c0ea692f2..4f0f86d08 100644
--- a/app/models/compliance_control_set.rb
+++ b/app/models/compliance_control_set.rb
@@ -1,5 +1,6 @@
-class ComplianceControlSet < ActiveRecord::Base
- has_paper_trail class_name: 'PublicVersion'
+class ComplianceControlSet < ApplicationModel
+ has_metadata
+
belongs_to :organisation
has_many :compliance_control_blocks, dependent: :destroy
has_many :compliance_controls, dependent: :destroy
diff --git a/app/models/concerns/custom_fields_support.rb b/app/models/concerns/custom_fields_support.rb
index 6c76bd653..017f496a8 100644
--- a/app/models/concerns/custom_fields_support.rb
+++ b/app/models/concerns/custom_fields_support.rb
@@ -3,22 +3,51 @@ module CustomFieldsSupport
included do
validate :custom_fields_values_are_valid
+ after_initialize :initialize_custom_fields
- def self.custom_fields
- CustomField.where(resource_type: self.name.split("::").last)
+ def self.custom_fields workgroup=:all
+ fields = CustomField.where(resource_type: self.name.split("::").last)
+ fields = fields.where(workgroup_id: workgroup&.id) if workgroup != :all
+ fields
end
- def custom_fields
- CustomField::Collection.new self
+ def method_missing method_name, *args
+ if method_name =~ /custom_field_*/ && method_name.to_sym != :custom_field_values && !@custom_fields_initialized
+ initialize_custom_fields
+ send method_name, *args
+ else
+ super method_name, *args
+ end
+ end
+
+ def custom_fields workgroup=:all
+ CustomField::Collection.new self, workgroup
+ end
+
+ def custom_field_values= vals
+ out = {}
+ custom_fields.each do |code, field|
+ out[code] = field.preprocess_value_for_assignment(vals.symbolize_keys[code.to_sym])
+ end
+ write_attribute :custom_field_values, out
+ end
+
+ def initialize_custom_fields
+ self.custom_field_values ||= {}
+ custom_fields(:all).values.each &:initialize_custom_field
+ custom_fields(:all).each do |k, v|
+ custom_field_values[k] ||= v.default_value
+ end
+ @custom_fields_initialized = true
end
def custom_field_value key
- (custom_field_values || {})[key.to_s]
+ (custom_field_values&.stringify_keys || {})[key.to_s]
end
private
def custom_fields_values_are_valid
- custom_fields.values.all?{|cf| cf.valid?}
+ custom_fields(:all).values.all?{|cf| cf.valid?}
end
end
end
diff --git a/app/models/concerns/metadata_support.rb b/app/models/concerns/metadata_support.rb
new file mode 100644
index 000000000..c4bedbcda
--- /dev/null
+++ b/app/models/concerns/metadata_support.rb
@@ -0,0 +1,107 @@
+module MetadataSupport
+ extend ActiveSupport::Concern
+
+ included do
+ class << self
+ def has_metadata?
+ !!@has_metadata
+ end
+
+ def has_metadata opts={}
+ @has_metadata = true
+
+ define_method :metadata do
+ attr_name = opts[:attr_name] || :metadata
+ @wrapped_metadata ||= begin
+ wrapped = MetadataSupport::MetadataWrapper.new self.read_attribute(attr_name)
+ wrapped.attribute_name = attr_name
+ wrapped.owner = self
+ wrapped
+ end
+ end
+
+ define_method :metadata= do |val|
+ @wrapped_metadata = nil
+ super val
+ end
+
+ define_method :set_metadata! do |name, value|
+ self.metadata.send "#{name}=", value
+ self.save!
+ end
+ end
+ end
+ end
+
+ def has_metadata?
+ self.class.has_metadata?
+ end
+
+ def merge_metadata_from source
+ return unless source.has_metadata?
+ source_metadata = source.metadata
+ res = {}
+ self.metadata.each do |k, v|
+ unless self.metadata.is_timestamp_attr?(k)
+ ts = self.metadata.timestamp_attr(k)
+ if source_metadata[ts] && source_metadata[ts] > self.metadata[ts]
+ res[k] = source_metadata[k]
+ else
+ res[k] = v
+ end
+ end
+ end
+ self.metadata = res
+ self
+ end
+
+ class MetadataWrapper < OpenStruct
+ attr_accessor :attribute_name, :owner
+
+ def is_timestamp_attr? name
+ name =~ /_updated_at$/
+ end
+
+ def timestamp_attr name
+ "#{name}_updated_at".to_sym
+ end
+
+ def method_missing(mid, *args)
+ out = super(mid, *args)
+ owner.send :write_attribute, attribute_name, @table
+ out = out&.to_time if args.length == 0 && is_timestamp_attr?(mid)
+ out
+ end
+
+ def each
+ @table.each do |k,v|
+ yield k, v
+ end
+ end
+
+ def new_ostruct_member name
+ unless is_timestamp_attr?(name)
+ timestamp_attr_name = timestamp_attr(name)
+ end
+
+ name = name.to_sym
+ unless respond_to?(name)
+ if timestamp_attr_name
+ define_singleton_method(timestamp_attr_name) { @table[timestamp_attr_name]&.to_time }
+ define_singleton_method(name) { @table[name] }
+ else
+ # we are defining an accessor for a timestamp
+ define_singleton_method(name) { @table[name]&.to_time }
+ end
+
+ define_singleton_method("#{name}=") do |x|
+ modifiable[timestamp_attr_name] = Time.now if timestamp_attr_name
+ modifiable[name] = x
+ owner.send :write_attribute, attribute_name, @table
+ end
+ modifiable[timestamp_attr_name] = Time.now if timestamp_attr_name
+ end
+ name
+ end
+ end
+end
diff --git a/app/models/custom_field.rb b/app/models/custom_field.rb
index 402df7fa9..22118a15a 100644
--- a/app/models/custom_field.rb
+++ b/app/models/custom_field.rb
@@ -1,16 +1,20 @@
-class CustomField < ActiveRecord::Base
+class CustomField < ApplicationModel
extend Enumerize
belongs_to :workgroup
- enumerize :field_type, in: %i{list}
+ enumerize :field_type, in: %i{list integer string attachment}
validates :name, uniqueness: {scope: [:resource_type, :workgroup_id]}
- validates :code, uniqueness: {scope: [:resource_type, :workgroup_id], case_sensitive: false}
+ validates :code, uniqueness: {scope: [:resource_type, :workgroup_id], case_sensitive: false}, presence: true
+
+ scope :for_workgroup, ->(workgroup){ where workgroup_id: workgroup.id }
+
+ scope :for_workgroup, ->(workgroup){ where workgroup_id: workgroup.id }
class Collection < HashWithIndifferentAccess
- def initialize object
- vals = object.class.custom_fields.map do |v|
- [v.code, CustomField::Value.new(object, v, object.custom_field_value(v.code))]
+ def initialize object, workgroup=:all
+ vals = object.class.custom_fields(workgroup).map do |v|
+ [v.code, CustomField::Instance.new(object, v, object.custom_field_value(v.code))]
end
super Hash[*vals.flatten]
end
@@ -20,11 +24,11 @@ class CustomField < ActiveRecord::Base
end
end
- class Value
+ class Instance
def self.new owner, custom_field, value
- field_type = custom_field.options["field_type"]
- klass_name = field_type && "CustomField::Value::#{field_type.classify}"
- klass = klass_name && const_defined?(klass_name) ? klass_name.constantize : CustomField::Value::Base
+ field_type = custom_field.field_type
+ klass_name = field_type && "CustomField::Instance::#{field_type.classify}"
+ klass = klass_name.safe_constantize || CustomField::Instance::Base
klass.new owner, custom_field, value
end
@@ -38,8 +42,14 @@ class CustomField < ActiveRecord::Base
@valid = false
end
+ attr_accessor :owner, :custom_field
+
delegate :code, :name, :field_type, to: :@custom_field
+ def default_value
+ options["default"]
+ end
+
def options
@custom_field.options || {}
end
@@ -57,6 +67,14 @@ class CustomField < ActiveRecord::Base
@raw_value
end
+ def input form_helper
+ @input ||= begin
+ klass_name = field_type && "CustomField::Instance::#{field_type.classify}::Input"
+ klass = klass_name.safe_constantize || CustomField::Instance::Base::Input
+ klass.new self, form_helper
+ end
+ end
+
def errors_key
"custom_fields.#{code}"
end
@@ -64,22 +82,184 @@ class CustomField < ActiveRecord::Base
def to_hash
HashWithIndifferentAccess[*%w(code name field_type options value).map{|k| [k, send(k)]}.flatten(1)]
end
+
+ def display_value
+ value
+ end
+
+ def initialize_custom_field
+ end
+
+ def preprocess_value_for_assignment val
+ val
+ end
+
+ def render_partial
+ ActionView::Base.new(Rails.configuration.paths["app/views"].first).render(
+ :partial => "shared/custom_fields/#{field_type}",
+ :locals => { field: self}
+ )
+ end
+
+ class Input
+ def initialize instance, form_helper
+ @instance = instance
+ @form_helper = form_helper
+ end
+
+ def custom_field
+ @instance.custom_field
+ end
+
+ delegate :custom_field, :value, :options, to: :@instance
+ delegate :code, :name, :field_type, to: :custom_field
+
+ def to_s
+ out = form_input
+ out.html_safe
+ end
+
+ protected
+
+ def form_input_id
+ "custom_field_#{code}"
+ end
+
+ def form_input_name
+ "#{@form_helper.object_name}[custom_field_values][#{code}]"
+ end
+
+ def form_input_options
+ {
+ input_html: {value: value, name: form_input_name},
+ label: name
+ }
+ end
+
+ def form_input
+ @form_helper.input form_input_id, form_input_options
+ end
+ end
end
class Integer < Base
def value
- @raw_value.to_i
+ @raw_value&.to_i
end
def validate
@valid = true
- unless @raw_value =~ /\A\d*\Z/
+ return if @raw_value.is_a?(Fixnum) || @raw_value.is_a?(Float)
+ unless @raw_value.to_s =~ /\A\d*\Z/
@owner.errors.add errors_key, "'#{@raw_value}' is not a valid integer"
@valid = false
end
end
end
+ class List < Integer
+ def validate
+ super
+ return unless value.present?
+ unless value >= 0 && value < options["list_values"].size
+ @owner.errors.add errors_key, "'#{@raw_value}' is not a valid value"
+ @valid = false
+ end
+ end
+
+ def display_value
+ return unless value
+ k = options["list_values"].is_a?(Hash) ? value.to_s : value.to_i
+ options["list_values"][k]
+ end
+
+ class Input < Base::Input
+ def form_input_options
+ collection = options["list_values"]
+ collection = collection.each_with_index.to_a if collection.is_a?(Array)
+ collection = collection.map(&:reverse) if collection.is_a?(Hash)
+ super.update({
+ selected: value,
+ collection: collection
+ })
+ end
+ end
+ end
+
+ class Attachment < Base
+ def initialize_custom_field
+ custom_field_code = self.code
+ _attr_name = attr_name
+ _uploader_name = uploader_name
+ owner.send :define_singleton_method, "read_uploader" do |attr|
+ if attr.to_s == _attr_name
+ custom_field_values[custom_field_code]
+ else
+ read_attribute attr
+ end
+ end
+
+ owner.send :define_singleton_method, "write_uploader" do |attr, val|
+ if attr.to_s == _attr_name
+ custom_field_values[custom_field_code] = val
+ else
+ write_attribute attr, val
+ end
+ end
+
+ owner.send :define_singleton_method, "#{_attr_name}_will_change!" do
+ custom_field_values_will_change!
+ end
+
+ _extension_whitelist = options["extension_whitelist"]
+
+ owner.send :define_singleton_method, "#{_uploader_name}_extension_whitelist" do
+ _extension_whitelist
+ end
+
+ unless owner.class.uploaders.has_key? _uploader_name.to_sym
+ owner.class.mount_uploader _uploader_name, CustomFieldAttachmentUploader, mount_on: "custom_field_#{code}_raw_value"
+ end
+ end
+
+ def preprocess_value_for_assignment val
+ if val.present?
+ owner.send "#{uploader_name}=", val
+ else
+ @raw_value
+ end
+ end
+
+ def value
+ owner.send "custom_field_#{code}"
+ end
+
+ def raw_value
+ @raw_value
+ end
+
+ def attr_name
+ "custom_field_#{code}_raw_value"
+ end
+
+ def uploader_name
+ "custom_field_#{code}"
+ end
+
+ def display_value
+ render_partial
+ end
+
+ class Input < Base::Input
+ def form_input_options
+ super.update({
+ as: :file,
+ wrapper: :horizontal_file_input
+ })
+ end
+ end
+ end
+
class String < Base
def value
"#{@raw_value}"
diff --git a/app/models/export/base.rb b/app/models/export/base.rb
index 6cf4c6b02..c65539635 100644
--- a/app/models/export/base.rb
+++ b/app/models/export/base.rb
@@ -1,4 +1,8 @@
+require 'net/http/post/multipart'
+
class Export::Base < ActiveRecord::Base
+ include Rails.application.routes.url_helpers
+
self.table_name = "exports"
belongs_to :referential
@@ -21,6 +25,22 @@ class Export::Base < ActiveRecord::Base
%w(zip csv json)
end
+ def upload_file file
+ url = URI.parse upload_workbench_export_url(self.workbench_id, self.id, host: Rails.application.config.rails_host)
+ res = nil
+ filename = File.basename(file.path)
+ content_type = MIME::Types.type_for(filename).first&.content_type
+ File.open(file.path) do |file_content|
+ req = Net::HTTP::Post::Multipart.new url.path,
+ file: UploadIO.new(file_content, content_type, filename),
+ token: self.token_upload
+ res = Net::HTTP.start(url.host, url.port) do |http|
+ http.request(req)
+ end
+ end
+ res
+ end
+
if Rails.env.development?
def self.force_load_descendants
path = Rails.root.join 'app/models/export'
diff --git a/app/models/export/message.rb b/app/models/export/message.rb
index b64b524ac..223429900 100644
--- a/app/models/export/message.rb
+++ b/app/models/export/message.rb
@@ -1,4 +1,4 @@
-class Export::Message < ActiveRecord::Base
+class Export::Message < ApplicationModel
self.table_name = :export_messages
include IevInterfaces::Message
diff --git a/app/models/export/resource.rb b/app/models/export/resource.rb
index 98f103be4..2a63c14a8 100644
--- a/app/models/export/resource.rb
+++ b/app/models/export/resource.rb
@@ -1,4 +1,4 @@
-class Export::Resource < ActiveRecord::Base
+class Export::Resource < ApplicationModel
self.table_name = :export_resources
include IevInterfaces::Resource
diff --git a/app/models/export/simple_exporter/base.rb b/app/models/export/simple_exporter/base.rb
index 4e6e8eba4..e77e23468 100644
--- a/app/models/export/simple_exporter/base.rb
+++ b/app/models/export/simple_exporter/base.rb
@@ -48,15 +48,15 @@ class Export::SimpleExporter::Base < Export::Base
exporter.export
set_status_from_exporter
convert_exporter_journal_to_messages
- self.file = tmp
self.save!
+ upload_file tmp
end
def set_status_from_exporter
if exporter.status.to_s == "error"
self.status = :failed
elsif exporter.status.to_s == "success"
- self.status = :successful
+ self.status = :successful
else
self.status = :warning
end
diff --git a/app/models/import/base.rb b/app/models/import/base.rb
index 62494c92e..82494b1dc 100644
--- a/app/models/import/base.rb
+++ b/app/models/import/base.rb
@@ -1,4 +1,4 @@
-class Import::Base < ActiveRecord::Base
+class Import::Base < ApplicationModel
self.table_name = "imports"
validates :file, presence: true
diff --git a/app/models/import/message.rb b/app/models/import/message.rb
index c1900a718..30b76ec5c 100644
--- a/app/models/import/message.rb
+++ b/app/models/import/message.rb
@@ -1,4 +1,4 @@
-class Import::Message < ActiveRecord::Base
+class Import::Message < ApplicationModel
self.table_name = :import_messages
include IevInterfaces::Message
diff --git a/app/models/import/resource.rb b/app/models/import/resource.rb
index 5bd011039..1951daacd 100644
--- a/app/models/import/resource.rb
+++ b/app/models/import/resource.rb
@@ -1,4 +1,4 @@
-class Import::Resource < ActiveRecord::Base
+class Import::Resource < ApplicationModel
self.table_name = :import_resources
include IevInterfaces::Resource
diff --git a/app/models/line_referential.rb b/app/models/line_referential.rb
index 0d2ed39b1..08193c960 100644
--- a/app/models/line_referential.rb
+++ b/app/models/line_referential.rb
@@ -1,7 +1,7 @@
-class LineReferential < ActiveRecord::Base
+class LineReferential < ApplicationModel
include ObjectidFormatterSupport
extend StifTransportModeEnumerations
-
+
has_many :line_referential_memberships
has_many :organisations, through: :line_referential_memberships
has_many :lines, class_name: 'Chouette::Line'
@@ -14,7 +14,7 @@ class LineReferential < ActiveRecord::Base
def add_member(organisation, options = {})
attributes = options.merge organisation: organisation
- line_referential_memberships.build attributes
+ line_referential_memberships.build attributes unless organisations.include?(organisation)
end
validates :name, presence: true
diff --git a/app/models/line_referential_membership.rb b/app/models/line_referential_membership.rb
index b49d1b5b1..8371bdc32 100644
--- a/app/models/line_referential_membership.rb
+++ b/app/models/line_referential_membership.rb
@@ -1,4 +1,6 @@
-class LineReferentialMembership < ActiveRecord::Base
+class LineReferentialMembership < ApplicationModel
belongs_to :organisation
belongs_to :line_referential
+
+ validates :organisation_id, presence: true, uniqueness: { scope: :line_referential }
end
diff --git a/app/models/line_referential_sync.rb b/app/models/line_referential_sync.rb
index 75c1e48a2..39e3846f0 100644
--- a/app/models/line_referential_sync.rb
+++ b/app/models/line_referential_sync.rb
@@ -1,4 +1,4 @@
-class LineReferentialSync < ActiveRecord::Base
+class LineReferentialSync < ApplicationModel
include AASM
belongs_to :line_referential
has_many :line_referential_sync_messages, :dependent => :destroy
diff --git a/app/models/line_referential_sync_message.rb b/app/models/line_referential_sync_message.rb
index 3b6cf3367..00a2b58a3 100644
--- a/app/models/line_referential_sync_message.rb
+++ b/app/models/line_referential_sync_message.rb
@@ -1,4 +1,4 @@
-class LineReferentialSyncMessage < ActiveRecord::Base
+class LineReferentialSyncMessage < ApplicationModel
belongs_to :line_referential_sync
enum criticity: [:info, :warning, :error]
diff --git a/app/models/merge.rb b/app/models/merge.rb
index e72c794fe..6e2a7036a 100644
--- a/app/models/merge.rb
+++ b/app/models/merge.rb
@@ -1,4 +1,4 @@
-class Merge < ActiveRecord::Base
+class Merge < ApplicationModel
extend Enumerize
belongs_to :workbench
@@ -138,7 +138,9 @@ class Merge < ActiveRecord::Base
new.switch do
referential_routes.each do |route|
existing_route = new.routes.find_by line_id: route.line_id, checksum: route.checksum
- unless existing_route
+ if existing_route
+ existing_route.merge_metadata_from route
+ else
objectid = Chouette::Route.where(objectid: route.objectid).exists? ? nil : route.objectid
attributes = route.attributes.merge(
id: nil,
@@ -196,7 +198,9 @@ class Merge < ActiveRecord::Base
existing_journey_pattern = new.journey_patterns.find_by route_id: existing_associated_route.id, checksum: journey_pattern.checksum
- unless existing_journey_pattern
+ if existing_journey_pattern
+ existing_journey_pattern.merge_metadata_from journey_pattern
+ else
objectid = Chouette::JourneyPattern.where(objectid: journey_pattern.objectid).exists? ? nil : journey_pattern.objectid
attributes = journey_pattern.attributes.merge(
id: nil,
@@ -241,7 +245,9 @@ class Merge < ActiveRecord::Base
existing_vehicle_journey = new.vehicle_journeys.find_by journey_pattern_id: existing_associated_journey_pattern.id, checksum: vehicle_journey.checksum
- unless existing_vehicle_journey
+ if existing_vehicle_journey
+ existing_vehicle_journey.merge_metadata_from vehicle_journey
+ else
objectid = Chouette::VehicleJourney.where(objectid: vehicle_journey.objectid).exists? ? nil : vehicle_journey.objectid
attributes = vehicle_journey.attributes.merge(
id: nil,
@@ -338,7 +344,9 @@ class Merge < ActiveRecord::Base
existing_time_table = line.time_tables.find_by checksum: candidate_time_table.checksum
- unless existing_time_table
+ if existing_time_table
+ existing_time_table.merge_metadata_from candidate_time_table
+ else
objectid = Chouette::TimeTable.where(objectid: time_table.objectid).exists? ? nil : time_table.objectid
candidate_time_table.objectid = objectid
diff --git a/app/models/organisation.rb b/app/models/organisation.rb
index 745bc0d22..5742c81e8 100644
--- a/app/models/organisation.rb
+++ b/app/models/organisation.rb
@@ -1,5 +1,5 @@
# coding: utf-8
-class Organisation < ActiveRecord::Base
+class Organisation < ApplicationModel
include DataFormatEnumerations
has_many :users, :dependent => :destroy
@@ -86,4 +86,8 @@ class Organisation < ActiveRecord::Base
workbenches.default
end
+ def lines_scope
+ functional_scope = sso_attributes.try(:[], "functional_scope")
+ JSON.parse(functional_scope) if functional_scope
+ end
end
diff --git a/app/models/public_version.rb b/app/models/public_version.rb
deleted file mode 100644
index 4dbf6ce27..000000000
--- a/app/models/public_version.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-class PublicVersion < PaperTrail::Version
- # custom behaviour, e.g:
- self.table_name = :'public.versions'
-end
diff --git a/app/models/referential.rb b/app/models/referential.rb
index 70148aa8e..1794126a2 100644
--- a/app/models/referential.rb
+++ b/app/models/referential.rb
@@ -1,5 +1,5 @@
# coding: utf-8
-class Referential < ActiveRecord::Base
+class Referential < ApplicationModel
include DataFormatEnumerations
include ObjectidFormatterSupport
@@ -241,7 +241,7 @@ class Referential < ActiveRecord::Base
end
end
- def self.new_from(from, functional_scope)
+ def self.new_from(from, organisation)
Referential.new(
name: I18n.t("activerecord.copy", name: from.name),
slug: "#{from.slug}_clone",
@@ -252,7 +252,7 @@ class Referential < ActiveRecord::Base
stop_area_referential: from.stop_area_referential,
created_from: from,
objectid_format: from.objectid_format,
- metadatas: from.metadatas.map { |m| ReferentialMetadata.new_from(m, functional_scope) }
+ metadatas: from.metadatas.map { |m| ReferentialMetadata.new_from(m, organisation) }
)
end
diff --git a/app/models/referential_cloning.rb b/app/models/referential_cloning.rb
index d4b74bd52..f2c81009a 100644
--- a/app/models/referential_cloning.rb
+++ b/app/models/referential_cloning.rb
@@ -1,4 +1,4 @@
-class ReferentialCloning < ActiveRecord::Base
+class ReferentialCloning < ApplicationModel
include AASM
belongs_to :source_referential, class_name: 'Referential'
belongs_to :target_referential, class_name: 'Referential'
diff --git a/app/models/referential_metadata.rb b/app/models/referential_metadata.rb
index 393dc70d3..7a8a01774 100644
--- a/app/models/referential_metadata.rb
+++ b/app/models/referential_metadata.rb
@@ -1,7 +1,7 @@
require 'activeattr_ext.rb'
require 'range_ext'
-class ReferentialMetadata < ActiveRecord::Base
+class ReferentialMetadata < ApplicationModel
belongs_to :referential, touch: true
belongs_to :referential_source, class_name: 'Referential'
has_array_of :lines, class_name: 'Chouette::Line'
@@ -155,10 +155,10 @@ class ReferentialMetadata < ActiveRecord::Base
end
private :clear_periods
- def self.new_from(from, functional_scope)
+ def self.new_from(from, organisation)
from.dup.tap do |metadata|
metadata.referential_source_id = from.referential_id
- metadata.line_ids = from.referential.lines.where(id: metadata.line_ids, objectid: functional_scope).collect(&:id)
+ metadata.line_ids = from.referential.lines.where(id: metadata.line_ids).for_organisation(organisation).pluck(:id)
metadata.referential_id = nil
end
end
diff --git a/app/models/referential_suite.rb b/app/models/referential_suite.rb
index 4f825628c..f4a72f22c 100644
--- a/app/models/referential_suite.rb
+++ b/app/models/referential_suite.rb
@@ -1,4 +1,4 @@
-class ReferentialSuite < ActiveRecord::Base
+class ReferentialSuite < ApplicationModel
belongs_to :new, class_name: 'Referential'
validate def validate_consistent_new
return true if new_id.nil? || new.nil?
diff --git a/app/models/simple_exporter.rb b/app/models/simple_exporter.rb
index c267b5b8c..1fcb76a29 100644
--- a/app/models/simple_exporter.rb
+++ b/app/models/simple_exporter.rb
@@ -64,7 +64,7 @@ class SimpleExporter < SimpleInterface
def map_item_to_rows item
return [item] unless configuration.item_to_rows_mapping
- configuration.item_to_rows_mapping.call(item).map {|row| row.is_a?(ActiveRecord::Base) ? row : CustomRow.new(row) }
+ instance_exec(item, &configuration.item_to_rows_mapping).map {|row| row.is_a?(ActiveRecord::Base) ? row : CustomRow.new(row) }
end
def resolve_value item, col
diff --git a/app/models/simple_interface.rb b/app/models/simple_interface.rb
index 43c740b57..7b04a07df 100644
--- a/app/models/simple_interface.rb
+++ b/app/models/simple_interface.rb
@@ -1,4 +1,4 @@
-class SimpleInterface < ActiveRecord::Base
+class SimpleInterface < ApplicationModel
attr_accessor :configuration, :interfaces_group
class << self
diff --git a/app/models/stop_area_referential.rb b/app/models/stop_area_referential.rb
index a9d3cc9b1..6c339547c 100644
--- a/app/models/stop_area_referential.rb
+++ b/app/models/stop_area_referential.rb
@@ -1,4 +1,4 @@
-class StopAreaReferential < ActiveRecord::Base
+class StopAreaReferential < ApplicationModel
validates :registration_number_format, format: { with: /\AX*\z/ }
include ObjectidFormatterSupport
@@ -12,7 +12,7 @@ class StopAreaReferential < ActiveRecord::Base
def add_member(organisation, options = {})
attributes = options.merge organisation: organisation
- stop_area_referential_memberships.build attributes
+ stop_area_referential_memberships.build attributes unless organisations.include?(organisation)
end
def last_sync
diff --git a/app/models/stop_area_referential_membership.rb b/app/models/stop_area_referential_membership.rb
index 435970961..d507bc50e 100644
--- a/app/models/stop_area_referential_membership.rb
+++ b/app/models/stop_area_referential_membership.rb
@@ -1,4 +1,6 @@
-class StopAreaReferentialMembership < ActiveRecord::Base
+class StopAreaReferentialMembership < ApplicationModel
belongs_to :organisation
belongs_to :stop_area_referential
+
+ validates :organisation_id, presence: true, uniqueness: { scope: :stop_area_referential }
end
diff --git a/app/models/stop_area_referential_sync.rb b/app/models/stop_area_referential_sync.rb
index e6cf2ecbc..8b48d35e6 100644
--- a/app/models/stop_area_referential_sync.rb
+++ b/app/models/stop_area_referential_sync.rb
@@ -1,4 +1,4 @@
-class StopAreaReferentialSync < ActiveRecord::Base
+class StopAreaReferentialSync < ApplicationModel
include AASM
belongs_to :stop_area_referential
has_many :stop_area_referential_sync_messages, :dependent => :destroy
diff --git a/app/models/stop_area_referential_sync_message.rb b/app/models/stop_area_referential_sync_message.rb
index cd2e62405..642ccfc38 100644
--- a/app/models/stop_area_referential_sync_message.rb
+++ b/app/models/stop_area_referential_sync_message.rb
@@ -1,4 +1,4 @@
-class StopAreaReferentialSyncMessage < ActiveRecord::Base
+class StopAreaReferentialSyncMessage < ApplicationModel
belongs_to :stop_area_referential_sync
enum criticity: [:info, :warning, :error]
diff --git a/app/models/user.rb b/app/models/user.rb
index eca7ede0c..29148d9e9 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1,4 +1,4 @@
-class User < ActiveRecord::Base
+class User < ApplicationModel
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable, :database_authenticatable
diff --git a/app/models/workbench.rb b/app/models/workbench.rb
index b5f4673bb..ef0b2eaa4 100644
--- a/app/models/workbench.rb
+++ b/app/models/workbench.rb
@@ -1,4 +1,4 @@
-class Workbench < ActiveRecord::Base
+class Workbench < ApplicationModel
DEFAULT_WORKBENCH_NAME = "Gestion de l'offre"
include ObjectidFormatterSupport
diff --git a/app/models/workgroup.rb b/app/models/workgroup.rb
index 7e3e857ec..3e8409634 100644
--- a/app/models/workgroup.rb
+++ b/app/models/workgroup.rb
@@ -1,4 +1,4 @@
-class Workgroup < ActiveRecord::Base
+class Workgroup < ApplicationModel
belongs_to :line_referential
belongs_to :stop_area_referential
diff --git a/app/policies/route_policy.rb b/app/policies/route_policy.rb
index 0337a5300..4fcb6be11 100644
--- a/app/policies/route_policy.rb
+++ b/app/policies/route_policy.rb
@@ -20,4 +20,8 @@ class RoutePolicy < ApplicationPolicy
def duplicate?
create?
end
+
+ def create_opposite?
+ create?
+ end
end
diff --git a/app/services/route_way_cost_calculator.rb b/app/services/route_way_cost_calculator.rb
index 2e30c94fc..d41a2e59a 100644
--- a/app/services/route_way_cost_calculator.rb
+++ b/app/services/route_way_cost_calculator.rb
@@ -5,7 +5,7 @@ class RouteWayCostCalculator
def calculate!
way_costs = StopAreasToWayCostsConverter.new(@route.stop_areas).convert
- way_costs = TomTom.batch(way_costs)
+ way_costs = TomTom.matrix(way_costs)
way_costs = WayCostCollectionJSONSerializer.dump(way_costs)
@route.update(costs: way_costs)
end
diff --git a/app/uploaders/custom_field_attachment_uploader.rb b/app/uploaders/custom_field_attachment_uploader.rb
new file mode 100644
index 000000000..411b65bc3
--- /dev/null
+++ b/app/uploaders/custom_field_attachment_uploader.rb
@@ -0,0 +1,12 @@
+class CustomFieldAttachmentUploader < CarrierWave::Uploader::Base
+
+ storage :file
+
+ def store_dir
+ "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
+ end
+
+ def extension_whitelist
+ model.send "#{mounted_as}_extension_whitelist"
+ end
+end
diff --git a/app/views/autocomplete_purchase_windows/index.rabl b/app/views/autocomplete_purchase_windows/index.rabl
index 1d0287602..bdc513c31 100644
--- a/app/views/autocomplete_purchase_windows/index.rabl
+++ b/app/views/autocomplete_purchase_windows/index.rabl
@@ -2,11 +2,12 @@ collection @purchase_windows, :object_root => false
node do |window|
{
- :id => window.id,
- :name => window.name,
- :objectid => window.objectid,
- :color => window.color,
- :short_id => window.get_objectid.short_id,
- :text => "<strong><span class='fa fa-circle' style='color:" + (window.color ? window.color : '#4b4b4b') + "'></span> " + window.name + " - " + window.get_objectid.short_id + "</strong>"
+ id: window.id,
+ name: window.name,
+ objectid: window.objectid,
+ color: window.color,
+ short_id: window.get_objectid.short_id,
+ bounding_dates: window.bounding_dates,
+ text: "<strong><span class='fa fa-circle' style='color:" + (window.color ? window.color : '#4b4b4b') + "'></span> " + window.name + " - " + window.get_objectid.short_id + "</strong>"
}
end
diff --git a/app/views/calendars/show.html.slim b/app/views/calendars/show.html.slim
index 648c98928..880db99f6 100644
--- a/app/views/calendars/show.html.slim
+++ b/app/views/calendars/show.html.slim
@@ -6,8 +6,7 @@
.row
.col-lg-6.col-md-6.col-sm-12.col-xs-12
= definition_list t('metadatas'),
- { Calendar.tmf('short_name') => resource.try(:short_name),
- Calendar.tmf('shared') => t("#{resource.shared}"),
+ { Calendar.tmf('shared') => t("#{resource.shared}"),
Calendar.tmf('organisation') => resource.organisation.name,
Calendar.tmf('dates') => resource.dates.collect{|d| l(d, format: :short)}.join(', ').html_safe,
Calendar.tmf('date_ranges') => resource.periods.map{|d| t('validity_range', debut: l(d.begin, format: :short), end: l(d.end, format: :short))}.join('<br>').html_safe }
@@ -18,7 +17,7 @@
.pagination.pull-right
= @year
.page_links
- = link_to '', calendar_path(@calendar, year: (@year - 1)), class: 'previous_page'
- = link_to '', calendar_path(@calendar, year: (@year + 1)), class: 'next_page'
+ = link_to '', workgroup_calendar_path(@workgroup, @calendar, year: (@year - 1)), class: 'previous_page'
+ = link_to '', workgroup_calendar_path(@workgroup, @calendar, year: (@year + 1)), class: 'next_page'
= render 'time_tables/show_time_table', time_table: @calendar
diff --git a/app/views/companies/_form.html.slim b/app/views/companies/_form.html.slim
index 3979c5800..e8b3fcede 100644
--- a/app/views/companies/_form.html.slim
+++ b/app/views/companies/_form.html.slim
@@ -12,7 +12,9 @@
= f.input :time_zone, include_blank: true
= f.input :url
= f.input :registration_number, :input_html => {:title => t("formtastic.titles#{format_restriction_for_locales(@line_referential)}.company.registration_number")}
-
+ - if resource.custom_fields(current_referential.workgroup).any?
+ - resource.custom_fields.each do |code, field|
+ = field.input(f).to_s
.separator
= f.button :submit, t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'company_form'
diff --git a/app/views/companies/show.html.slim b/app/views/companies/show.html.slim
index ca0a410b3..8960b92dd 100644
--- a/app/views/companies/show.html.slim
+++ b/app/views/companies/show.html.slim
@@ -6,8 +6,11 @@
.container-fluid
.row
.col-lg-6.col-md-6.col-sm-12.col-xs-12
- = definition_list t('metadatas'),
- { 'ID Codif' => @company.try(:get_objectid).try(:short_id),
- Chouette::Company.human_attribute_name(:phone) => resource.phone,
- Chouette::Company.human_attribute_name(:email) => resource.email,
- Chouette::Company.human_attribute_name(:url) => resource.url }
+ - attributes = { t('id_codif') => @company.try(:objectid).try(:local_id),
+ Chouette::Company.human_attribute_name(:phone) => @company.phone,
+ Chouette::Company.human_attribute_name(:email) => @company.email,
+ Chouette::Company.human_attribute_name(:url) => @company.url }
+ - @company.custom_fields(current_referential.workgroup).each do |code, field|
+ - attributes.merge!(field.name => field.display_value)
+
+ = definition_list t('metadatas'), attributes
diff --git a/app/views/compliance_control_blocks/edit.html.slim b/app/views/compliance_control_blocks/edit.html.slim
index 49aee7705..1d32256b0 100644
--- a/app/views/compliance_control_blocks/edit.html.slim
+++ b/app/views/compliance_control_blocks/edit.html.slim
@@ -1,3 +1,4 @@
+- breadcrumb :compliance_control_set, compliance_control_set
- page_header_content_for @compliance_control_block
.page_content
diff --git a/app/views/compliance_control_blocks/new.html.slim b/app/views/compliance_control_blocks/new.html.slim
index 7d2551311..aab40572b 100644
--- a/app/views/compliance_control_blocks/new.html.slim
+++ b/app/views/compliance_control_blocks/new.html.slim
@@ -1,3 +1,5 @@
+- breadcrumb :compliance_control_set, compliance_control_set
+
.page_content
.container-fluid
.row
diff --git a/app/views/lines/_filters.html.slim b/app/views/lines/_filters.html.slim
index da0539bd0..f745d10a4 100644
--- a/app/views/lines/_filters.html.slim
+++ b/app/views/lines/_filters.html.slim
@@ -44,5 +44,5 @@
.actions
- = link_to 'Effacer', @workbench, class: 'btn btn-link'
- = f.submit 'Filtrer', class: 'btn btn-default'
+ = link_to t('actions.erase'), @workbench, class: 'btn btn-link'
+ = f.submit t('actions.filter'), class: 'btn btn-default'
diff --git a/app/views/referential_companies/_form.html.slim b/app/views/referential_companies/_form.html.slim
index b02eab3f1..0e7b20af4 100644
--- a/app/views/referential_companies/_form.html.slim
+++ b/app/views/referential_companies/_form.html.slim
@@ -1,18 +1,19 @@
-= semantic_form_for [@referential, @company] do |form|
- = form.inputs do
- = form.input :name, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.company.name") }
- = form.input :short_name
- = form.input :organizational_unit
- = form.input :operating_department_name
- = form.input :code
- = form.input :phone, as: :phone
- = form.input :fax, as: :phone
- = form.input :email, as: :email
- = form.input :time_zone, include_blank: true
- = form.input :url
- = form.input :registration_number, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.company.registration_number") }
- = form.input :objectid, :required => !@company.new_record?, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.company.objectid") }
-
- = form.actions do
- = form.action :submit, as: :button
- = form.action :cancel, as: :link \ No newline at end of file
+= simple_form_for [@referential, @company], html: {class: 'form-horizontal', id: 'company_form'}, wrapper: :horizontal_form do |f|
+ .row
+ .col-lg-12
+ = f.input :name, :input_html => {:title => t("formtastic.titles#{format_restriction_for_locales(@line_referential)}.company.name")}
+ = f.input :short_name
+ = f.input :organizational_unit
+ = f.input :operating_department_name
+ = f.input :code
+ = f.input :phone
+ = f.input :fax
+ = f.input :email, as: :email
+ = f.input :time_zone, include_blank: true
+ = f.input :url
+ = f.input :registration_number, :input_html => {:title => t("formtastic.titles#{format_restriction_for_locales(@line_referential)}.company.registration_number")}
+ - if resource.custom_fields(@referential.workgroup).any?
+ - resource.custom_fields.each do |code, field|
+ = field.input(f).to_s
+ .separator
+ = f.button :submit, t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'company_form'
diff --git a/app/views/referential_companies/edit.html.slim b/app/views/referential_companies/edit.html.slim
index b3fcf6cd8..95be64aa1 100644
--- a/app/views/referential_companies/edit.html.slim
+++ b/app/views/referential_companies/edit.html.slim
@@ -1,3 +1,5 @@
- breadcrumb :referential_company, @referential, @company
- page_header_content_for @company
-= render 'form'
+.page_content
+ .container-fluid
+ = render 'form'
diff --git a/app/views/referential_companies/new.html.slim b/app/views/referential_companies/new.html.slim
index 5e59db139..1dfdc8eb5 100644
--- a/app/views/referential_companies/new.html.slim
+++ b/app/views/referential_companies/new.html.slim
@@ -1,2 +1,6 @@
- breadcrumb :referential_companies, @referential
-= render 'form'
+.page_content
+ .container-fluid
+ .row
+ .col-lg-8.col-lg-offset-2.col-md-8.col-md-offset-2.col-sm-10.col-sm-offset-1
+ = render 'form'
diff --git a/app/views/referential_companies/show.html.slim b/app/views/referential_companies/show.html.slim
index 1599145be..8ad011edf 100644
--- a/app/views/referential_companies/show.html.slim
+++ b/app/views/referential_companies/show.html.slim
@@ -17,8 +17,11 @@
.container-fluid
.row
.col-lg-6.col-md-6.col-sm-12.col-xs-12
- = definition_list t('metadatas'),
- { t('id_codif') => @company.try(:objectid).try(:local_id),
- Chouette::Company.human_attribute_name(:phone) => @company.phone,
- Chouette::Company.human_attribute_name(:email) => @company.email,
- Chouette::Company.human_attribute_name(:url) => @company.url }
+ - attributes = { t('id_codif') => @company.try(:objectid).try(:local_id),
+ Chouette::Company.human_attribute_name(:phone) => @company.phone,
+ Chouette::Company.human_attribute_name(:email) => @company.email,
+ Chouette::Company.human_attribute_name(:url) => @company.url }
+ - @company.custom_fields(@referential.workgroup).each do |code, field|
+ - attributes.merge!(field.name => field.display_value)
+
+ = definition_list t('metadatas'), attributes
diff --git a/app/views/referential_lines/_filters.html.slim b/app/views/referential_lines/_filters.html.slim
index 501f61c16..15db0e33e 100644
--- a/app/views/referential_lines/_filters.html.slim
+++ b/app/views/referential_lines/_filters.html.slim
@@ -1,7 +1,7 @@
= search_form_for @q, url: referential_line_path(@referential, @line), class: 'form form-filter' do |f|
.ffg-row
.input-group.search_bar class=filter_item_class(params[:q], :name_or_objectid_cont)
- = f.search_field :name_or_objectid_cont, class: 'form-control', placeholder: "Indiquez un nom d'itinéraire ou un ID..."
+ = f.search_field :name_or_objectid_cont, class: 'form-control', placeholder: t('.name_or_objectid_cont')
span.input-group-btn
button.btn.btn-default#search-btn type='submit'
span.fa.fa-search
@@ -12,5 +12,5 @@
= f.input :wayback_eq_any, class: 'form-control', collection: Chouette::Route.wayback.values, as: :check_boxes, label: false, required: false, wrapper_html: { class: 'checkbox_list'}, label_method: lambda{|l| ("<span>" + t("enumerize.route.wayback.#{l}") + "</span>").html_safe}
.actions
- = link_to 'Effacer', referential_line_path(@referential, @line), class: 'btn btn-link'
- = f.submit 'Filtrer', class: 'btn btn-default'
+ = link_to t('actions.erase'), referential_line_path(@referential, @line), class: 'btn btn-link'
+ = f.submit t('actions.filter'), class: 'btn btn-default'
diff --git a/app/views/referential_vehicle_journeys/_filters.html.slim b/app/views/referential_vehicle_journeys/_filters.html.slim
index f1fbdb5d8..f9fa4fcf7 100644
--- a/app/views/referential_vehicle_journeys/_filters.html.slim
+++ b/app/views/referential_vehicle_journeys/_filters.html.slim
@@ -68,5 +68,5 @@
.actions
- = link_to 'Effacer', referential_vehicle_journeys_path(@referential), class: 'btn btn-link'
- = f.submit 'Filtrer', class: 'btn btn-default'
+ = link_to t('actions.erase'), referential_vehicle_journeys_path(@referential), class: 'btn btn-link'
+ = f.submit t('actions.filter'), class: 'btn btn-default'
diff --git a/app/views/referentials/_form.html.slim b/app/views/referentials/_form.html.slim
index 96d847ec1..c378f871e 100644
--- a/app/views/referentials/_form.html.slim
+++ b/app/views/referentials/_form.html.slim
@@ -49,7 +49,7 @@
.separator
.row
.col-lg-11
- = subform.input :lines, as: :select, collection: Chouette::Line.includes(:company).order(:name).where(objectid: current_functional_scope), selected: subform.object.line_ids, label_method: :display_name, input_html: { 'data-select2ed': 'true', 'data-select2ed-placeholder': t('simple_form.labels.referential.placeholders.select_lines'), 'multiple': 'multiple', style: 'width: 100%' }
+ = subform.input :lines, as: :select, collection: Chouette::Line.includes(:company).order(:name).for_organisation(current_organisation), selected: subform.object.line_ids, label_method: :display_name, input_html: { 'data-select2ed': 'true', 'data-select2ed-placeholder': t('simple_form.labels.referential.placeholders.select_lines'), 'multiple': 'multiple', style: 'width: 100%' }
.col-lg-1
a.clear-lines.btn.btn-default href='#'
.fa.fa-trash
diff --git a/app/views/referentials/select_compliance_control_set.html.slim b/app/views/referentials/select_compliance_control_set.html.slim
index 69c87aab2..7be82364d 100644
--- a/app/views/referentials/select_compliance_control_set.html.slim
+++ b/app/views/referentials/select_compliance_control_set.html.slim
@@ -1,3 +1,5 @@
+- breadcrumb @referential
+
.page_content
.container-fluid
.row
@@ -6,7 +8,7 @@
.row
.col-lg-12
.form-group
- = label_tag 'name', nil, class: 'string required col-sm-4 col-xs-5 control-label'
+ = label_tag ComplianceControlSet.ts, nil, class: 'string required col-sm-4 col-xs-5 control-label'
.col-sm-8.col-xs-7
= select_tag :compliance_control_set, options_from_collection_for_select(@compliance_control_sets, "id", "name"), class: 'select optional form-control'
.separator
diff --git a/app/views/routes/show.html.slim b/app/views/routes/show.html.slim
index d2e750fb0..d4571c173 100644
--- a/app/views/routes/show.html.slim
+++ b/app/views/routes/show.html.slim
@@ -34,7 +34,7 @@
end \
), \
TableBuilderHelper::Column.new( \
- key: :deleted_at, \
+ name: Chouette::Line.tmf('activated'), \
attribute: Proc.new { |s| line_status(s.try(:stop_area).deleted_at) } \
), \
TableBuilderHelper::Column.new( \
diff --git a/app/views/shared/custom_fields/_attachment.html.slim b/app/views/shared/custom_fields/_attachment.html.slim
new file mode 100644
index 000000000..32d0fda4d
--- /dev/null
+++ b/app/views/shared/custom_fields/_attachment.html.slim
@@ -0,0 +1,4 @@
+- if field.value.present?
+ = link_to I18n.t("custom_fields.#{field.owner.class.name.demodulize.underscore}.#{field.code}.link"), field.value.url
+- else
+ = "-"
diff --git a/app/views/shared/iev_interfaces/_messages.html.slim b/app/views/shared/iev_interfaces/_messages.html.slim
index 022f4ee01..14157a88d 100644
--- a/app/views/shared/iev_interfaces/_messages.html.slim
+++ b/app/views/shared/iev_interfaces/_messages.html.slim
@@ -9,6 +9,6 @@
- else
.col-md-6= export_message_content message
.col-md-6
- - if message.criticity != "info"
+ - if message.resource_attributes
pre
= JSON.pretty_generate message.resource_attributes || {}
diff --git a/app/views/stop_areas/_filters.html.slim b/app/views/stop_areas/_filters.html.slim
index a32638567..c698eaaa5 100644
--- a/app/views/stop_areas/_filters.html.slim
+++ b/app/views/stop_areas/_filters.html.slim
@@ -41,5 +41,5 @@
input_html: { checked: @status.try(:[], :deactivated) }
.actions
- = link_to 'Effacer', @workbench, class: 'btn btn-link'
- = f.submit 'Filtrer', class: 'btn btn-default'
+ = link_to t('actions.erase'), @workbench, class: 'btn btn-link'
+ = f.submit t('actions.filter'), class: 'btn btn-default'
diff --git a/app/views/stop_areas/_form.html.slim b/app/views/stop_areas/_form.html.slim
index 1cba88f94..00f2ad8bb 100644
--- a/app/views/stop_areas/_form.html.slim
+++ b/app/views/stop_areas/_form.html.slim
@@ -48,7 +48,7 @@
- if has_feature?(:stop_area_waiting_time)
= f.input :waiting_time, input_html: { min: 0 }
- = f.input :registration_number, required: stop_area_registration_number_is_required(f.object), :input_html => {title: stop_area_registration_number_title(f.object), value: stop_area_registration_number_value(f.object)}
+ = f.input :registration_number, required: stop_area_registration_number_is_required(f.object), :input_html => {title: stop_area_registration_number_title(f.object), value: stop_area_registration_number_value(f.object)}, hint: stop_area_registration_number_hint
= f.input :fare_code
= f.input :nearest_topic_name, :input_html => {:title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.stop_area.nearest_topic_name")}
= f.input :comment, as: :text, :input_html => {:rows => 5, :title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.stop_area.comment")}
@@ -62,6 +62,12 @@
= f.input :stairs_availability, as: :select, :collection => [[t("true"), true], [t("false"), false]], :include_blank => true
= f.input :lift_availability, as: :select, :collection => [[t("true"), true], [t("false"), false]], :include_blank => true
+ - if resource.custom_fields(resource.stop_area_referential.workgroup).any?
+ .custom_fields
+ h3 = t("stop_areas.stop_area.custom_fields")
+ - resource.custom_fields(resource.stop_area_referential.workgroup).each do |code, field|
+ = field.input(f).to_s
+
.separator
= f.button :submit, t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'stop_area_form'
diff --git a/app/views/stop_areas/index.html.slim b/app/views/stop_areas/index.html.slim
index 587efbdaa..fbdb54e02 100644
--- a/app/views/stop_areas/index.html.slim
+++ b/app/views/stop_areas/index.html.slim
@@ -32,7 +32,7 @@
attribute: 'registration_number' \
), \
TableBuilderHelper::Column.new( \
- name: t('activerecord.attributes.stop_area.state'), \
+ name: Chouette::StopArea.tmf('state'), \
attribute: Proc.new { |s| stop_area_status(s) } \
), \
TableBuilderHelper::Column.new( \
diff --git a/app/views/stop_areas/show.html.slim b/app/views/stop_areas/show.html.slim
index a6147b86d..851bd9b82 100644
--- a/app/views/stop_areas/show.html.slim
+++ b/app/views/stop_areas/show.html.slim
@@ -23,4 +23,6 @@
t('activerecord.attributes.stop_area.state') => stop_area_status(@stop_area),
@stop_area.human_attribute_name(:comment) => @stop_area.try(:comment),
})
+ - @stop_area.custom_fields.each do |code, field|
+ - attributes.merge!(field.name => field.display_value)
= definition_list t('metadatas'), attributes
diff --git a/app/views/vehicle_journeys/index.html.slim b/app/views/vehicle_journeys/index.html.slim
index cd55d3ce6..7fcee545f 100644
--- a/app/views/vehicle_journeys/index.html.slim
+++ b/app/views/vehicle_journeys/index.html.slim
@@ -7,7 +7,7 @@
- if has_feature? :purchase_windows
= link_to I18n.t("purchase_windows.index.title"), [@referential, :purchase_windows], class: 'btn btn-primary sticky-action', target: :blank
- if @route.opposite_route.present?
- = link_to(t('routes.actions.opposite_route_timetable'), [@referential, @route.line, @route.opposite_route, :vehicle_journeys], class: 'btn btn-primary sticky-action')
+ = link_to(t('routes.actions.reversed_vehicle_journey'), [@referential, @route.line, @route.opposite_route, :vehicle_journeys], class: 'btn btn-primary sticky-action')
.page_content
@@ -33,7 +33,6 @@
| window.all_missions = #{(@all_missions.to_json).html_safe};
| window.custom_fields = #{(@custom_fields.to_json).html_safe};
| window.extra_headers = #{(@extra_headers.to_json).html_safe};
- // | window.I18n = #{(I18n.backend.send(:translations).to_json).html_safe};
- if has_feature?(:vehicle_journeys_return_route)
= javascript_tag do
diff --git a/app/views/workbench_outputs/show.html.slim b/app/views/workbench_outputs/show.html.slim
index a9e106dbb..b310119e6 100644
--- a/app/views/workbench_outputs/show.html.slim
+++ b/app/views/workbench_outputs/show.html.slim
@@ -6,7 +6,8 @@
.row.mb-sm
.col-lg-12.text-right
= link_to t('.see_current_output'), referential_path(@workbench.output.current), class: 'btn btn-primary' if @workbench.output&.current
- = link_to t('merges.actions.create'), new_workbench_merge_path(@workbench), class: 'btn btn-primary'
+ - if policy(Merge).create?
+ = link_to t('merges.actions.create'), new_workbench_merge_path(@workbench), class: 'btn btn-primary'
.page_content
.container-fluid
diff --git a/app/views/workbenches/show.html.slim b/app/views/workbenches/show.html.slim
index 8312338d0..7dd1583fa 100644
--- a/app/views/workbenches/show.html.slim
+++ b/app/views/workbenches/show.html.slim
@@ -32,7 +32,8 @@
end \
), \
TableBuilderHelper::Column.new( \
- key: :status, \
+ key: :archived_at, \
+ name: Referential.tmf('status'), \
attribute: Proc.new {|w| w.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} \
), \
TableBuilderHelper::Column.new( \
@@ -45,7 +46,7 @@
), \
TableBuilderHelper::Column.new( \
key: :lines, \
- name: t('activerecord.attributes.referential.number_of_lines'), \
+ name: Referential.tmf('number_of_lines'), \
attribute: Proc.new {|w| w.lines.count} \
), \
TableBuilderHelper::Column.new( \