aboutsummaryrefslogtreecommitdiffstats
path: root/app/models
diff options
context:
space:
mode:
authorLuc Donnet2018-01-03 11:57:42 +0100
committerLuc Donnet2018-01-03 11:57:42 +0100
commit7cce4762c11e7d1e78433f6f88d2e12928c398dc (patch)
tree3084d95692a70f9c5d5a842aae6f4ec0ea07a1c3 /app/models
parent6497b23e18385121974f6cbf56d48caf897e69b1 (diff)
parent414d0f6c4dd992696354757c4ae700952a7e4dd9 (diff)
downloadchouette-core-7cce4762c11e7d1e78433f6f88d2e12928c398dc.tar.bz2
Merge branch 'master' into 5024-prevent-duplicate-referentials-from-being-created-during-parallel-db-transactions--rb201711271659
Diffstat (limited to 'app/models')
-rw-r--r--app/models/calendar.rb151
-rw-r--r--app/models/calendar/period.rb2
-rw-r--r--app/models/chouette/area_type.rb42
-rw-r--r--app/models/chouette/line.rb13
-rw-r--r--app/models/chouette/purchase_window.rb36
-rw-r--r--app/models/chouette/stop_area.rb33
-rw-r--r--app/models/chouette/vehicle_journey.rb12
-rw-r--r--app/models/chouette/vehicle_journey_at_stop.rb11
-rw-r--r--app/models/compliance_check_block.rb6
-rw-r--r--app/models/compliance_control.rb3
-rw-r--r--app/models/compliance_control_block.rb10
-rw-r--r--app/models/concerns/date_support.rb80
-rw-r--r--app/models/concerns/period_support.rb80
-rw-r--r--app/models/generic_attribute_control/min_max.rb2
-rw-r--r--app/models/generic_attribute_control/pattern.rb2
-rw-r--r--app/models/generic_attribute_control/uniqueness.rb2
-rw-r--r--app/models/import.rb48
-rw-r--r--app/models/organisation.rb66
-rw-r--r--app/models/referential.rb14
-rw-r--r--app/models/referential_cloning.rb21
-rw-r--r--app/models/user.rb2
-rw-r--r--app/models/vehicle_journey_control/delta.rb2
-rw-r--r--app/models/vehicle_journey_control/speed.rb2
-rw-r--r--app/models/vehicle_journey_control/waiting_time.rb4
24 files changed, 409 insertions, 235 deletions
diff --git a/app/models/calendar.rb b/app/models/calendar.rb
index b2e73929f..34ed51374 100644
--- a/app/models/calendar.rb
+++ b/app/models/calendar.rb
@@ -3,22 +3,19 @@ require_relative 'calendar/date_value'
require_relative 'calendar/period'
class Calendar < ActiveRecord::Base
+ include DateSupport
+ include PeriodSupport
+
has_paper_trail
belongs_to :organisation
- has_many :time_tables
validates_presence_of :name, :short_name, :organisation
validates_uniqueness_of :short_name
- after_initialize :init_dates_and_date_ranges
+ has_many :time_tables
scope :contains_date, ->(date) { where('date ? = any (dates) OR date ? <@ any (date_ranges)', date, date) }
- def init_dates_and_date_ranges
- self.dates ||= []
- self.date_ranges ||= []
- end
-
def self.ransackable_scopes(auth_object = nil)
[:contains_date]
end
@@ -35,144 +32,4 @@ class Calendar < ActiveRecord::Base
end
end
-
- ### Calendar::Period
- # Required by coocon
- def build_period
- Calendar::Period.new
- end
-
- def periods
- @periods ||= init_periods
- end
-
- def init_periods
- (date_ranges || [])
- .each_with_index
- .map( &Calendar::Period.method(:from_range) )
- end
- private :init_periods
-
- validate :validate_periods
-
- def validate_periods
- periods_are_valid = periods.all?(&:valid?)
-
- periods.each do |period|
- if period.intersect?(periods)
- period.errors.add(:base, I18n.t('calendars.errors.overlapped_periods'))
- periods_are_valid = false
- end
- end
-
- unless periods_are_valid
- errors.add(:periods, :invalid)
- end
- end
-
- def flatten_date_array attributes, key
- date_int = %w(1 2 3).map {|e| attributes["#{key}(#{e}i)"].to_i }
- Date.new(*date_int)
- end
-
- def periods_attributes=(attributes = {})
- @periods = []
- attributes.each do |index, period_attribute|
- # Convert date_select to date
- ['begin', 'end'].map do |attr|
- period_attribute[attr] = flatten_date_array(period_attribute, attr)
- end
- period = Calendar::Period.new(period_attribute.merge(id: index))
- @periods << period unless period.marked_for_destruction?
- end
-
- date_ranges_will_change!
- end
-
- before_validation :fill_date_ranges
-
- def fill_date_ranges
- if @periods
- self.date_ranges = @periods.map(&:range).compact.sort_by(&:begin)
- end
- end
-
- after_save :clear_periods
-
- def clear_periods
- @periods = nil
- end
-
- private :clear_periods
-
- ### Calendar::DateValue
-
- # Required by coocon
- def build_date_value
- Calendar::DateValue.new
- end
-
- def date_values
- @date_values ||= init_date_values
- end
-
- def init_date_values
- if dates
- dates.each_with_index.map { |d, index| Calendar::DateValue.from_date(index, d) }
- else
- []
- end
- end
- private :init_date_values
-
- validate :validate_date_values
-
- def validate_date_values
- date_values_are_valid = date_values.all?(&:valid?)
-
- date_values.each do |date_value|
- if date_values.count { |d| d.value == date_value.value } > 1
- date_value.errors.add(:base, I18n.t('activerecord.errors.models.calendar.attributes.dates.date_in_dates'))
- date_values_are_valid = false
- end
- date_ranges.each do |date_range|
- if date_range.cover? date_value.value
- date_value.errors.add(:base, I18n.t('activerecord.errors.models.calendar.attributes.dates.date_in_date_ranges'))
- date_values_are_valid = false
- end
- end
- end
-
- unless date_values_are_valid
- errors.add(:date_values, :invalid)
- end
- end
-
- def date_values_attributes=(attributes = {})
- @date_values = []
- attributes.each do |index, date_value_attribute|
- date_value_attribute['value'] = flatten_date_array(date_value_attribute, 'value')
- date_value = Calendar::DateValue.new(date_value_attribute.merge(id: index))
- @date_values << date_value unless date_value.marked_for_destruction?
- end
-
- dates_will_change!
- end
-
- before_validation :fill_dates
-
- def fill_dates
- if @date_values
- self.dates = @date_values.map(&:value).compact.sort
- end
- end
-
- after_save :clear_date_values
-
- def clear_date_values
- @date_values = nil
- end
-
- private :clear_date_values
-
end
diff --git a/app/models/calendar/period.rb b/app/models/calendar/period.rb
index 1c423dfcc..56ab722fe 100644
--- a/app/models/calendar/period.rb
+++ b/app/models/calendar/period.rb
@@ -1,5 +1,5 @@
class Calendar < ActiveRecord::Base
-
+
class Period
include ActiveAttr::Model
diff --git a/app/models/chouette/area_type.rb b/app/models/chouette/area_type.rb
new file mode 100644
index 000000000..43d96b391
--- /dev/null
+++ b/app/models/chouette/area_type.rb
@@ -0,0 +1,42 @@
+class Chouette::AreaType
+ include Comparable
+
+ ALL = %i(zdep zder zdlp zdlr lda gdl).freeze
+
+ @@all = ALL
+ mattr_accessor :all
+
+ def self.all=(values)
+ @@all = ALL & values
+ reset_caches!
+ end
+
+ @@instances = {}
+ def self.find(code)
+ code = code.to_sym
+ @@instances[code] ||= new(code) if ALL.include? code
+ end
+
+ def self.reset_caches!
+ @@instances = {}
+ @@options = nil
+ end
+
+ def self.options
+ @@options ||= all.map { |c| find(c) }.map { |t| [ t.label, t.code ] }
+ end
+
+ attr_reader :code
+ def initialize(code)
+ @code = code
+ end
+
+ def <=>(other)
+ all.index(code) <=> all.index(other.code)
+ end
+
+ def label
+ I18n.translate code, scope: 'area_types.label'
+ end
+
+end
diff --git a/app/models/chouette/line.rb b/app/models/chouette/line.rb
index 784e3f5b9..2d776e94b 100644
--- a/app/models/chouette/line.rb
+++ b/app/models/chouette/line.rb
@@ -72,12 +72,23 @@ module Chouette
end
def display_name
- [self.get_objectid.local_id, number, name, company.try(:name)].compact.join(' - ')
+ [self.get_objectid.short_id, number, name, company.try(:name)].compact.join(' - ')
end
def companies
line_referential.companies.where(id: ([company_id] + Array(secondary_company_ids)).compact)
end
+ def deactivate!
+ update_attribute :deactivated, true
+ end
+
+ def activate!
+ update_attribute :deactivated, false
+ end
+
+ def activated?
+ !deactivated
+ end
end
end
diff --git a/app/models/chouette/purchase_window.rb b/app/models/chouette/purchase_window.rb
new file mode 100644
index 000000000..e89a0ec7f
--- /dev/null
+++ b/app/models/chouette/purchase_window.rb
@@ -0,0 +1,36 @@
+require 'range_ext'
+require_relative '../calendar/period'
+
+module Chouette
+ class PurchaseWindow < Chouette::TridentActiveRecord
+ # include ChecksumSupport
+ include ObjectidSupport
+ include PeriodSupport
+ extend Enumerize
+ enumerize :color, in: %w(#9B9B9B #FFA070 #C67300 #7F551B #41CCE3 #09B09C #3655D7 #6321A0 #E796C6 #DD2DAA)
+
+ has_paper_trail
+ belongs_to :referential
+ has_and_belongs_to_many :vehicle_journeys, :class_name => 'Chouette::VehicleJourney'
+
+ validates_presence_of :name, :referential
+
+ scope :contains_date, ->(date) { where('date ? <@ any (date_ranges)', date) }
+
+ def self.ransackable_scopes(auth_object = nil)
+ [:contains_date]
+ end
+
+ def self.colors_i18n
+ Hash[*color.values.map{|c| [I18n.t("enumerize.purchase_window.color.#{c[1..-1]}"), c]}.flatten]
+ end
+
+ def local_id
+ "IBOO-#{self.referential.id}-#{self.id}"
+ end
+
+ # def checksum_attributes
+ # end
+
+ end
+end
diff --git a/app/models/chouette/stop_area.rb b/app/models/chouette/stop_area.rb
index cc7170728..4f1359ff8 100644
--- a/app/models/chouette/stop_area.rb
+++ b/app/models/chouette/stop_area.rb
@@ -9,7 +9,7 @@ module Chouette
include ObjectidSupport
extend Enumerize
- enumerize :area_type, in: %i(zdep zder zdlp zdlr lda)
+ enumerize :area_type, in: Chouette::AreaType::ALL
with_options dependent: :destroy do |assoc|
assoc.has_many :stop_points
@@ -39,11 +39,21 @@ module Chouette
validates_format_of :coordinates, :with => %r{\A *-?(0?[0-9](\.[0-9]*)?|[0-8][0-9](\.[0-9]*)?|90(\.[0]*)?) *\, *-?(0?[0-9]?[0-9](\.[0-9]*)?|1[0-7][0-9](\.[0-9]*)?|180(\.[0]*)?) *\Z}, :allow_nil => true, :allow_blank => true
validates_format_of :url, :with => %r{\Ahttps?:\/\/([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?\Z}, :allow_nil => true, :allow_blank => true
+ validates_numericality_of :waiting_time, greater_than_or_equal_to: 0, only_integer: true, if: :waiting_time
+ validate :parent_area_type_must_be_greater
+
def self.nullable_attributes
[:registration_number, :street_name, :country_code, :fare_code,
:nearest_topic_name, :comment, :long_lat_type, :zip_code, :city_name, :url, :time_zone]
end
+ def parent_area_type_must_be_greater
+ return unless self.parent
+ if Chouette::AreaType.find(self.area_type) >= Chouette::AreaType.find(self.parent.area_type)
+ errors.add(:parent_id, I18n.t('stop_areas.errors.parent_area_type', area_type: self.parent.area_type))
+ end
+ end
+
after_update :clean_invalid_access_links
before_save :coordinates_to_lat_lng
@@ -72,6 +82,10 @@ module Chouette
end
end
+ def full_name
+ "#{name} #{zip_code} #{city_name} - #{user_objectid}"
+ end
+
def user_objectid
if objectid =~ /^.*:([0-9A-Za-z_-]+):STIF$/
$1
@@ -196,10 +210,12 @@ module Chouette
GeoRuby::SimpleFeatures::Envelope.from_coordinates coordinates
end
+ # DEPRECATED use StopArea#area_type
def stop_area_type
area_type ? area_type : " "
end
+ # DEPRECATED use StopArea#area_type
def stop_area_type=(stop_area_type)
self.area_type = (stop_area_type ? stop_area_type.camelcase : nil)
end
@@ -324,5 +340,20 @@ module Chouette
end
end
+ def activated?
+ deleted_at.nil?
+ end
+
+ def deactivated?
+ !activated?
+ end
+
+ def activate!
+ update_attribute :deleted_at, nil
+ end
+
+ def deactivate!
+ update_attribute :deleted_at, Time.now
+ end
end
end
diff --git a/app/models/chouette/vehicle_journey.rb b/app/models/chouette/vehicle_journey.rb
index 247c30668..983bf5363 100644
--- a/app/models/chouette/vehicle_journey.rb
+++ b/app/models/chouette/vehicle_journey.rb
@@ -1,3 +1,4 @@
+# coding: utf-8
module Chouette
class VehicleJourney < Chouette::TridentActiveRecord
has_paper_trail
@@ -23,6 +24,7 @@ module Chouette
belongs_to :journey_pattern
has_and_belongs_to_many :footnotes, :class_name => 'Chouette::Footnote'
+ has_and_belongs_to_many :purchase_windows, :class_name => 'Chouette::PurchaseWindow'
validates_presence_of :route
validates_presence_of :journey_pattern
@@ -139,7 +141,7 @@ module Chouette
end
def update_has_and_belongs_to_many_from_state item
- ['time_tables', 'footnotes'].each do |assos|
+ ['time_tables', 'footnotes', 'purchase_windows'].each do |assos|
saved = self.send(assos).map(&:id)
(saved - item[assos].map{|t| t['id']}).each do |id|
@@ -241,11 +243,9 @@ module Chouette
end
def self.matrix(vehicle_journeys)
- {}.tap do |hash|
- vehicle_journeys.map{ |vj|
- vj.vehicle_journey_at_stops.map{ |vjas |hash[ "#{vj.id}-#{vjas.stop_point_id}"] = vjas }
- }
- end
+ Hash[*VehicleJourneyAtStop.where(vehicle_journey_id: vehicle_journeys.pluck(:id)).map do |vjas|
+ [ "#{vjas.vehicle_journey_id}-#{vjas.stop_point_id}", vjas]
+ end.flatten]
end
def self.with_stops
diff --git a/app/models/chouette/vehicle_journey_at_stop.rb b/app/models/chouette/vehicle_journey_at_stop.rb
index 6f0119e74..6b3c1e7de 100644
--- a/app/models/chouette/vehicle_journey_at_stop.rb
+++ b/app/models/chouette/vehicle_journey_at_stop.rb
@@ -75,5 +75,14 @@ module Chouette
attrs << self.arrival_day_offset.to_s
end
end
+
+ def departure
+ departure_time.utc.strftime "%H:%M" if departure_time
+ end
+
+ def arrival
+ arrival_time.utc.strftime "%H:%M" if arrival_time
+ end
+
end
-end \ No newline at end of file
+end
diff --git a/app/models/compliance_check_block.rb b/app/models/compliance_check_block.rb
index 05240b428..059547e1b 100644
--- a/app/models/compliance_check_block.rb
+++ b/app/models/compliance_check_block.rb
@@ -6,8 +6,8 @@ class ComplianceCheckBlock < ActiveRecord::Base
has_many :compliance_checks
- hstore_accessor :condition_attributes,
- transport_mode: :string,
- transport_submode: :string
+ store_accessor :condition_attributes,
+ :transport_mode,
+ :transport_submode
end
diff --git a/app/models/compliance_control.rb b/app/models/compliance_control.rb
index 65e22643d..2bde5b95a 100644
--- a/app/models/compliance_control.rb
+++ b/app/models/compliance_control.rb
@@ -6,7 +6,7 @@ class ComplianceControl < ActiveRecord::Base
def prerequisite; I18n.t('compliance_controls.metas.no_prerequisite'); end
def predicate; I18n.t("compliance_controls.#{self.name.underscore}.description") end
def dynamic_attributes
- hstore_metadata_for_control_attributes.keys
+ stored_attributes[:control_attributes] || []
end
def policy_class
@@ -39,7 +39,6 @@ class ComplianceControl < ActiveRecord::Base
belongs_to :compliance_control_block
enumerize :criticity, in: criticities, scope: true, default: :warning
- hstore_accessor :control_attributes, {}
validates :criticity, presence: true
validates :name, presence: true
diff --git a/app/models/compliance_control_block.rb b/app/models/compliance_control_block.rb
index cfcdfd1a6..d7d84fd06 100644
--- a/app/models/compliance_control_block.rb
+++ b/app/models/compliance_control_block.rb
@@ -5,11 +5,15 @@ class ComplianceControlBlock < ActiveRecord::Base
belongs_to :compliance_control_set
has_many :compliance_controls, dependent: :destroy
- hstore_accessor :condition_attributes,
- transport_mode: :string,
- transport_submode: :string
+ store_accessor :condition_attributes,
+ :transport_mode,
+ :transport_submode
validates :transport_mode, presence: true
validates :compliance_control_set, presence: true
+ def name
+ ApplicationController.helpers.transport_mode_text(self)
+ end
+
end
diff --git a/app/models/concerns/date_support.rb b/app/models/concerns/date_support.rb
new file mode 100644
index 000000000..fbfe19af1
--- /dev/null
+++ b/app/models/concerns/date_support.rb
@@ -0,0 +1,80 @@
+module DateSupport
+ extend ActiveSupport::Concern
+
+ included do
+ after_initialize :init_dates
+
+ def init_dates
+ self.dates ||= []
+ end
+
+ ### Calendar::DateValue
+ # Required by coocon
+ def build_date_value
+ Calendar::DateValue.new
+ end
+
+ def date_values
+ @date_values ||= init_date_values
+ end
+
+ def init_date_values
+ if dates
+ dates.each_with_index.map { |d, index| Calendar::DateValue.from_date(index, d) }
+ else
+ []
+ end
+ end
+ private :init_date_values
+
+ validate :validate_date_values
+
+ def validate_date_values
+ date_values_are_valid = date_values.all?(&:valid?)
+
+ date_values.each do |date_value|
+ if date_values.count { |d| d.value == date_value.value } > 1
+ date_value.errors.add(:base, I18n.t('activerecord.errors.models.calendar.attributes.dates.date_in_dates'))
+ date_values_are_valid = false
+ end
+ date_ranges.each do |date_range|
+ if date_range.cover? date_value.value
+ date_value.errors.add(:base, I18n.t('activerecord.errors.models.calendar.attributes.dates.date_in_date_ranges'))
+ date_values_are_valid = false
+ end
+ end
+ end
+
+ unless date_values_are_valid
+ errors.add(:date_values, :invalid)
+ end
+ end
+
+ def date_values_attributes=(attributes = {})
+ @date_values = []
+ attributes.each do |index, date_value_attribute|
+ date_value_attribute['value'] = flatten_date_array(date_value_attribute, 'value')
+ date_value = Calendar::DateValue.new(date_value_attribute.merge(id: index))
+ @date_values << date_value unless date_value.marked_for_destruction?
+ end
+
+ dates_will_change!
+ end
+
+ before_validation :fill_dates
+
+ def fill_dates
+ if @date_values
+ self.dates = @date_values.map(&:value).compact.sort
+ end
+ end
+
+ after_save :clear_date_values
+
+ def clear_date_values
+ @date_values = nil
+ end
+
+ private :clear_date_values
+ end
+end \ No newline at end of file
diff --git a/app/models/concerns/period_support.rb b/app/models/concerns/period_support.rb
new file mode 100644
index 000000000..e17451fe4
--- /dev/null
+++ b/app/models/concerns/period_support.rb
@@ -0,0 +1,80 @@
+module PeriodSupport
+ extend ActiveSupport::Concern
+
+ included do
+ after_initialize :init_date_ranges
+
+ def init_date_ranges
+ self.date_ranges ||= []
+ end
+
+ ### Calendar::Period
+ # Required by coocon
+ def build_period
+ Calendar::Period.new
+ end
+
+ def periods
+ @periods ||= init_periods
+ end
+
+ def init_periods
+ (date_ranges || [])
+ .each_with_index
+ .map( &Calendar::Period.method(:from_range) )
+ end
+ private :init_periods
+
+ validate :validate_periods
+
+ def validate_periods
+ periods_are_valid = periods.all?(&:valid?)
+
+ periods.each do |period|
+ if period.intersect?(periods)
+ period.errors.add(:base, I18n.t('calendars.errors.overlapped_periods'))
+ periods_are_valid = false
+ end
+ end
+
+ unless periods_are_valid
+ errors.add(:periods, :invalid)
+ end
+ end
+
+ def flatten_date_array attributes, key
+ date_int = %w(1 2 3).map {|e| attributes["#{key}(#{e}i)"].to_i }
+ Date.new(*date_int)
+ end
+
+ def periods_attributes=(attributes = {})
+ @periods = []
+ attributes.each do |index, period_attribute|
+ # Convert date_select to date
+ ['begin', 'end'].map do |attr|
+ period_attribute[attr] = flatten_date_array(period_attribute, attr)
+ end
+ period = Calendar::Period.new(period_attribute.merge(id: index))
+ @periods << period unless period.marked_for_destruction?
+ end
+
+ date_ranges_will_change!
+ end
+
+ before_validation :fill_date_ranges
+
+ def fill_date_ranges
+ if @periods
+ self.date_ranges = @periods.map(&:range).compact.sort_by(&:begin)
+ end
+ end
+
+ after_save :clear_periods
+
+ def clear_periods
+ @periods = nil
+ end
+
+ private :clear_periods
+ end
+end
diff --git a/app/models/generic_attribute_control/min_max.rb b/app/models/generic_attribute_control/min_max.rb
index ab6f546a7..1c429b9a4 100644
--- a/app/models/generic_attribute_control/min_max.rb
+++ b/app/models/generic_attribute_control/min_max.rb
@@ -1,6 +1,6 @@
module GenericAttributeControl
class MinMax < ComplianceControl
- hstore_accessor :control_attributes, minimum: :integer, maximum: :integer, target: :string
+ store_accessor :control_attributes, :minimum, :maximum, :target
validates :minimum, numericality: true, allow_nil: true
validates :maximum, numericality: true, allow_nil: true
diff --git a/app/models/generic_attribute_control/pattern.rb b/app/models/generic_attribute_control/pattern.rb
index 3a4a55d5c..7fc008e28 100644
--- a/app/models/generic_attribute_control/pattern.rb
+++ b/app/models/generic_attribute_control/pattern.rb
@@ -1,6 +1,6 @@
module GenericAttributeControl
class Pattern < ComplianceControl
- hstore_accessor :control_attributes, pattern: :string, target: :string
+ store_accessor :control_attributes, :pattern, :target
validates :target, presence: true
validates :pattern, presence: true
diff --git a/app/models/generic_attribute_control/uniqueness.rb b/app/models/generic_attribute_control/uniqueness.rb
index f707c944b..82b5c0892 100644
--- a/app/models/generic_attribute_control/uniqueness.rb
+++ b/app/models/generic_attribute_control/uniqueness.rb
@@ -1,6 +1,6 @@
module GenericAttributeControl
class Uniqueness < ComplianceControl
- hstore_accessor :control_attributes, target: :string
+ store_accessor :control_attributes, :target
validates :target, presence: true
diff --git a/app/models/import.rb b/app/models/import.rb
index 20e7f2d8a..049a65f40 100644
--- a/app/models/import.rb
+++ b/app/models/import.rb
@@ -14,12 +14,11 @@ class Import < ActiveRecord::Base
end
extend Enumerize
- enumerize :status, in: %i(new pending successful warning failed running aborted canceled), scope: true, default: :new
+ enumerize :status, in: %w(new pending successful warning failed running aborted canceled), scope: true, default: :new
validates :name, presence: true
validates :file, presence: true
validates_presence_of :workbench, :creator
- validates_format_of :file, with: %r{\.zip\z}i, message: I18n.t('activerecord.errors.models.import.attributes.file.wrong_file_extension')
before_create :initialize_fields
@@ -28,15 +27,19 @@ class Import < ActiveRecord::Base
end
def children_succeedeed
- children.with_status(:successful).count
+ children.with_status(:successful, :warning).count
end
- def self.failing_statuses
- symbols_with_indifferent_access(%i(failed aborted canceled))
+ def self.launched_statuses
+ %w(new pending)
+ end
+
+ def self.failed_statuses
+ %w(failed aborted canceled)
end
def self.finished_statuses
- symbols_with_indifferent_access(%i(successful failed warning aborted canceled))
+ %w(successful failed warning aborted canceled)
end
def notify_parent
@@ -52,35 +55,25 @@ class Import < ActiveRecord::Base
end
def update_status
- status_count = children.group(:status).count
- children_finished_count = children_failed_count = children_count = 0
-
- status_count.each do |status, count|
- if self.class.failing_statuses.include?(status)
- children_failed_count += count
- end
- if self.class.finished_statuses.include?(status)
- children_finished_count += count
- end
- children_count += count
- end
-
- attributes = {
- current_step: children_finished_count
- }
-
status =
- if children_failed_count > 0
+ if children.where(status: self.class.failed_statuses).count > 0
'failed'
- elsif status_count['successful'] == children_count
+ elsif children.where(status: "warning").count > 0
+ 'warning'
+ elsif children.where(status: "successful").count == children.count
'successful'
end
+ attributes = {
+ current_step: children.count,
+ status: status
+ }
+
if self.class.finished_statuses.include?(status)
attributes[:ended_at] = Time.now
end
- update attributes.merge(status: status)
+ update attributes
end
def update_referentials
@@ -97,7 +90,4 @@ class Import < ActiveRecord::Base
self.token_download = SecureRandom.urlsafe_base64
end
- def self.symbols_with_indifferent_access(array)
- array.flat_map { |symbol| [symbol, symbol.to_s] }
- end
end
diff --git a/app/models/organisation.rb b/app/models/organisation.rb
index f6fba2d67..da7d1fcf3 100644
--- a/app/models/organisation.rb
+++ b/app/models/organisation.rb
@@ -1,3 +1,4 @@
+# coding: utf-8
class Organisation < ActiveRecord::Base
include DataFormatEnumerations
@@ -18,36 +19,39 @@ class Organisation < ActiveRecord::Base
validates_presence_of :name
validates_uniqueness_of :code
- def self.portail_api_request
- conf = Rails.application.config.try(:stif_portail_api)
- raise 'Rails.application.config.stif_portail_api configuration is not defined' unless conf
+ class << self
- HTTPService.get_json_resource(
- host: conf[:url],
- path: '/api/v1/organizations',
- token: conf[:key])
- end
+ def portail_api_request
+ conf = Rails.application.config.try(:stif_portail_api)
+ raise 'Rails.application.config.stif_portail_api configuration is not defined' unless conf
+
+ HTTPService.get_json_resource(
+ host: conf[:url],
+ path: '/api/v1/organizations',
+ token: conf[:key])
+ end
- def self.sync_update code, name, scope
- org = Organisation.find_or_initialize_by(code: code)
- if scope
- org.sso_attributes ||= {}
- if org.sso_attributes['functional_scope'] != scope
- org.sso_attributes['functional_scope'] = scope
- # FIXME see #1941
- org.sso_attributes_will_change!
+ def sync_update code, name, scope
+ org = Organisation.find_or_initialize_by(code: code)
+ if scope
+ org.sso_attributes ||= {}
+ if org.sso_attributes['functional_scope'] != scope
+ org.sso_attributes['functional_scope'] = scope
+ # FIXME see #1941
+ org.sso_attributes_will_change!
+ end
end
+ org.name = name
+ org.synced_at = Time.now
+ org.save
+ org
end
- org.name = name
- org.synced_at = Time.now
- org.save
- org
- end
- def self.portail_sync
- self.portail_api_request.each do |el|
- org = self.sync_update el['code'], el['name'], el['functional_scope']
- puts "✓ Organisation #{org.name} has been updated" unless Rails.env.test?
+ def portail_sync
+ portail_api_request.each do |el|
+ org = self.sync_update el['code'], el['name'], el['functional_scope']
+ puts "✓ Organisation #{org.name} has been updated" unless Rails.env.test?
+ end
end
end
@@ -64,4 +68,16 @@ class Organisation < ActiveRecord::Base
raise ActiveRecord::RecordNotFound
end
+ def functional_scope
+ JSON.parse( (sso_attributes || {}).fetch('functional_scope', '[]') )
+ end
+
+ def lines_set
+ STIF::CodifligneLineId.lines_set_from_functional_scope( functional_scope )
+ end
+
+ def has_feature?(feature)
+ features && features.include?(feature.to_s)
+ end
+
end
diff --git a/app/models/referential.rb b/app/models/referential.rb
index 3a9ef2027..1cdda9e6a 100644
--- a/app/models/referential.rb
+++ b/app/models/referential.rb
@@ -1,3 +1,4 @@
+# coding: utf-8
class Referential < ActiveRecord::Base
include DataFormatEnumerations
include ObjectidFormatterSupport
@@ -34,7 +35,7 @@ class Referential < ActiveRecord::Base
I18n.t('referentials.errors.inconsistent_organisation',
indirect_name: workbench.organisation.name,
direct_name: organisation.name))
- end
+ end, if: :organisation
belongs_to :line_referential
validates_presence_of :line_referential
@@ -139,6 +140,10 @@ class Referential < ActiveRecord::Base
Chouette::RoutingConstraintZone.all
end
+ def purchase_windows
+ Chouette::PurchaseWindow.all
+ end
+
before_validation :define_default_attributes
def define_default_attributes
@@ -295,7 +300,8 @@ class Referential < ActiveRecord::Base
def detect_overlapped_referentials
self.class.where(id: overlapped_referential_ids).each do |referential|
- errors.add :metadatas, I18n.t("referentials.errors.overlapped_referential", referential: referential.name)
+ Rails.logger.info "Referential #{referential.id} #{referential.metadatas.inspect} overlaps #{metadatas.inspect}"
+ errors.add :metadatas, I18n.t("referentials.errors.overlapped_referential", :referential => referential.name)
end
end
@@ -315,11 +321,11 @@ class Referential < ActiveRecord::Base
end
def assign_slug
- self.slug ||= "#{self.name.parameterize.gsub('-', '_')}_#{Time.now.to_i}"
+ self.slug ||= "#{name.parameterize.gsub('-', '_')}_#{Time.now.to_i}" if name
end
def assign_prefix
- self.prefix = organisation.name.parameterize.gsub('-', '_')
+ self.prefix = organisation.name.parameterize.gsub('-', '_') if organisation
end
def assign_line_and_stop_area_referential
diff --git a/app/models/referential_cloning.rb b/app/models/referential_cloning.rb
index 5bf283814..24117e6c8 100644
--- a/app/models/referential_cloning.rb
+++ b/app/models/referential_cloning.rb
@@ -2,14 +2,27 @@ class ReferentialCloning < ActiveRecord::Base
include AASM
belongs_to :source_referential, class_name: 'Referential'
belongs_to :target_referential, class_name: 'Referential'
- after_commit :perform_clone, :on => :create
+ after_commit :clone, on: :create
- private
- def perform_clone
+ def clone
ReferentialCloningWorker.perform_async(id)
- # ReferentialCloningWorker.new.perform(id)
end
+ def clone!
+ run!
+
+ AF83::SchemaCloner
+ .new(source_referential.slug, target_referential.slug)
+ .clone_schema
+
+ successful!
+ rescue Exception => e
+ Rails.logger.error "Clone failed : #{e}"
+ failed!
+ end
+
+ private
+
aasm column: :status do
state :new, :initial => true
state :pending
diff --git a/app/models/user.rb b/app/models/user.rb
index 37d35209a..1342f60ed 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -36,7 +36,7 @@ class User < ActiveRecord::Base
self.name = extra[:full_name]
self.email = extra[:email]
self.organisation = Organisation.sync_update extra[:organisation_code], extra[:organisation_name], extra[:functional_scope]
- self.permissions = Stif::PermissionTranslator.translate(extra[:permissions])
+ self.permissions = Stif::PermissionTranslator.translate(extra[:permissions], self.organisation)
end
def self.portail_api_request
diff --git a/app/models/vehicle_journey_control/delta.rb b/app/models/vehicle_journey_control/delta.rb
index 1f3a4d492..077dd6c4a 100644
--- a/app/models/vehicle_journey_control/delta.rb
+++ b/app/models/vehicle_journey_control/delta.rb
@@ -1,7 +1,7 @@
module VehicleJourneyControl
class Delta < ComplianceControl
- hstore_accessor :control_attributes, maximum: :integer
+ store_accessor :control_attributes, :maximum
validates :maximum, numericality: true, allow_nil: true
diff --git a/app/models/vehicle_journey_control/speed.rb b/app/models/vehicle_journey_control/speed.rb
index be9f838e4..14fad9139 100644
--- a/app/models/vehicle_journey_control/speed.rb
+++ b/app/models/vehicle_journey_control/speed.rb
@@ -1,6 +1,6 @@
module VehicleJourneyControl
class Speed < ComplianceControl
- hstore_accessor :control_attributes, minimum: :integer, maximum: :integer
+ store_accessor :control_attributes, :minimum, :maximum
validates :minimum, numericality: true, allow_nil: true
validates :maximum, numericality: true, allow_nil: true
diff --git a/app/models/vehicle_journey_control/waiting_time.rb b/app/models/vehicle_journey_control/waiting_time.rb
index 68fccb5c1..f2666cb72 100644
--- a/app/models/vehicle_journey_control/waiting_time.rb
+++ b/app/models/vehicle_journey_control/waiting_time.rb
@@ -1,8 +1,8 @@
module VehicleJourneyControl
class WaitingTime < ComplianceControl
- hstore_accessor :control_attributes, maximum: :integer
+ store_accessor :control_attributes, :maximum
- validates :maximum, numericality: true, allow_nil: true
+ validates_numericality_of :maximum, allow_nil: true, greater_than_or_equal_to: 0
def self.default_code; "3-VehicleJourney-1" end
end