diff options
Diffstat (limited to 'app/models')
58 files changed, 2281 insertions, 1991 deletions
diff --git a/app/models/chouette.rb b/app/models/chouette.rb new file mode 100644 index 000000000..fe49300d4 --- /dev/null +++ b/app/models/chouette.rb @@ -0,0 +1,5 @@ +module Chouette + def self.use_relative_model_naming? + true + end +end
\ No newline at end of file diff --git a/app/models/chouette/access_link.rb b/app/models/chouette/access_link.rb index b43dcfb7f..46fbcb631 100644 --- a/app/models/chouette/access_link.rb +++ b/app/models/chouette/access_link.rb @@ -1,5 +1,6 @@ module Chouette - class AccessLink < TridentActiveRecord + class AccessLink < Chouette::TridentActiveRecord + include ObjectidSupport # FIXME http://jira.codehaus.org/browse/JRUBY-6358 self.primary_key = "id" @@ -62,4 +63,4 @@ module Chouette Chouette::Geometry::AccessLinkPresenter.new self end end -end +end
\ No newline at end of file diff --git a/app/models/chouette/access_point.rb b/app/models/chouette/access_point.rb index 4a1ae8a0e..7757fdcfb 100644 --- a/app/models/chouette/access_point.rb +++ b/app/models/chouette/access_point.rb @@ -1,173 +1,170 @@ require 'geokit' require 'geo_ruby' -class Chouette::AccessPoint < Chouette::ActiveRecord - # FIXME http://jira.codehaus.org/browse/JRUBY-6358 - self.primary_key = "id" +module Chouette + class AccessPoint < Chouette::ActiveRecord + # FIXME http://jira.codehaus.org/browse/JRUBY-6358 + self.primary_key = "id" - include StifReflexAttributesSupport - include Geokit::Mappable - include ProjectionFields + include Geokit::Mappable + include ProjectionFields + include ObjectidSupport - has_many :access_links, :dependent => :destroy - belongs_to :stop_area + has_many :access_links, :dependent => :destroy + belongs_to :stop_area - attr_accessor :access_point_type - attr_writer :coordinates + attr_accessor :access_point_type + attr_writer :coordinates - validates_presence_of :name - validates_presence_of :access_type + validates_presence_of :name + validates_presence_of :access_type - validates_presence_of :latitude, :if => :longitude - validates_presence_of :longitude, :if => :latitude - validates_numericality_of :latitude, :less_than_or_equal_to => 90, :greater_than_or_equal_to => -90, :allow_nil => true - validates_numericality_of :longitude, :less_than_or_equal_to => 180, :greater_than_or_equal_to => -180, :allow_nil => true + validates_presence_of :latitude, :if => :longitude + validates_presence_of :longitude, :if => :latitude + validates_numericality_of :latitude, :less_than_or_equal_to => 90, :greater_than_or_equal_to => -90, :allow_nil => true + validates_numericality_of :longitude, :less_than_or_equal_to => 180, :greater_than_or_equal_to => -180, :allow_nil => true - validates_format_of :coordinates, :with => %r{\A *-?(0?[0-9](\.[0-9]*)?|[0-8][0-9](\.[0-9]*)?|90(\.[0]*)?) *\, *-?(0?[0-9]?[0-9](\.[0-9]*)?|1[0-7][0-9](\.[0-9]*)?|180(\.[0]*)?) *\Z}, :allow_nil => true, :allow_blank => true - before_save :coordinates_to_lat_lng - def self.nullable_attributes - [:street_name, :country_code, :comment, :long_lat_type, :zip_code, :city_name] - end - - - def referential - @referential ||= Referential.where(:slug => Apartment::Tenant.current).first! - end + validates_format_of :coordinates, :with => %r{\A *-?(0?[0-9](\.[0-9]*)?|[0-8][0-9](\.[0-9]*)?|90(\.[0]*)?) *\, *-?(0?[0-9]?[0-9](\.[0-9]*)?|1[0-7][0-9](\.[0-9]*)?|180(\.[0]*)?) *\Z}, :allow_nil => true, :allow_blank => true + before_save :coordinates_to_lat_lng + def self.nullable_attributes + [:street_name, :country_code, :comment, :long_lat_type, :zip_code, :city_name] + end - def referential - @referential ||= Referential.where(:slug => Apartment::Tenant.current).first! - end + def referential + @referential ||= Referential.where(:slug => Apartment::Tenant.current).first! + end - def combine_lat_lng - if self.latitude.nil? || self.longitude.nil? - "" - else - self.latitude.to_s+","+self.longitude.to_s + def combine_lat_lng + if self.latitude.nil? || self.longitude.nil? + "" + else + self.latitude.to_s+","+self.longitude.to_s + end end - end - def coordinates - @coordinates || combine_lat_lng - end + def coordinates + @coordinates || combine_lat_lng + end - def coordinates_to_lat_lng - if ! @coordinates.nil? - if @coordinates.empty? - self.latitude = nil - self.longitude = nil - else - self.latitude = BigDecimal.new(@coordinates.split(",").first) - self.longitude = BigDecimal.new(@coordinates.split(",").last) + def coordinates_to_lat_lng + if ! @coordinates.nil? + if @coordinates.empty? + self.latitude = nil + self.longitude = nil + else + self.latitude = BigDecimal.new(@coordinates.split(",").first) + self.longitude = BigDecimal.new(@coordinates.split(",").last) + end + @coordinates = nil end - @coordinates = nil end - end - def to_lat_lng - Geokit::LatLng.new(latitude, longitude) if latitude and longitude - end + def to_lat_lng + Geokit::LatLng.new(latitude, longitude) if latitude and longitude + end - def geometry - GeoRuby::SimpleFeatures::Point.from_lon_lat(longitude, latitude, 4326) if latitude and longitude - end + def geometry + GeoRuby::SimpleFeatures::Point.from_lon_lat(longitude, latitude, 4326) if latitude and longitude + end - def geometry=(geometry) - geometry = geometry.to_wgs84 - self.latitude, self.longitude, self.long_lat_type = geometry.lat, geometry.lng, "WGS84" - end + def geometry=(geometry) + geometry = geometry.to_wgs84 + self.latitude, self.longitude, self.long_lat_type = geometry.lat, geometry.lng, "WGS84" + end - def position - geometry - end + def position + geometry + end - def position=(position) - position = nil if String === position && position == "" - position = Geokit::LatLng.normalize(position), 4326 if String === position - self.latitude = position.lat - self.longitude = position.lng - end + def position=(position) + position = nil if String === position && position == "" + position = Geokit::LatLng.normalize(position), 4326 if String === position + self.latitude = position.lat + self.longitude = position.lng + end - def default_position - stop_area.geometry or stop_area.default_position - end + def default_position + stop_area.geometry or stop_area.default_position + end - def access_point_type - access_type && Chouette::AccessPointType.new(access_type.underscore) - end + def access_point_type + access_type && Chouette::AccessPointType.new(access_type.underscore) + end - def access_point_type=(access_point_type) - self.access_type = (access_point_type ? access_point_type.camelcase : nil) - end + def access_point_type=(access_point_type) + self.access_type = (access_point_type ? access_point_type.camelcase : nil) + end - @@access_point_types = nil - def self.access_point_types - @@access_point_types ||= Chouette::AccessPointType.all.select do |access_point_type| - access_point_type.to_i >= 0 + @@access_point_types = nil + def self.access_point_types + @@access_point_types ||= Chouette::AccessPointType.all.select do |access_point_type| + access_point_type.to_i >= 0 + end end - end - def generic_access_link_matrix - matrix = Array.new - hash = Hash.new - access_links.each do |link| - hash[link.link_key] = link - end - key=Chouette::AccessLink.build_link_key(self,stop_area,"access_point_to_stop_area") - if hash.has_key?(key) - matrix << hash[key] - else - link = Chouette::AccessLink.new - link.access_point = self - link.stop_area = stop_area - link.link_orientation_type = "access_point_to_stop_area" - matrix << link - end - key=Chouette::AccessLink.build_link_key(self,stop_area,"stop_area_to_access_point") - if hash.has_key?(key) - matrix << hash[key] - else - link = Chouette::AccessLink.new - link.access_point = self - link.stop_area = stop_area - link.link_orientation_type = "stop_area_to_access_point" - matrix << link - end - matrix - end + def generic_access_link_matrix + matrix = Array.new + hash = Hash.new + access_links.each do |link| + hash[link.link_key] = link + end + key=Chouette::AccessLink.build_link_key(self,stop_area,"access_point_to_stop_area") + if hash.has_key?(key) + matrix << hash[key] + else + link = Chouette::AccessLink.new + link.access_point = self + link.stop_area = stop_area + link.link_orientation_type = "access_point_to_stop_area" + matrix << link + end + key=Chouette::AccessLink.build_link_key(self,stop_area,"stop_area_to_access_point") + if hash.has_key?(key) + matrix << hash[key] + else + link = Chouette::AccessLink.new + link.access_point = self + link.stop_area = stop_area + link.link_orientation_type = "stop_area_to_access_point" + matrix << link + end + matrix + end - def detail_access_link_matrix - matrix = Array.new - hash = Hash.new - access_links.each do |link| - hash[link.link_key] = link - end - stop_area.children_at_base.each do |child| - key=Chouette::AccessLink.build_link_key(self,child,"access_point_to_stop_area") - if hash.has_key?(key) - matrix << hash[key] - else - link = Chouette::AccessLink.new - link.access_point = self - link.stop_area = child - link.link_orientation_type = "access_point_to_stop_area" - matrix << link - end - key=Chouette::AccessLink.build_link_key(self,child,"stop_area_to_access_point") - if hash.has_key?(key) - matrix << hash[key] - else - link = Chouette::AccessLink.new - link.access_point = self - link.stop_area = child - link.link_orientation_type = "stop_area_to_access_point" - matrix << link - end - end - matrix - end + def detail_access_link_matrix + matrix = Array.new + hash = Hash.new + access_links.each do |link| + hash[link.link_key] = link + end + stop_area.children_at_base.each do |child| + key=Chouette::AccessLink.build_link_key(self,child,"access_point_to_stop_area") + if hash.has_key?(key) + matrix << hash[key] + else + link = Chouette::AccessLink.new + link.access_point = self + link.stop_area = child + link.link_orientation_type = "access_point_to_stop_area" + matrix << link + end + key=Chouette::AccessLink.build_link_key(self,child,"stop_area_to_access_point") + if hash.has_key?(key) + matrix << hash[key] + else + link = Chouette::AccessLink.new + link.access_point = self + link.stop_area = child + link.link_orientation_type = "stop_area_to_access_point" + matrix << link + end + end + matrix + end - def geometry_presenter - Chouette::Geometry::AccessPointPresenter.new self + def geometry_presenter + Chouette::Geometry::AccessPointPresenter.new self + end end -end +end
\ No newline at end of file diff --git a/app/models/chouette/access_point_type.rb b/app/models/chouette/access_point_type.rb index 94d28e5ae..f7439a428 100644 --- a/app/models/chouette/access_point_type.rb +++ b/app/models/chouette/access_point_type.rb @@ -1,50 +1,52 @@ -class Chouette::AccessPointType < ActiveSupport::StringInquirer +module Chouette + class AccessPointType < ActiveSupport::StringInquirer - def initialize(text_code, numerical_code) - super text_code.to_s - @numerical_code = numerical_code - end + def initialize(text_code, numerical_code) + super text_code.to_s + @numerical_code = numerical_code + end - def self.new(text_code, numerical_code = nil) - if text_code and numerical_code - super - elsif self === text_code - text_code - else - if Fixnum === text_code - text_code, numerical_code = definitions.rassoc(text_code) + def self.new(text_code, numerical_code = nil) + if text_code and numerical_code + super + elsif self === text_code + text_code else - text_code, numerical_code = definitions.assoc(text_code.to_s) - end + if Fixnum === text_code + text_code, numerical_code = definitions.rassoc(text_code) + else + text_code, numerical_code = definitions.assoc(text_code.to_s) + end - super text_code, numerical_code + super text_code, numerical_code + end end - end - def to_i - @numerical_code - end + def to_i + @numerical_code + end - def inspect - "#{to_s}/#{to_i}" - end + def inspect + "#{to_s}/#{to_i}" + end - def name - camelize - end + def name + camelize + end - @@definitions = [ - ["in", 0], - ["out", 1], - ["in_out", 2] - ] - cattr_reader :definitions - - @@all = nil - def self.all - @@all ||= definitions.collect do |text_code, numerical_code| - new(text_code, numerical_code) + @@definitions = [ + ["in", 0], + ["out", 1], + ["in_out", 2] + ] + cattr_reader :definitions + + @@all = nil + def self.all + @@all ||= definitions.collect do |text_code, numerical_code| + new(text_code, numerical_code) + end end - end -end + end +end
\ No newline at end of file diff --git a/app/models/chouette/active_record.rb b/app/models/chouette/active_record.rb index e12f30266..c2aab9d50 100644 --- a/app/models/chouette/active_record.rb +++ b/app/models/chouette/active_record.rb @@ -24,6 +24,10 @@ module Chouette end end + def self.model_name + ActiveModel::Name.new self, Chouette, self.name.demodulize + end + # TODO: Can we remove this? # class << self # alias_method :create_reflection_without_chouette_naming, :create_reflection diff --git a/app/models/chouette/command.rb b/app/models/chouette/command.rb index d2995a000..b735747bf 100644 --- a/app/models/chouette/command.rb +++ b/app/models/chouette/command.rb @@ -10,85 +10,85 @@ require 'tmpdir' end #end -class Chouette::Command +module Chouette + class Command - include Chouette::CommandLineSupport + include Chouette::CommandLineSupport - @@command = "chouette" - cattr_accessor :command + @@command = "chouette" + cattr_accessor :command - attr_accessor :database, :schema, :host, :user, :password, :port + attr_accessor :database, :schema, :host, :user, :password, :port - def initialize(options = {}) - database_options_from_active_record.merge(options).each do |k,v| - send "#{k}=", v + def initialize(options = {}) + database_options_from_active_record.merge(options).each do |k,v| + send "#{k}=", v + end end - end - def database_options_from_active_record - config = Chouette::ActiveRecord.connection_pool.spec.config - { - :database => config[:database], - :user => config[:username], - :password => config[:password], - :port => config[:port], - :host => (config[:host] or "localhost") - } - end + def database_options_from_active_record + config = Chouette::ActiveRecord.connection_pool.spec.config + { + :database => config[:database], + :user => config[:username], + :password => config[:password], + :port => config[:port], + :host => (config[:host] or "localhost") + } + end - def run!(options = {}) - Dir.mktmpdir do |config_dir| - chouette_properties = File.join(config_dir, "chouette.properties") - open(chouette_properties, "w") do |f| - f.puts "database.name = #{database}" - f.puts "database.schema = #{schema}" - #f.puts "database.showsql = true" - f.puts "hibernate.username = #{user}" - f.puts "hibernate.password = #{password}" - f.puts "jdbc.url=jdbc:postgresql://#{host}:#{port}/#{database}" - f.puts "jdbc.username = #{user}" - f.puts "jdbc.password = #{password}" - #f.puts "database.hbm2ddl.auto=update" - end + def run!(options = {}) + Dir.mktmpdir do |config_dir| + chouette_properties = File.join(config_dir, "chouette.properties") + open(chouette_properties, "w") do |f| + f.puts "database.name = #{database}" + f.puts "database.schema = #{schema}" + #f.puts "database.showsql = true" + f.puts "hibernate.username = #{user}" + f.puts "hibernate.password = #{password}" + f.puts "jdbc.url=jdbc:postgresql://#{host}:#{port}/#{database}" + f.puts "jdbc.username = #{user}" + f.puts "jdbc.password = #{password}" + #f.puts "database.hbm2ddl.auto=update" + end - logger.debug "Chouette properties: #{File.readlines(chouette_properties).collect(&:strip).join(', ')}" + logger.debug "Chouette properties: #{File.readlines(chouette_properties).collect(&:strip).join(', ')}" - command_line = "#{command} -classpath #{config_dir} #{command_options(options)}" - logger.debug "Execute '#{command_line}'" + command_line = "#{command} -classpath #{config_dir} #{command_options(options)}" + logger.debug "Execute '#{command_line}'" - execute! command_line + execute! command_line + end end - end - class Option + class Option - attr_accessor :key, :value + attr_accessor :key, :value - def initialize(key, value) - @key, @value = key.to_s, value - end + def initialize(key, value) + @key, @value = key.to_s, value + end - def command_key - key.camelize(:lower) - end + def command_key + key.camelize(:lower) + end - def to_s - unless value == true - "-#{command_key} #{value}" - else - "-#{command_key}" + def to_s + unless value == true + "-#{command_key} #{value}" + else + "-#{command_key}" + end end + end - end + def command_options(options) + options.collect do |key, value| + Option.new(key, value) + end.sort_by(&:key).join(' ') + end - def command_options(options) - options.collect do |key, value| - Option.new(key, value) - end.sort_by(&:key).join(' ') end - - - -end +end
\ No newline at end of file diff --git a/app/models/chouette/company.rb b/app/models/chouette/company.rb index a472020e1..a06bf5d91 100644 --- a/app/models/chouette/company.rb +++ b/app/models/chouette/company.rb @@ -1,18 +1,20 @@ -class Chouette::Company < Chouette::ActiveRecord - include CompanyRestrictions - include StifCodifligneAttributesSupport - include LineReferentialSupport +module Chouette + class Company < Chouette::ActiveRecord + include CompanyRestrictions + include LineReferentialSupport + include ObjectidSupport - has_many :lines + has_many :lines - validates_format_of :registration_number, :with => %r{\A[0-9A-Za-z_-]+\Z}, :allow_nil => true, :allow_blank => true - validates_presence_of :name - validates_format_of :url, :with => %r{\Ahttps?:\/\/([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?\Z}, :allow_nil => true, :allow_blank => true - - def self.nullable_attributes - [:organizational_unit, :operating_department_name, :code, :phone, :fax, :email, :url, :time_zone] - end + validates_format_of :registration_number, :with => %r{\A[0-9A-Za-z_-]+\Z}, :allow_nil => true, :allow_blank => true + validates_presence_of :name + validates_presence_of :objectid_format + validates_format_of :url, :with => %r{\Ahttps?:\/\/([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?\Z}, :allow_nil => true, :allow_blank => true + def self.nullable_attributes + [:organizational_unit, :operating_department_name, :code, :phone, :fax, :email, :url, :time_zone] + end -end + end +end
\ No newline at end of file diff --git a/app/models/chouette/connection_link.rb b/app/models/chouette/connection_link.rb index e225c2fae..d19b53974 100644 --- a/app/models/chouette/connection_link.rb +++ b/app/models/chouette/connection_link.rb @@ -1,48 +1,50 @@ -class Chouette::ConnectionLink < Chouette::TridentActiveRecord - include ConnectionLinkRestrictions - # FIXME http://jira.codehaus.org/browse/JRUBY-6358 - self.primary_key = "id" +module Chouette + class ConnectionLink < Chouette::TridentActiveRecord + include ObjectidSupport + include ConnectionLinkRestrictions + # FIXME http://jira.codehaus.org/browse/JRUBY-6358 + self.primary_key = "id" - attr_accessor :connection_link_type + attr_accessor :connection_link_type - belongs_to :departure, :class_name => 'Chouette::StopArea' - belongs_to :arrival, :class_name => 'Chouette::StopArea' + belongs_to :departure, :class_name => 'Chouette::StopArea' + belongs_to :arrival, :class_name => 'Chouette::StopArea' - validates_presence_of :name + validates_presence_of :name - def self.nullable_attributes - [:link_distance, :default_duration, :frequent_traveller_duration, :occasional_traveller_duration, - :mobility_restricted_traveller_duration, :link_type] - end + def self.nullable_attributes + [:link_distance, :default_duration, :frequent_traveller_duration, :occasional_traveller_duration, + :mobility_restricted_traveller_duration, :link_type] + end - def connection_link_type - link_type && Chouette::ConnectionLinkType.new( link_type.underscore) - end + def connection_link_type + link_type && Chouette::ConnectionLinkType.new( link_type.underscore) + end - def connection_link_type=(connection_link_type) - self.link_type = (connection_link_type ? connection_link_type.camelcase : nil) - end - - @@connection_link_types = nil - def self.connection_link_types - @@connection_link_types ||= Chouette::ConnectionLinkType.all - end + def connection_link_type=(connection_link_type) + self.link_type = (connection_link_type ? connection_link_type.camelcase : nil) + end - def possible_areas - Chouette::StopArea.where("area_type != 'ITL'") - end + @@connection_link_types = nil + def self.connection_link_types + @@connection_link_types ||= Chouette::ConnectionLinkType.all + end - def stop_areas - Chouette::StopArea.where(:id => [self.departure_id,self.arrival_id]) - end + def possible_areas + Chouette::StopArea.where("area_type != 'ITL'") + end - def geometry - GeoRuby::SimpleFeatures::LineString.from_points( [ departure.geometry, arrival.geometry], 4326) if departure.geometry and arrival.geometry - end + def stop_areas + Chouette::StopArea.where(:id => [self.departure_id,self.arrival_id]) + end - def geometry_presenter - Chouette::Geometry::ConnectionLinkPresenter.new self - end + def geometry + GeoRuby::SimpleFeatures::LineString.from_points( [ departure.geometry, arrival.geometry], 4326) if departure.geometry and arrival.geometry + end -end + def geometry_presenter + Chouette::Geometry::ConnectionLinkPresenter.new self + end + end +end
\ No newline at end of file diff --git a/app/models/chouette/connection_link_type.rb b/app/models/chouette/connection_link_type.rb index 41635f48c..ca27ed5da 100644 --- a/app/models/chouette/connection_link_type.rb +++ b/app/models/chouette/connection_link_type.rb @@ -1,51 +1,52 @@ -class Chouette::ConnectionLinkType < ActiveSupport::StringInquirer +module Chouette + class ConnectionLinkType < ActiveSupport::StringInquirer - def initialize(text_code, numerical_code) - super text_code.to_s - @numerical_code = numerical_code - end + def initialize(text_code, numerical_code) + super text_code.to_s + @numerical_code = numerical_code + end - def self.new(text_code, numerical_code = nil) - if text_code and numerical_code - super - elsif self === text_code - text_code - else - if Fixnum === text_code - text_code, numerical_code = definitions.rassoc(text_code) + def self.new(text_code, numerical_code = nil) + if text_code and numerical_code + super + elsif self === text_code + text_code else - text_code, numerical_code = definitions.assoc(text_code.to_s) - end + if Fixnum === text_code + text_code, numerical_code = definitions.rassoc(text_code) + else + text_code, numerical_code = definitions.assoc(text_code.to_s) + end - super text_code, numerical_code + super text_code, numerical_code + end end - end - - def to_i - @numerical_code - end - def inspect - "#{to_s}/#{to_i}" - end + def to_i + @numerical_code + end - def name - camelize - end + def inspect + "#{to_s}/#{to_i}" + end - @@definitions = [ - ["underground", 0], - ["mixed", 1], - ["overground", 2] - ] - cattr_reader :definitions - - @@all = nil - def self.all - @@all ||= definitions.collect do |text_code, numerical_code| - new(text_code, numerical_code) + def name + camelize end - end -end + @@definitions = [ + ["underground", 0], + ["mixed", 1], + ["overground", 2] + ] + cattr_reader :definitions + + @@all = nil + def self.all + @@all ||= definitions.collect do |text_code, numerical_code| + new(text_code, numerical_code) + end + end + end +end
\ No newline at end of file diff --git a/app/models/chouette/direction.rb b/app/models/chouette/direction.rb index 93bc1318b..41d703b56 100644 --- a/app/models/chouette/direction.rb +++ b/app/models/chouette/direction.rb @@ -1,60 +1,61 @@ -class Chouette::Direction < ActiveSupport::StringInquirer +module Chouette + class Direction < ActiveSupport::StringInquirer - def initialize(text_code, numerical_code) - super text_code.to_s - @numerical_code = numerical_code - end + def initialize(text_code, numerical_code) + super text_code.to_s + @numerical_code = numerical_code + end - def self.new(text_code, numerical_code = nil) - if text_code and numerical_code - super - elsif self === text_code - text_code - else - if Fixnum === text_code - text_code, numerical_code = definitions.rassoc(text_code) + def self.new(text_code, numerical_code = nil) + if text_code and numerical_code + super + elsif self === text_code + text_code else - text_code, numerical_code = definitions.assoc(text_code.to_s) - end + if Fixnum === text_code + text_code, numerical_code = definitions.rassoc(text_code) + else + text_code, numerical_code = definitions.assoc(text_code.to_s) + end - super text_code, numerical_code + super text_code, numerical_code + end end - end - - def to_i - @numerical_code - end - def inspect - "#{to_s}/#{to_i}" - end + def to_i + @numerical_code + end - def name - to_s - end + def inspect + "#{to_s}/#{to_i}" + end - @@definitions = [ - ["straight_forward", 0], - ["backward", 1], - ["clock_wise", 2], - ["counter_clock_wise", 3], - ["north", 4], - ["north_west", 5], - ["west", 6], - ["south_west", 7], - ["south", 8], - ["south_east", 9], - ["east", 10], - ["north_east", 11] - ] - cattr_reader :definitions - - @@all = nil - def self.all - @@all ||= definitions.collect do |text_code, numerical_code| - new(text_code, numerical_code) + def name + to_s end - end -end + @@definitions = [ + ["straight_forward", 0], + ["backward", 1], + ["clock_wise", 2], + ["counter_clock_wise", 3], + ["north", 4], + ["north_west", 5], + ["west", 6], + ["south_west", 7], + ["south", 8], + ["south_east", 9], + ["east", 10], + ["north_east", 11] + ] + cattr_reader :definitions + + @@all = nil + def self.all + @@all ||= definitions.collect do |text_code, numerical_code| + new(text_code, numerical_code) + end + end + end +end
\ No newline at end of file diff --git a/app/models/chouette/exporter.rb b/app/models/chouette/exporter.rb index df85a9dde..98cab7269 100644 --- a/app/models/chouette/exporter.rb +++ b/app/models/chouette/exporter.rb @@ -1,32 +1,34 @@ -class Chouette::Exporter +module Chouette + class Exporter - attr_reader :schema + attr_reader :schema - def initialize(schema) - @schema = schema - end + def initialize(schema) + @schema = schema + end - def chouette_command - @chouette_command ||= Chouette::Command.new(:schema => schema) - end + def chouette_command + @chouette_command ||= Chouette::Command.new(:schema => schema) + end - def export(file, options = {}) - options = { - :format => :neptune - }.merge(options) - - command_options = { - :c => "export", - :o => "line", - :format => options.delete(:format).to_s.upcase, - :output_file => File.expand_path(file), - :optimize_memory => true - }.merge(options) - - logger.info "Export #{file} in schema #{schema}" - chouette_command.run! command_options - end + def export(file, options = {}) + options = { + :format => :neptune + }.merge(options) - include Chouette::CommandLineSupport + command_options = { + :c => "export", + :o => "line", + :format => options.delete(:format).to_s.upcase, + :output_file => File.expand_path(file), + :optimize_memory => true + }.merge(options) -end + logger.info "Export #{file} in schema #{schema}" + chouette_command.run! command_options + end + + include Chouette::CommandLineSupport + + end +end
\ No newline at end of file diff --git a/app/models/chouette/file_validator.rb b/app/models/chouette/file_validator.rb index 513648a62..98453c71c 100644 --- a/app/models/chouette/file_validator.rb +++ b/app/models/chouette/file_validator.rb @@ -1,47 +1,49 @@ -class Chouette::FileValidator +module Chouette + class FileValidator - attr_reader :schema, :database, :user, :password, :host + attr_reader :schema, :database, :user, :password, :host - def initialize(schema) - @schema = schema + def initialize(schema) + @schema = schema - Chouette::ActiveRecord.connection_pool.spec.config.tap do |config| - @database = config[:database] - @user = config[:username] - @password = config[:password] - @host = (config[:host] or "localhost") + Chouette::ActiveRecord.connection_pool.spec.config.tap do |config| + @database = config[:database] + @user = config[:username] + @password = config[:password] + @host = (config[:host] or "localhost") + end end - end - def self.chouette_command=(command) - Chouette::Command.command = command - end + def self.chouette_command=(command) + Chouette::Command.command = command + end - class << self - deprecate :chouette_command= => "Use Chouette::Command.command =" - end + class << self + deprecate :chouette_command= => "Use Chouette::Command.command =" + end - def chouette_command - @chouette_command ||= Chouette::Command.new(:schema => schema) - end + def chouette_command + @chouette_command ||= Chouette::Command.new(:schema => schema) + end - def validate(file, options = {}) - options = { - :format => :neptune - }.merge(options) + def validate(file, options = {}) + options = { + :format => :neptune + }.merge(options) - command_options = { - :c => "validate", - :o => "line", - :input_file => File.expand_path(file), - :optimize_memory => true - }.merge(options) + command_options = { + :c => "validate", + :o => "line", + :input_file => File.expand_path(file), + :optimize_memory => true + }.merge(options) - logger.info "Validate #{file}" - chouette_command.run! command_options - end + logger.info "Validate #{file}" + chouette_command.run! command_options + end - include Chouette::CommandLineSupport + include Chouette::CommandLineSupport -end + end +end
\ No newline at end of file diff --git a/app/models/chouette/footnote.rb b/app/models/chouette/footnote.rb index 1664faf23..051027cea 100644 --- a/app/models/chouette/footnote.rb +++ b/app/models/chouette/footnote.rb @@ -1,13 +1,15 @@ -class Chouette::Footnote < Chouette::ActiveRecord - include ChecksumSupport +module Chouette + class Footnote < Chouette::ActiveRecord + include ChecksumSupport - belongs_to :line, inverse_of: :footnotes - has_and_belongs_to_many :vehicle_journeys, :class_name => 'Chouette::VehicleJourney' + belongs_to :line, inverse_of: :footnotes + has_and_belongs_to_many :vehicle_journeys, :class_name => 'Chouette::VehicleJourney' - validates_presence_of :line + validates_presence_of :line - def checksum_attributes - attrs = ['code', 'label'] - self.slice(*attrs).values + def checksum_attributes + attrs = ['code', 'label'] + self.slice(*attrs).values + end end -end +end
\ No newline at end of file diff --git a/app/models/chouette/group_of_line.rb b/app/models/chouette/group_of_line.rb index a987d6311..3023d23ed 100644 --- a/app/models/chouette/group_of_line.rb +++ b/app/models/chouette/group_of_line.rb @@ -1,31 +1,33 @@ -class Chouette::GroupOfLine < Chouette::ActiveRecord - include StifCodifligneAttributesSupport - include GroupOfLineRestrictions - include LineReferentialSupport +module Chouette + class GroupOfLine < Chouette::ActiveRecord + include ObjectidSupport + include GroupOfLineRestrictions + include LineReferentialSupport - # FIXME http://jira.codehaus.org/browse/JRUBY-6358 - self.primary_key = "id" + # FIXME http://jira.codehaus.org/browse/JRUBY-6358 + self.primary_key = "id" - has_and_belongs_to_many :lines, :class_name => 'Chouette::Line', :order => 'lines.name' + has_and_belongs_to_many :lines, :class_name => 'Chouette::Line', :order => 'lines.name' - validates_presence_of :name + validates_presence_of :name - attr_reader :line_tokens + attr_reader :line_tokens - def self.nullable_attributes - [:comment] - end + def self.nullable_attributes + [:comment] + end - def commercial_stop_areas - Chouette::StopArea.joins(:children => [:stop_points => [:route => [:line => :group_of_lines] ] ]).where(:group_of_lines => {:id => self.id}).uniq - end + def commercial_stop_areas + Chouette::StopArea.joins(:children => [:stop_points => [:route => [:line => :group_of_lines] ] ]).where(:group_of_lines => {:id => self.id}).uniq + end - def stop_areas - Chouette::StopArea.joins(:stop_points => [:route => [:line => :group_of_lines] ]).where(:group_of_lines => {:id => self.id}) - end + def stop_areas + Chouette::StopArea.joins(:stop_points => [:route => [:line => :group_of_lines] ]).where(:group_of_lines => {:id => self.id}) + end - def line_tokens=(ids) - self.line_ids = ids.split(",") - end + def line_tokens=(ids) + self.line_ids = ids.split(",") + end -end + end +end
\ No newline at end of file diff --git a/app/models/chouette/journey_frequency.rb b/app/models/chouette/journey_frequency.rb index 45b8aea8c..1b4efe96e 100644 --- a/app/models/chouette/journey_frequency.rb +++ b/app/models/chouette/journey_frequency.rb @@ -1,5 +1,4 @@ module Chouette - class JourneyFrequencyValidator < ActiveModel::Validator def validate(record) timeband = record.timeband @@ -31,6 +30,6 @@ module Chouette validates :first_departure_time, presence: true validates :last_departure_time, presence: true validates :scheduled_headway_interval, presence: true - validates_with JourneyFrequencyValidator + validates_with Chouette::JourneyFrequencyValidator end -end +end
\ No newline at end of file diff --git a/app/models/chouette/journey_pattern.rb b/app/models/chouette/journey_pattern.rb index 1104c6035..5058c95dc 100644 --- a/app/models/chouette/journey_pattern.rb +++ b/app/models/chouette/journey_pattern.rb @@ -1,144 +1,191 @@ -class Chouette::JourneyPattern < Chouette::TridentActiveRecord - include ChecksumSupport - include JourneyPatternRestrictions - # FIXME http://jira.codehaus.org/browse/JRUBY-6358 - self.primary_key = "id" - - belongs_to :route - has_many :vehicle_journeys, :dependent => :destroy - has_many :vehicle_journey_at_stops, :through => :vehicle_journeys - has_and_belongs_to_many :stop_points, -> { order("stop_points.position") }, :before_add => :vjas_add, :before_remove => :vjas_remove, :after_add => :shortcuts_update_for_add, :after_remove => :shortcuts_update_for_remove - has_many :stop_areas, through: :stop_points - - validates_presence_of :route - validates_presence_of :name - - #validates :stop_points, length: { minimum: 2, too_short: :minimum }, on: :update - enum section_status: { todo: 0, completed: 1, control: 2 } - - attr_accessor :control_checked - def local_id - "IBOO-#{self.referential.id}-#{self.try(:route).try(:line).try(:objectid).try(:local_id)}-#{self.id}" - end +module Chouette + class JourneyPattern < Chouette::TridentActiveRecord + include ChecksumSupport + include JourneyPatternRestrictions + include ObjectidSupport + # FIXME http://jira.codehaus.org/browse/JRUBY-6358 + self.primary_key = "id" + + belongs_to :route + has_many :vehicle_journeys, :dependent => :destroy + has_many :vehicle_journey_at_stops, :through => :vehicle_journeys + has_and_belongs_to_many :stop_points, -> { order("stop_points.position") }, :before_add => :vjas_add, :before_remove => :vjas_remove, :after_add => :shortcuts_update_for_add, :after_remove => :shortcuts_update_for_remove + has_many :stop_areas, through: :stop_points + has_many :journey_pattern_sections + has_many :route_sections, through: :journey_pattern_sections, dependent: :destroy + + validates_presence_of :route + validates_presence_of :name + + #validates :stop_points, length: { minimum: 2, too_short: :minimum }, on: :update + enum section_status: { todo: 0, completed: 1, control: 2 } + + attr_accessor :control_checked + after_update :control_route_sections, :unless => "control_checked" + + + def local_id + "IBOO-#{self.referential.id}-#{self.route.line.get_objectid.local_id}-#{self.id}" + end - def checksum_attributes - values = self.slice(*['name', 'published_name', 'registration_number']).values - values << self.stop_points.map(&:stop_area).map(&:user_objectid) - values.flatten - end + def checksum_attributes + values = self.slice(*['name', 'published_name', 'registration_number']).values + values << self.stop_points.map(&:stop_area).map(&:user_objectid) + values.flatten + end - def self.state_update route, state - transaction do - state.each do |item| - item.delete('errors') - jp = find_by(objectid: item['object_id']) || state_create_instance(route, item) - next if item['deletable'] && jp.persisted? && jp.destroy - # Update attributes and stop_points associations - jp.update_attributes(state_permited_attributes(item)) unless item['new_record'] - jp.state_stop_points_update(item) if !jp.errors.any? && jp.persisted? - item['errors'] = jp.errors if jp.errors.any? + def self.state_update route, state + transaction do + state.each do |item| + item.delete('errors') + jp = find_by(objectid: item['object_id']) || state_create_instance(route, item) + next if item['deletable'] && jp.persisted? && jp.destroy + # Update attributes and stop_points associations + jp.update_attributes(state_permited_attributes(item)) unless item['new_record'] + jp.state_stop_points_update(item) if !jp.errors.any? && jp.persisted? + item['errors'] = jp.errors if jp.errors.any? + end + + if state.any? {|item| item['errors']} + state.map {|item| item.delete('object_id') if item['new_record']} + raise ::ActiveRecord::Rollback + end end - if state.any? {|item| item['errors']} - state.map {|item| item.delete('object_id') if item['new_record']} - raise ActiveRecord::Rollback - end + state.map {|item| item.delete('new_record')} + state.delete_if {|item| item['deletable']} end - state.map {|item| item.delete('new_record')} - state.delete_if {|item| item['deletable']} - end + def self.state_permited_attributes item + { + name: item['name'], + published_name: item['published_name'], + registration_number: item['registration_number'] + } + end - def self.state_permited_attributes item - { - name: item['name'], - published_name: item['published_name'], - registration_number: item['registration_number'] - } - end + def self.state_create_instance route, item + # Flag new record, so we can unset object_id if transaction rollback + jp = route.journey_patterns.create(state_permited_attributes(item)) - def self.state_create_instance route, item - # Flag new record, so we can unset object_id if transaction rollback - jp = route.journey_patterns.create(state_permited_attributes(item)) + # FIXME + # DefaultAttributesSupport will trigger some weird validation on after save + # wich will call to valid?, wich will populate errors + # In this case, we mark jp to be valid if persisted? return true + jp.errors.clear if jp.persisted? - # FIXME - # DefaultAttributesSupport will trigger some weird validation on after save - # wich will call to valid?, wich will populate errors - # In this case, we mark jp to be valid if persisted? return true - jp.errors.clear if jp.persisted? + item['object_id'] = jp.objectid + item['new_record'] = true + jp + end - item['object_id'] = jp.objectid - item['new_record'] = true - jp - end + def state_stop_points_update item + item['stop_points'].each do |sp| + exist = stop_area_ids.include?(sp['id']) + next if exist && sp['checked'] + + stop_point = route.stop_points.find_by(stop_area_id: sp['id']) + if !exist && sp['checked'] + stop_points << stop_point + end + if exist && !sp['checked'] + stop_points.delete(stop_point) + end + end + end - def state_stop_points_update item - item['stop_points'].each do |sp| - exist = stop_area_ids.include?(sp['id']) - next if exist && sp['checked'] + # TODO: this a workarround + # otherwise, we loose the first stop_point + # when creating a new journey_pattern + def special_update + bck_sp = self.stop_points.map {|s| s} + self.update_attributes :stop_points => [] + self.update_attributes :stop_points => bck_sp + end - stop_point = route.stop_points.find_by(stop_area_id: sp['id']) - if !exist && sp['checked'] - stop_points << stop_point - end - if exist && !sp['checked'] - stop_points.delete(stop_point) - end + def departure_stop_point + return unless departure_stop_point_id + Chouette::StopPoint.find( departure_stop_point_id) end - end - # TODO: this a workarround - # otherwise, we loose the first stop_point - # when creating a new journey_pattern - def special_update - bck_sp = self.stop_points.map {|s| s} - self.update_attributes :stop_points => [] - self.update_attributes :stop_points => bck_sp - end + def arrival_stop_point + return unless arrival_stop_point_id + Chouette::StopPoint.find( arrival_stop_point_id) + end - def departure_stop_point - return unless departure_stop_point_id - Chouette::StopPoint.find( departure_stop_point_id) - end + def shortcuts_update_for_add( stop_point) + stop_points << stop_point unless stop_points.include?( stop_point) - def arrival_stop_point - return unless arrival_stop_point_id - Chouette::StopPoint.find( arrival_stop_point_id) - end + ordered_stop_points = stop_points + ordered_stop_points = ordered_stop_points.sort { |a,b| a.position <=> b.position} unless ordered_stop_points.empty? - def shortcuts_update_for_add( stop_point) - stop_points << stop_point unless stop_points.include?( stop_point) + self.update_attributes( :departure_stop_point_id => (ordered_stop_points.first && ordered_stop_points.first.id), + :arrival_stop_point_id => (ordered_stop_points.last && ordered_stop_points.last.id)) + end - ordered_stop_points = stop_points - ordered_stop_points = ordered_stop_points.sort { |a,b| a.position <=> b.position} unless ordered_stop_points.empty? + def shortcuts_update_for_remove( stop_point) + stop_points.delete( stop_point) if stop_points.include?( stop_point) - self.update_attributes( :departure_stop_point_id => (ordered_stop_points.first && ordered_stop_points.first.id), - :arrival_stop_point_id => (ordered_stop_points.last && ordered_stop_points.last.id)) - end + ordered_stop_points = stop_points + ordered_stop_points = ordered_stop_points.sort { |a,b| a.position <=> b.position} unless ordered_stop_points.empty? - def shortcuts_update_for_remove( stop_point) - stop_points.delete( stop_point) if stop_points.include?( stop_point) + self.update_attributes( :departure_stop_point_id => (ordered_stop_points.first && ordered_stop_points.first.id), + :arrival_stop_point_id => (ordered_stop_points.last && ordered_stop_points.last.id)) + end - ordered_stop_points = stop_points - ordered_stop_points = ordered_stop_points.sort { |a,b| a.position <=> b.position} unless ordered_stop_points.empty? + def vjas_add( stop_point) + return if new_record? - self.update_attributes( :departure_stop_point_id => (ordered_stop_points.first && ordered_stop_points.first.id), - :arrival_stop_point_id => (ordered_stop_points.last && ordered_stop_points.last.id)) - end + vehicle_journeys.each do |vj| + vjas = vj.vehicle_journey_at_stops.create :stop_point_id => stop_point.id + end + end + + def vjas_remove( stop_point) + return if new_record? - def vjas_add( stop_point) - return if new_record? + vehicle_journey_at_stops.where( :stop_point_id => stop_point.id).each do |vjas| + vjas.destroy + end + end +<<<<<<< HEAD - vehicle_journeys.each do |vj| - vjas = vj.vehicle_journey_at_stops.create :stop_point_id => stop_point.id + def control_route_sections + stop_area_ids = self.stop_points.map(&:stop_area_id) + control_route_sections_by_stop_areas(stop_area_ids) end - end - def vjas_remove( stop_point) - return if new_record? + def control_route_sections_by_stop_areas(stop_area_ids) + journey_pattern_section_all + i = 0 + to_control = false + stop_area_ids.each_cons(2) do |a| + jps = @route_sections_orders[i] + i += 1 + unless jps + to_control = true + next + end + unless [jps.route_section.departure.id, jps.route_section.arrival.id] == a + jps.destroy + to_control = true + end + end + self.control_checked = true + to_control ? self.control! : self.completed! + end - vehicle_journey_at_stops.where( :stop_point_id => stop_point.id).each do |vjas| - vjas.destroy + protected + + def journey_pattern_section_all + @route_sections_orders = {} + self.journey_pattern_sections.all.map do |journey_pattern_section| + @route_sections_orders[journey_pattern_section.rank] = journey_pattern_section + end end end end +======= + end +end +>>>>>>> master diff --git a/app/models/chouette/journey_pattern_section.rb b/app/models/chouette/journey_pattern_section.rb new file mode 100644 index 000000000..226a50c27 --- /dev/null +++ b/app/models/chouette/journey_pattern_section.rb @@ -0,0 +1,22 @@ +module Chouette + class JourneyPatternSection < Chouette::ActiveRecord + belongs_to :journey_pattern + belongs_to :route_section + + validates :journey_pattern_id, presence: true + validates :route_section_id, presence: true + validates :rank, presence: true, numericality: :only_integer + validates :journey_pattern_id, uniqueness: { scope: [:route_section_id, :rank] } + + default_scope { order(:rank) } + + def self.update_by_journey_pattern_rank(journey_pattern_id, route_section_id, rank) + jps = self.find_or_initialize_by(journey_pattern_id: journey_pattern_id, rank: rank) + if route_section_id.present? + jps.update_attributes(route_section_id: route_section_id) + else + jps.destroy + end + end + end +end
\ No newline at end of file diff --git a/app/models/chouette/line.rb b/app/models/chouette/line.rb index 0139bb6a4..780f6473f 100644 --- a/app/models/chouette/line.rb +++ b/app/models/chouette/line.rb @@ -1,81 +1,83 @@ -class Chouette::Line < Chouette::ActiveRecord - include StifCodifligneAttributesSupport - include LineRestrictions - include LineReferentialSupport - extend StifTransportModeEnumerations - extend StifTransportSubmodeEnumerations +module Chouette + class Line < Chouette::ActiveRecord + include LineRestrictions + include LineReferentialSupport + include ObjectidSupport + extend StifTransportModeEnumerations + extend StifTransportSubmodeEnumerations - extend ActiveModel::Naming + extend ActiveModel::Naming - # FIXME http://jira.codehaus.org/browse/JRUBY-6358 - self.primary_key = "id" + # FIXME http://jira.codehaus.org/browse/JRUBY-6358 + self.primary_key = "id" - belongs_to :company - belongs_to :network - belongs_to :line_referential + belongs_to :company + belongs_to :network + belongs_to :line_referential - has_array_of :secondary_companies, class_name: 'Chouette::Company' + has_array_of :secondary_companies, class_name: 'Chouette::Company' - has_many :routes, :dependent => :destroy - has_many :journey_patterns, :through => :routes - has_many :vehicle_journeys, :through => :journey_patterns - has_many :routing_constraint_zones, through: :routes + has_many :routes, :dependent => :destroy + has_many :journey_patterns, :through => :routes + has_many :vehicle_journeys, :through => :journey_patterns + has_many :routing_constraint_zones, through: :routes - has_and_belongs_to_many :group_of_lines, :class_name => 'Chouette::GroupOfLine', :order => 'group_of_lines.name' + has_and_belongs_to_many :group_of_lines, :class_name => 'Chouette::GroupOfLine', :order => 'group_of_lines.name' - has_many :footnotes, :inverse_of => :line, :validate => :true, :dependent => :destroy - accepts_nested_attributes_for :footnotes, :reject_if => :all_blank, :allow_destroy => true + has_many :footnotes, :inverse_of => :line, :validate => :true, :dependent => :destroy + accepts_nested_attributes_for :footnotes, :reject_if => :all_blank, :allow_destroy => true - attr_reader :group_of_line_tokens + attr_reader :group_of_line_tokens - # validates_presence_of :network - # validates_presence_of :company + # validates_presence_of :network + # validates_presence_of :company - validates_format_of :registration_number, :with => %r{\A[\d\w_\-]+\Z}, :allow_nil => true, :allow_blank => true - validates_format_of :stable_id, :with => %r{\A[\d\w_\-]+\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_format_of :color, :with => %r{\A[0-9a-fA-F]{6}\Z}, :allow_nil => true, :allow_blank => true - validates_format_of :text_color, :with => %r{\A[0-9a-fA-F]{6}\Z}, :allow_nil => true, :allow_blank => true + validates_format_of :registration_number, :with => %r{\A[\d\w_\-]+\Z}, :allow_nil => true, :allow_blank => true + validates_format_of :stable_id, :with => %r{\A[\d\w_\-]+\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_format_of :color, :with => %r{\A[0-9a-fA-F]{6}\Z}, :allow_nil => true, :allow_blank => true + validates_format_of :text_color, :with => %r{\A[0-9a-fA-F]{6}\Z}, :allow_nil => true, :allow_blank => true - validates_presence_of :name + validates_presence_of :name - scope :by_text, ->(text) { where('lower(name) LIKE :t or lower(published_name) LIKE :t or lower(objectid) LIKE :t or lower(comment) LIKE :t or lower(number) LIKE :t', - t: "%#{text.downcase}%") } + scope :by_text, ->(text) { where('lower(name) LIKE :t or lower(published_name) LIKE :t or lower(objectid) LIKE :t or lower(comment) LIKE :t or lower(number) LIKE :t', + t: "%#{text.downcase}%") } - def self.nullable_attributes - [:published_name, :number, :comment, :url, :color, :text_color, :stable_id] - end + def self.nullable_attributes + [:published_name, :number, :comment, :url, :color, :text_color, :stable_id] + end - def geometry_presenter - Chouette::Geometry::LinePresenter.new self - end + def geometry_presenter + Chouette::Geometry::LinePresenter.new self + end - def commercial_stop_areas - Chouette::StopArea.joins(:children => [:stop_points => [:route => :line] ]).where(:lines => {:id => self.id}).uniq - end + def commercial_stop_areas + Chouette::StopArea.joins(:children => [:stop_points => [:route => :line] ]).where(:lines => {:id => self.id}).uniq + end - def stop_areas - Chouette::StopArea.joins(:stop_points => [:route => :line]).where(:lines => {:id => self.id}) - end + def stop_areas + Chouette::StopArea.joins(:stop_points => [:route => :line]).where(:lines => {:id => self.id}) + end - def stop_areas_last_parents - Chouette::StopArea.joins(:stop_points => [:route => :line]).where(:lines => {:id => self.id}).collect(&:root).flatten.uniq - end + def stop_areas_last_parents + Chouette::StopArea.joins(:stop_points => [:route => :line]).where(:lines => {:id => self.id}).collect(&:root).flatten.uniq + end - def group_of_line_tokens=(ids) - self.group_of_line_ids = ids.split(",") - end + def group_of_line_tokens=(ids) + self.group_of_line_ids = ids.split(",") + end - def vehicle_journey_frequencies? - self.vehicle_journeys.unscoped.where(journey_category: 1).count > 0 - end + def vehicle_journey_frequencies? + self.vehicle_journeys.unscoped.where(journey_category: 1).count > 0 + end - def display_name - [objectid.local_id, number, name, company.try(:name)].compact.join(' - ') - end + def display_name + [self.get_objectid.local_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 companies + line_referential.companies.where(id: ([company_id] + Array(secondary_company_ids)).compact) + end -end + end +end
\ No newline at end of file diff --git a/app/models/chouette/link_orientation_type.rb b/app/models/chouette/link_orientation_type.rb index ec279aba3..c3addf4b4 100644 --- a/app/models/chouette/link_orientation_type.rb +++ b/app/models/chouette/link_orientation_type.rb @@ -1,49 +1,51 @@ -class Chouette::LinkOrientationType < ActiveSupport::StringInquirer +module Chouette + class LinkOrientationType < ActiveSupport::StringInquirer - def initialize(text_code, numerical_code) - super text_code.to_s - @numerical_code = numerical_code - end + def initialize(text_code, numerical_code) + super text_code.to_s + @numerical_code = numerical_code + end - def self.new(text_code, numerical_code = nil) - if text_code and numerical_code - super - elsif self === text_code - text_code - else - if Fixnum === text_code - text_code, numerical_code = definitions.rassoc(text_code) + def self.new(text_code, numerical_code = nil) + if text_code and numerical_code + super + elsif self === text_code + text_code else - text_code, numerical_code = definitions.assoc(text_code.to_s) - end + if Fixnum === text_code + text_code, numerical_code = definitions.rassoc(text_code) + else + text_code, numerical_code = definitions.assoc(text_code.to_s) + end - super text_code, numerical_code + super text_code, numerical_code + end end - end - def to_i - @numerical_code - end + def to_i + @numerical_code + end - def inspect - "#{to_s}/#{to_i}" - end + def inspect + "#{to_s}/#{to_i}" + end - def name - camelize - end + def name + camelize + end - @@definitions = [ - ["access_point_to_stop_area", 0], - ["stop_area_to_access_point", 1] - ] - cattr_reader :definitions + @@definitions = [ + ["access_point_to_stop_area", 0], + ["stop_area_to_access_point", 1] + ] + cattr_reader :definitions - @@all = nil - def self.all - @@all ||= definitions.collect do |text_code, numerical_code| - new(text_code, numerical_code) + @@all = nil + def self.all + @@all ||= definitions.collect do |text_code, numerical_code| + new(text_code, numerical_code) + end end - end -end + end +end
\ No newline at end of file diff --git a/app/models/chouette/loader.rb b/app/models/chouette/loader.rb index 40a2be4ee..7ab696dab 100644 --- a/app/models/chouette/loader.rb +++ b/app/models/chouette/loader.rb @@ -1,110 +1,112 @@ -class Chouette::Loader +module Chouette + class Loader - attr_reader :schema, :database, :user, :password, :host + attr_reader :schema, :database, :user, :password, :host - def initialize(schema) - @schema = schema + def initialize(schema) + @schema = schema - Chouette::ActiveRecord.connection_pool.spec.config.tap do |config| - @database = config[:database] - @user = config[:username] - @password = config[:password] - @host = (config[:host] or "localhost") + Chouette::ActiveRecord.connection_pool.spec.config.tap do |config| + @database = config[:database] + @user = config[:username] + @password = config[:password] + @host = (config[:host] or "localhost") + end end - end - # Load dump where datas are in schema 'chouette' - def load_dump(file) - logger.info "Load #{file} in schema #{schema}" - with_pg_password do - execute!("sed -e 's/ chouette/ \"#{schema}\"/' -e 's/ OWNER TO .*;/ OWNER TO #{user};/' #{file} | psql #{pg_options} --set ON_ERROR_ROLLBACK=1 --set ON_ERROR_STOP=1") + # Load dump where datas are in schema 'chouette' + def load_dump(file) + logger.info "Load #{file} in schema #{schema}" + with_pg_password do + execute!("sed -e 's/ chouette/ \"#{schema}\"/' -e 's/ OWNER TO .*;/ OWNER TO #{user};/' #{file} | psql #{pg_options} --set ON_ERROR_ROLLBACK=1 --set ON_ERROR_STOP=1") + end + self end - self - end - def self.chouette_command=(command) - Chouette::Command.command = command - end + def self.chouette_command=(command) + Chouette::Command.command = command + end - class << self - deprecate :chouette_command= => "Use Chouette::Command.command =" - end + class << self + deprecate :chouette_command= => "Use Chouette::Command.command =" + end - def chouette_command - @chouette_command ||= Chouette::Command.new(:schema => schema) - end + def chouette_command + @chouette_command ||= Chouette::Command.new(:schema => schema) + end - def import(file, options = {}) - options = { - :format => :neptune - }.merge(options) - - command_options = { - :c => "import", - :o => "line", - :format => options.delete(:format).to_s.upcase, - :input_file => File.expand_path(file), - :optimize_memory => true - }.merge(options) - - logger.info "Import #{file} in schema #{schema}" - chouette_command.run! command_options - end + def import(file, options = {}) + options = { + :format => :neptune + }.merge(options) + + command_options = { + :c => "import", + :o => "line", + :format => options.delete(:format).to_s.upcase, + :input_file => File.expand_path(file), + :optimize_memory => true + }.merge(options) + + logger.info "Import #{file} in schema #{schema}" + chouette_command.run! command_options + end - def backup(file) - logger.info "Backup schema #{schema} in #{file}" + def backup(file) + logger.info "Backup schema #{schema} in #{file}" - with_pg_password do - execute!("pg_dump -n #{schema} -f #{file} #{pg_options}") - end + with_pg_password do + execute!("pg_dump -n #{schema} -f #{file} #{pg_options}") + end - self - end + self + end - def pg_options - [].tap do |options| - options << "-U #{user}" if user - options << "-h #{host}" if host - options << database - end.join(" ") - end + def pg_options + [].tap do |options| + options << "-U #{user}" if user + options << "-h #{host}" if host + options << database + end.join(" ") + end - def create - logger.info "Create schema #{schema}" - with_pg_password do - execute!("psql -c 'CREATE SCHEMA \"#{schema}\";' #{pg_options}") + def create + logger.info "Create schema #{schema}" + with_pg_password do + execute!("psql -c 'CREATE SCHEMA \"#{schema}\";' #{pg_options}") + end + self end - self - end - def drop - logger.info "Drop schema #{schema}" - with_pg_password do - execute!("psql -c 'DROP SCHEMA \"#{schema}\" CASCADE;' #{pg_options}") + def drop + logger.info "Drop schema #{schema}" + with_pg_password do + execute!("psql -c 'DROP SCHEMA \"#{schema}\" CASCADE;' #{pg_options}") + end + self end - self - end - def with_pg_password(&block) - ENV['PGPASSWORD'] = password.to_s if password - begin - yield - ensure - ENV['PGPASSWORD'] = nil + def with_pg_password(&block) + ENV['PGPASSWORD'] = password.to_s if password + begin + yield + ensure + ENV['PGPASSWORD'] = nil + end end - end - @@binarisation_command = "binarisation" - cattr_accessor :binarisation_command + @@binarisation_command = "binarisation" + cattr_accessor :binarisation_command - def binarize(period, target_directory) - # TODO check these computed daybefore/dayafter - day_before = Date.today - period.begin - day_after = period.end - period.begin + def binarize(period, target_directory) + # TODO check these computed daybefore/dayafter + day_before = Date.today - period.begin + day_after = period.end - period.begin - execute! "#{binarisation_command} --host=#{host} --dbname=#{database} --user=#{user} --password=#{password} --schema=#{schema} --daybefore=#{day_before} --dayafter=#{day_after} --targetdirectory=#{target_directory}" - end + execute! "#{binarisation_command} --host=#{host} --dbname=#{database} --user=#{user} --password=#{password} --schema=#{schema} --daybefore=#{day_before} --dayafter=#{day_after} --targetdirectory=#{target_directory}" + end - include Chouette::CommandLineSupport + include Chouette::CommandLineSupport -end + end +end
\ No newline at end of file diff --git a/app/models/chouette/netex_object_id.rb b/app/models/chouette/netex_object_id.rb deleted file mode 100644 index 441004c1e..000000000 --- a/app/models/chouette/netex_object_id.rb +++ /dev/null @@ -1,40 +0,0 @@ -class Chouette::NetexObjectId < String - - def valid? - parts.present? - end - alias_method :objectid?, :valid? - - @@format = /^([A-Za-z_]+):([0-9A-Za-z_]+):([A-Za-z]+):([0-9A-Za-z_-]+)$/ - cattr_reader :format - - def parts - match(format).try(:captures) - end - - def provider_id - parts.try(:first) - end - - def system_id - parts.try(:second) - end - - def object_type - parts.try(:third) - end - - def local_id - parts.try(:fourth) - end - - def self.create(provider_id, system_id, object_type, local_id) - new [provider_id, system_id, object_type, local_id].join(":") - end - - def self.new(string) - string ||= "" - self === string ? string : super - end - -end diff --git a/app/models/chouette/network.rb b/app/models/chouette/network.rb index 8df205789..c51de3984 100644 --- a/app/models/chouette/network.rb +++ b/app/models/chouette/network.rb @@ -1,49 +1,51 @@ -class Chouette::Network < Chouette::ActiveRecord - include StifCodifligneAttributesSupport - include NetworkRestrictions - include LineReferentialSupport - # FIXME http://jira.codehaus.org/browse/JRUBY-6358 - self.primary_key = "id" +module Chouette + class Network < Chouette::ActiveRecord + include NetworkRestrictions + include LineReferentialSupport + include ObjectidSupport + # FIXME http://jira.codehaus.org/browse/JRUBY-6358 + self.primary_key = "id" - has_many :lines + has_many :lines - attr_accessor :source_type_name + attr_accessor :source_type_name - validates_format_of :registration_number, :with => %r{\A[0-9A-Za-z_-]+\Z}, :allow_nil => true, :allow_blank => true - validates_presence_of :name + validates_format_of :registration_number, :with => %r{\A[0-9A-Za-z_-]+\Z}, :allow_nil => true, :allow_blank => true + validates_presence_of :name + validates_presence_of :objectid_format - def self.object_id_key - "PTNetwork" - end - - def self.nullable_attributes - [:source_name, :source_type, :source_identifier, :comment] - end + def self.object_id_key + "PTNetwork" + end - def commercial_stop_areas - Chouette::StopArea.joins(:children => [:stop_points => [:route => [:line => :network] ] ]).where(:networks => {:id => self.id}).uniq - end + def self.nullable_attributes + [:source_name, :source_type, :source_identifier, :comment] + end - def stop_areas - Chouette::StopArea.joins(:stop_points => [:route => [:line => :network] ]).where(:networks => {:id => self.id}) - end + def commercial_stop_areas + Chouette::StopArea.joins(:children => [:stop_points => [:route => [:line => :network] ] ]).where(:networks => {:id => self.id}).uniq + end - def source_type_name - # return nil if source_type is nil - source_type && Chouette::SourceType.new( source_type.underscore) - end + def stop_areas + Chouette::StopArea.joins(:stop_points => [:route => [:line => :network] ]).where(:networks => {:id => self.id}) + end - def source_type_name=(source_type_name) - self.source_type = (source_type_name ? source_type_name.camelcase : nil) - end + def source_type_name + # return nil if source_type is nil + source_type && Chouette::SourceType.new( source_type.underscore) + end - @@source_type_names = nil - def self.source_type_names - @@source_type_names ||= Chouette::SourceType.all.select do |source_type_name| - source_type_name.to_i > 0 + def source_type_name=(source_type_name) + self.source_type = (source_type_name ? source_type_name.camelcase : nil) end - end + @@source_type_names = nil + def self.source_type_names + @@source_type_names ||= Chouette::SourceType.all.select do |source_type_name| + source_type_name.to_i > 0 + end + end -end + end +end
\ No newline at end of file diff --git a/app/models/chouette/object_id.rb b/app/models/chouette/object_id.rb deleted file mode 100644 index 0b122c91b..000000000 --- a/app/models/chouette/object_id.rb +++ /dev/null @@ -1,36 +0,0 @@ -class Chouette::ObjectId < String - - def valid? - parts.present? - end - alias_method :objectid?, :valid? - - @@format = /^([0-9A-Za-z_]+):([A-Za-z]+):([0-9A-Za-z_-]+)$/ - cattr_reader :format - - def parts - match(format).try(:captures) - end - - def system_id - parts.try(:first) - end - - def object_type - parts.try(:second) - end - - def local_id - parts.try(:third) - end - - def self.create(system_id, object_type, local_id) - new [system_id, object_type, local_id].join(":") - end - - def self.new(string) - string ||= "" - self === string ? string : super - end - -end diff --git a/app/models/chouette/objectid/netex.rb b/app/models/chouette/objectid/netex.rb new file mode 100644 index 000000000..7953c6b12 --- /dev/null +++ b/app/models/chouette/objectid/netex.rb @@ -0,0 +1,33 @@ +module Chouette + module Objectid + class Netex + include ActiveModel::Model + + attr_accessor :provider_id, :object_type, :local_id, :creation_id + validates_presence_of :provider_id, :object_type, :local_id, :creation_id + validate :must_respect_format + + def initialize(**attributes) + @provider_id ||= (attributes[:provider_id] ||= 'chouette') + @object_type = attributes[:object_type] + @local_id = attributes[:local_id] + @creation_id = (attributes[:creation_id] ||= 'LOC') + end + + @@format = /^([A-Za-z_-]+):([A-Za-z]+):([0-9A-Za-z_-]+):([A-Za-z]+)$/ + cattr_reader :format + + def to_s + "#{self.provider_id}:#{self.object_type}:#{self.local_id}:#{self.creation_id}" + end + + def must_respect_format + self.to_s.match(format) + end + + def short_id + local_id + end + end + end +end
\ No newline at end of file diff --git a/app/models/chouette/objectid/stif_codifligne.rb b/app/models/chouette/objectid/stif_codifligne.rb new file mode 100644 index 000000000..a1e40f0a1 --- /dev/null +++ b/app/models/chouette/objectid/stif_codifligne.rb @@ -0,0 +1,24 @@ +module Chouette + module Objectid + class StifCodifligne < Chouette::Objectid::Netex + + attr_accessor :sync_id + validates_presence_of :sync_id + validates :creation_id, presence: false + + @@format = /^([A-Za-z_]+):([A-Za-z]+):([A-Za-z]+):([0-9A-Za-z_-]+)$/ + + def initialize(**attributes) + @provider_id = attributes[:provider_id] + @object_type = attributes[:object_type] + @local_id = attributes[:local_id] + @sync_id = attributes[:sync_id] + super + end + + def to_s + "#{self.provider_id}:#{self.sync_id}:#{self.object_type}:#{self.local_id}" + end + end + end +end
\ No newline at end of file diff --git a/app/models/chouette/objectid/stif_netex.rb b/app/models/chouette/objectid/stif_netex.rb new file mode 100644 index 000000000..80208af56 --- /dev/null +++ b/app/models/chouette/objectid/stif_netex.rb @@ -0,0 +1,15 @@ +module Chouette + module Objectid + class StifNetex < Chouette::Objectid::Netex + + def initialize(**attributes) + @provider_id = (attributes[:provider_id] ||= 'stif') + super + end + + def short_id + local_id.try(:split, "-").try(:[], -1) + end + end + end +end
\ No newline at end of file diff --git a/app/models/chouette/objectid/stif_reflex.rb b/app/models/chouette/objectid/stif_reflex.rb new file mode 100644 index 000000000..69a3f52fa --- /dev/null +++ b/app/models/chouette/objectid/stif_reflex.rb @@ -0,0 +1,23 @@ +module Chouette + module Objectid + class StifReflex < Chouette::Objectid::Netex + + attr_accessor :country_code, :zip_code + validates_presence_of :country_code, :zip_code + validates :creation_id, presence: false + + @@format = /^([A-Za-z_]+):([0-9A-Za-z_-]+):([A-Za-z]+):([0-9A-Za-z_-]+):([A-Za-z]+)$/ + + def initialize(**attributes) + @provider_id = attributes[:provider_id] + @country_code = attributes[:country_code] + @zip_code = attributes[:zip_code] + super + end + + def to_s + "#{self.country_code}:#{self.zip_code}:#{self.object_type}:#{self.local_id}:#{self.provider_id}" + end + end + end +end
\ No newline at end of file diff --git a/app/models/chouette/objectid_formatter/netex.rb b/app/models/chouette/objectid_formatter/netex.rb new file mode 100644 index 000000000..7279fdaa5 --- /dev/null +++ b/app/models/chouette/objectid_formatter/netex.rb @@ -0,0 +1,18 @@ +module Chouette + module ObjectidFormatter + class Netex + def before_validation(model) + model.update_attributes(objectid: Chouette::Objectid::Netex.new(local_id: SecureRandom.uuid, object_type: model.class.name.gsub(/Chouette::/,'')).to_s) unless model.read_attribute(:objectid) + end + + def after_commit(model) + # unused method in this context + end + + def get_objectid(definition) + parts = definition.try(:split, ":") + Chouette::Objectid::Netex.new(provider_id: parts[0], object_type: parts[1], local_id: parts[2], creation_id: parts[3]) rescue nil + end + end + end +end
\ No newline at end of file diff --git a/app/models/chouette/objectid_formatter/stif_codifligne.rb b/app/models/chouette/objectid_formatter/stif_codifligne.rb new file mode 100644 index 000000000..0624fc8a8 --- /dev/null +++ b/app/models/chouette/objectid_formatter/stif_codifligne.rb @@ -0,0 +1,18 @@ +module Chouette + module ObjectidFormatter + class Chouette::ObjectidFormatter::StifCodifligne + def before_validation(model) + # unused method in this context + end + + def after_commit(model) + # unused method in this context + end + + def get_objectid(definition) + parts = definition.try(:split, ":") + Chouette::Objectid::StifCodifligne.new(provider_id: parts[0], sync_id: parts[1], object_type: parts[2], local_id: parts[3]) rescue nil + end + end + end +end
\ No newline at end of file diff --git a/app/models/chouette/objectid_formatter/stif_netex.rb b/app/models/chouette/objectid_formatter/stif_netex.rb new file mode 100644 index 000000000..0256754bf --- /dev/null +++ b/app/models/chouette/objectid_formatter/stif_netex.rb @@ -0,0 +1,18 @@ +module Chouette + module ObjectidFormatter + class Chouette::ObjectidFormatter::StifNetex + def before_validation(model) + model.attributes = {objectid: "__pending_id__#{SecureRandom.uuid}"} unless model.read_attribute(:objectid) + end + + def after_commit(model) + model.update_attributes(objectid: Chouette::Objectid::StifNetex.new(provider_id: "stif", object_type: model.class.name.gsub(/Chouette::/,''), local_id: model.local_id).to_s) + end + + def get_objectid(definition) + parts = definition.try(:split, ":") + Chouette::Objectid::StifNetex.new(provider_id: parts[0], object_type: parts[1], local_id: parts[2], creation_id: parts[3]) rescue nil + end + end + end +end
\ No newline at end of file diff --git a/app/models/chouette/objectid_formatter/stif_reflex.rb b/app/models/chouette/objectid_formatter/stif_reflex.rb new file mode 100644 index 000000000..5637f2806 --- /dev/null +++ b/app/models/chouette/objectid_formatter/stif_reflex.rb @@ -0,0 +1,18 @@ +module Chouette + module ObjectidFormatter + class Chouette::ObjectidFormatter::StifReflex + def before_validation(model) + # unused method in this context + end + + def after_commit(model) + # unused method in this context + end + + def get_objectid(definition) + parts = definition.try(:split, ":") + Chouette::Objectid::StifReflex.new(country_code: parts[0], zip_code: parts[1], object_type: parts[2], local_id: parts[3], provider_id: parts[4]) rescue nil + end + end + end +end
\ No newline at end of file diff --git a/app/models/chouette/pt_link.rb b/app/models/chouette/pt_link.rb index 8a4e368ea..5bf77da02 100644 --- a/app/models/chouette/pt_link.rb +++ b/app/models/chouette/pt_link.rb @@ -1,37 +1,37 @@ require 'geokit' -class Chouette::PtLink < Chouette::ActiveRecord - # FIXME http://jira.codehaus.org/browse/JRUBY-6358 - self.primary_key = "id" +module Chouette + class PtLink < Chouette::ActiveRecord + # FIXME http://jira.codehaus.org/browse/JRUBY-6358 + self.primary_key = "id" - include Geokit::Mappable + include Geokit::Mappable - def geometry - the_geom - end + def geometry + the_geom + end - def self.import_csv - csv_file = Rails.root + "chouette_pt_links.csv" - if File.exists?( csv_file) - csv = CSV::Reader.parse(File.read(csv_file)) + def self.import_csv + csv_file = Rails.root + "chouette_pt_links.csv" + if File.exists?( csv_file) + csv = CSV::Reader.parse(File.read(csv_file)) - slug = csv.shift.first + slug = csv.shift.first - Network::Base.find_by_slug( slug).tune_connection + Network::Base.find_by_slug( slug).tune_connection - csv.each do |row| - origin = Chouette::StopArea.find_by_objectid( row[0]) - destination = Chouette::StopArea.find_by_objectid( row[1]) + csv.each do |row| + origin = Chouette::StopArea.find_by_objectid( row[0]) + destination = Chouette::StopArea.find_by_objectid( row[1]) - raise "unknown origin #{row[0]}" unless origin - raise "unknown destination #{row[1]}" unless destination + raise "unknown origin #{row[0]}" unless origin + raise "unknown destination #{row[1]}" unless destination - Chouette::PtLink.create( :departure_id => origin.id, - :arrival_id => destination.id, - :the_geom => GeoRuby::SimpleFeatures::Geometry.from_hex_ewkb( row[2])) + Chouette::PtLink.create( :departure_id => origin.id, + :arrival_id => destination.id, + :the_geom => GeoRuby::SimpleFeatures::Geometry.from_hex_ewkb( row[2])) + end end end - end - -end +end
\ No newline at end of file diff --git a/app/models/chouette/route.rb b/app/models/chouette/route.rb index 1a05d43d9..be86b5b04 100644 --- a/app/models/chouette/route.rb +++ b/app/models/chouette/route.rb @@ -1,78 +1,80 @@ -class Chouette::Route < Chouette::TridentActiveRecord - include RouteRestrictions - include ChecksumSupport +module Chouette + class Route < Chouette::TridentActiveRecord + include RouteRestrictions + include ChecksumSupport + include ObjectidSupport - extend Enumerize - extend ActiveModel::Naming + extend Enumerize + extend ActiveModel::Naming - 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 + 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 - # FIXME http://jira.codehaus.org/browse/JRUBY-6358 - self.primary_key = "id" + # FIXME http://jira.codehaus.org/browse/JRUBY-6358 + self.primary_key = "id" - def self.nullable_attributes - [:published_name, :comment, :number, :name, :direction, :wayback] - end + def self.nullable_attributes + [:published_name, :comment, :number, :name, :direction, :wayback] + end - belongs_to :line - belongs_to :opposite_route, :class_name => 'Chouette::Route', :foreign_key => :opposite_route_id + belongs_to :line + belongs_to :opposite_route, :class_name => 'Chouette::Route', :foreign_key => :opposite_route_id - has_many :routing_constraint_zones - has_many :journey_patterns, :dependent => :destroy - has_many :vehicle_journeys, :dependent => :destroy do - def timeless - Chouette::Route.vehicle_journeys_timeless(proxy_association.owner.journey_patterns.pluck( :departure_stop_point_id)) + has_many :routing_constraint_zones + has_many :journey_patterns, :dependent => :destroy + has_many :vehicle_journeys, :dependent => :destroy do + def timeless + Chouette::Route.vehicle_journeys_timeless(proxy_association.owner.journey_patterns.pluck( :departure_stop_point_id)) + end end - end - has_many :vehicle_journey_frequencies, :dependent => :destroy do - # Todo : I think there is a better way to do this. - def timeless - Chouette::Route.vehicle_journeys_timeless(proxy_association.owner.journey_patterns.pluck( :departure_stop_point_id)) + has_many :vehicle_journey_frequencies, :dependent => :destroy do + # Todo : I think there is a better way to do this. + def timeless + Chouette::Route.vehicle_journeys_timeless(proxy_association.owner.journey_patterns.pluck( :departure_stop_point_id)) + end end - end - has_many :stop_points, -> { order("position") }, :dependent => :destroy do - def find_by_stop_area(stop_area) - stop_area_ids = Integer === stop_area ? [stop_area] : (stop_area.children_in_depth + [stop_area]).map(&:id) - where( :stop_area_id => stop_area_ids).first or - raise ActiveRecord::RecordNotFound.new("Can't find a StopArea #{stop_area.inspect} in Route #{proxy_owner.id.inspect}'s StopPoints") - end - - def between(departure, arrival) - between_positions = [departure, arrival].collect do |endpoint| - case endpoint - when Chouette::StopArea - find_by_stop_area(endpoint).position - when Chouette::StopPoint - endpoint.position - when Integer - endpoint - else - raise ActiveRecord::RecordNotFound.new("Can't determine position in route #{proxy_owner.id} with #{departure.inspect}") + has_many :stop_points, -> { order("position") }, :dependent => :destroy do + def find_by_stop_area(stop_area) + stop_area_ids = Integer === stop_area ? [stop_area] : (stop_area.children_in_depth + [stop_area]).map(&:id) + where( :stop_area_id => stop_area_ids).first or + raise ActiveRecord::RecordNotFound.new("Can't find a StopArea #{stop_area.inspect} in Route #{proxy_owner.id.inspect}'s StopPoints") + end + + def between(departure, arrival) + between_positions = [departure, arrival].collect do |endpoint| + case endpoint + when Chouette::StopArea + find_by_stop_area(endpoint).position + when Chouette::StopPoint + endpoint.position + when Integer + endpoint + else + raise ActiveRecord::RecordNotFound.new("Can't determine position in route #{proxy_owner.id} with #{departure.inspect}") + end end + where(" position between ? and ? ", between_positions.first, between_positions.last) end - where(" position between ? and ? ", between_positions.first, between_positions.last) end - end - has_many :stop_areas, -> { order('stop_points.position ASC') }, :through => :stop_points do - def between(departure, arrival) - departure, arrival = [departure, arrival].map do |endpoint| - String === endpoint ? Chouette::StopArea.find_by_objectid(endpoint) : endpoint + has_many :stop_areas, -> { order('stop_points.position ASC') }, :through => :stop_points do + def between(departure, arrival) + departure, arrival = [departure, arrival].map do |endpoint| + String === endpoint ? Chouette::StopArea.find_by_objectid(endpoint) : endpoint + end + proxy_owner.stop_points.between(departure, arrival).includes(:stop_area).collect(&:stop_area) end - proxy_owner.stop_points.between(departure, arrival).includes(:stop_area).collect(&:stop_area) end - end - accepts_nested_attributes_for :stop_points, :allow_destroy => :true + accepts_nested_attributes_for :stop_points, :allow_destroy => :true - validates_presence_of :name - validates_presence_of :published_name - validates_presence_of :line + validates_presence_of :name + validates_presence_of :published_name + validates_presence_of :line - # validates_presence_of :direction - # validates_presence_of :wayback + # validates_presence_of :direction + # validates_presence_of :wayback - validates :wayback, inclusion: { in: self.wayback.values } + validates :wayback, inclusion: { in: self.wayback.values } def duplicate overrides = { @@ -88,103 +90,114 @@ class Chouette::Route < Chouette::TridentActiveRecord new_route end - def duplicate_stop_points(for_route:) - stop_points.each(&duplicate_stop_point(for_route: for_route)) - end - def duplicate_stop_point(for_route:) - -> stop_point do - stop_point.duplicate(for_route: for_route) + def duplicate_stop_points(for_route:) + stop_points.each(&duplicate_stop_point(for_route: for_route)) + end + def duplicate_stop_point(for_route:) + -> stop_point do + stop_point.duplicate(for_route: for_route) + end end - end - def local_id - "IBOO-#{self.referential.id}-#{self.line.objectid.local_id}-#{self.id}" - end + def local_id + "IBOO-#{self.referential.id}-#{self.line.get_objectid.local_id}-#{self.id}" + end - def geometry_presenter - Chouette::Geometry::RoutePresenter.new self - end + def geometry_presenter + Chouette::Geometry::RoutePresenter.new self + end - @@opposite_waybacks = { outbound: :inbound, inbound: :outbound} - def opposite_wayback - @@opposite_waybacks[wayback.to_sym] - end + @@opposite_waybacks = { outbound: :inbound, inbound: :outbound} + def opposite_wayback + @@opposite_waybacks[wayback.to_sym] + end - def opposite_route_candidates - if opposite_wayback - line.routes.where(opposite_route: [nil, self], wayback: opposite_wayback) - else - self.class.none + def opposite_route_candidates + if opposite_wayback + line.routes.where(opposite_route: [nil, self], wayback: opposite_wayback) + else + self.class.none + end end - end - validate :check_opposite_route - def check_opposite_route - return unless opposite_route && opposite_wayback - unless opposite_route_candidates.include?(opposite_route) - errors.add(:opposite_route_id, :invalid) + validate :check_opposite_route + def check_opposite_route + return unless opposite_route && opposite_wayback + unless opposite_route_candidates.include?(opposite_route) + errors.add(:opposite_route_id, :invalid) + end end - end - def checksum_attributes - values = self.slice(*['name', 'published_name', 'wayback']).values - values.tap do |attrs| - attrs << self.stop_points.map{|sp| "#{sp.stop_area.user_objectid}#{sp.for_boarding}#{sp.for_alighting}" }.join - attrs << self.routing_constraint_zones.map(&:checksum) + def checksum_attributes + values = self.slice(*['name', 'published_name', 'wayback']).values + values.tap do |attrs| + attrs << self.stop_points.map{|sp| "#{sp.stop_area.user_objectid}#{sp.for_boarding}#{sp.for_alighting}" }.join + attrs << self.routing_constraint_zones.map(&:checksum) + end end - end - def geometry - points = stop_areas.map(&:to_lat_lng).compact.map do |loc| - [loc.lng, loc.lat] + def geometry + points = stop_areas.map(&:to_lat_lng).compact.map do |loc| + [loc.lng, loc.lat] + end + GeoRuby::SimpleFeatures::LineString.from_coordinates( points, 4326) end - GeoRuby::SimpleFeatures::LineString.from_coordinates( points, 4326) - end - def time_tables - vehicle_journeys.joins(:time_tables).map(&:"time_tables").flatten.uniq - end + def time_tables + vehicle_journeys.joins(:time_tables).map(&:"time_tables").flatten.uniq + end - def sorted_vehicle_journeys(journey_category_model) - send(journey_category_model) - .joins(:journey_pattern, :vehicle_journey_at_stops) - .joins('LEFT JOIN "time_tables_vehicle_journeys" ON "time_tables_vehicle_journeys"."vehicle_journey_id" = "vehicle_journeys"."id" LEFT JOIN "time_tables" ON "time_tables"."id" = "time_tables_vehicle_journeys"."time_table_id"') - .where("vehicle_journey_at_stops.stop_point_id=journey_patterns.departure_stop_point_id") - .order("vehicle_journey_at_stops.departure_time") - end + def sorted_vehicle_journeys(journey_category_model) + send(journey_category_model) + .joins(:journey_pattern, :vehicle_journey_at_stops) + .joins('LEFT JOIN "time_tables_vehicle_journeys" ON "time_tables_vehicle_journeys"."vehicle_journey_id" = "vehicle_journeys"."id" LEFT JOIN "time_tables" ON "time_tables"."id" = "time_tables_vehicle_journeys"."time_table_id"') + .where("vehicle_journey_at_stops.stop_point_id=journey_patterns.departure_stop_point_id") + .order("vehicle_journey_at_stops.departure_time") + end - def stop_point_permutation?( stop_point_ids) - stop_points.map(&:id).map(&:to_s).sort == stop_point_ids.map(&:to_s).sort - end + def stop_point_permutation?( stop_point_ids) + stop_points.map(&:id).map(&:to_s).sort == stop_point_ids.map(&:to_s).sort + end - def reorder!( stop_point_ids) - return false unless stop_point_permutation?( stop_point_ids) + def reorder!( stop_point_ids) + return false unless stop_point_permutation?( stop_point_ids) - stop_area_id_by_stop_point_id = {} - stop_points.each do |sp| - stop_area_id_by_stop_point_id.merge!( sp.id => sp.stop_area_id) - end + stop_area_id_by_stop_point_id = {} + stop_points.each do |sp| + stop_area_id_by_stop_point_id.merge!( sp.id => sp.stop_area_id) + end - reordered_stop_area_ids = [] - stop_point_ids.each do |stop_point_id| - reordered_stop_area_ids << stop_area_id_by_stop_point_id[ stop_point_id.to_i] + reordered_stop_area_ids = [] + stop_point_ids.each do |stop_point_id| + reordered_stop_area_ids << stop_area_id_by_stop_point_id[ stop_point_id.to_i] + end + + stop_points.each_with_index do |sp, index| + if sp.stop_area_id.to_s != reordered_stop_area_ids[ index].to_s + #result = sp.update_attributes( :stop_area_id => reordered_stop_area_ids[ index]) + sp.stop_area_id = reordered_stop_area_ids[ index] + result = sp.save! + end + end + + return true end - stop_points.each_with_index do |sp, index| - if sp.stop_area_id.to_s != reordered_stop_area_ids[ index].to_s - #result = sp.update_attributes( :stop_area_id => reordered_stop_area_ids[ index]) - sp.stop_area_id = reordered_stop_area_ids[ index] - result = sp.save! + def journey_patterns_control_route_sections + self.journey_patterns.each do |jp| + jp.control_route_sections end end - return true - end + protected +<<<<<<< HEAD + def self.vehicle_journeys_timeless(stop_point_id) + all( :conditions => ['vehicle_journeys.id NOT IN (?)', Chouette::VehicleJourneyAtStop.where(stop_point_id: stop_point_id).pluck(:vehicle_journey_id)] ) + end +======= protected +>>>>>>> master - def self.vehicle_journeys_timeless(stop_point_id) - all( :conditions => ['vehicle_journeys.id NOT IN (?)', Chouette::VehicleJourneyAtStop.where(stop_point_id: stop_point_id).pluck(:vehicle_journey_id)] ) end - -end +end
\ No newline at end of file diff --git a/app/models/chouette/route_section.rb b/app/models/chouette/route_section.rb new file mode 100644 index 000000000..e4b4347e7 --- /dev/null +++ b/app/models/chouette/route_section.rb @@ -0,0 +1,83 @@ +module Chouette + class RouteSection < Chouette::TridentActiveRecord + belongs_to :departure, class_name: 'Chouette::StopArea' + belongs_to :arrival, class_name: 'Chouette::StopArea' + has_many :journey_pattern_sections + has_many :journey_patterns, through: :journey_pattern_sections, dependent: :destroy + + validates :departure, :arrival, :processed_geometry, presence: true + + scope :by_endpoint_name, ->(endpoint, name) do + joins("INNER JOIN stop_areas #{endpoint} ON #{endpoint}.id = route_sections.#{endpoint}_id").where(["#{endpoint}.name ilike ?", "%#{name}%"]) + end + scope :by_line_id, ->(line_id) do + joins(:journey_pattern_sections, :journey_patterns).joins('INNER JOIN routes ON journey_patterns.route_id = routes.id').where("routes.line_id = #{line_id}") + end + + def stop_areas + [departure, arrival].compact + end + + def default_geometry + points = stop_areas.collect(&:geometry).compact + GeoRuby::SimpleFeatures::LineString.from_points(points) if points.many? + end + + def name + stop_areas.map do |stop_area| + stop_area.try(:name) or '?' + end.join(' - ') + " (#{geometry_description})" + end + + def via_count + input_geometry ? [ input_geometry.points.count - 2, 0 ].max : 0 + end + + def geometry_description + if input_geometry || processed_geometry + [ "#{distance.to_i}m" ].tap do |parts| + parts << "#{via_count} #{'via'.pluralize(via_count)}" if via_count > 0 + end.join(' - ') + else + "-" + end + end + + DEFAULT_PROCESSOR = Proc.new { |section| section.input_geometry || section.default_geometry.try(:to_rgeo) } + + @@processor = DEFAULT_PROCESSOR + cattr_accessor :processor + + def instance_processor + no_processing || processor.nil? ? DEFAULT_PROCESSOR : processor + end + + def process_geometry + if input_geometry_changed? || processed_geometry.nil? + self.processed_geometry = instance_processor.call(self) + self.distance = processed_geometry.to_georuby.to_wgs84.spherical_distance if processed_geometry + end + + true + end + before_validation :process_geometry + + def editable_geometry=(geometry) + self.input_geometry = geometry + end + + def editable_geometry + input_geometry.try(:to_georuby) or default_geometry + end + + def editable_geometry_before_type_cast + editable_geometry.to_ewkt + end + + def geometry(mode = nil) + mode ||= :processed + mode == :editable ? editable_geometry : processed_geometry.to_georuby + end + + end +end
\ No newline at end of file diff --git a/app/models/chouette/routing_constraint_zone.rb b/app/models/chouette/routing_constraint_zone.rb index efe1b7237..0691ef688 100644 --- a/app/models/chouette/routing_constraint_zone.rb +++ b/app/models/chouette/routing_constraint_zone.rb @@ -1,43 +1,46 @@ -class Chouette::RoutingConstraintZone < Chouette::TridentActiveRecord - include ChecksumSupport +module Chouette + class RoutingConstraintZone < Chouette::TridentActiveRecord + include ChecksumSupport + include ObjectidSupport - belongs_to :route - has_array_of :stop_points, class_name: 'Chouette::StopPoint' + belongs_to :route + has_array_of :stop_points, class_name: 'Chouette::StopPoint' - validates_presence_of :name, :stop_points, :route - # validates :stop_point_ids, length: { minimum: 2, too_short: I18n.t('activerecord.errors.models.routing_constraint_zone.attributes.stop_points.not_enough_stop_points') } - validate :stop_points_belong_to_route, :not_all_stop_points_selected + validates_presence_of :name, :stop_points, :route, :objectid_format + # validates :stop_point_ids, length: { minimum: 2, too_short: I18n.t('activerecord.errors.models.routing_constraint_zone.attributes.stop_points.not_enough_stop_points') } + validate :stop_points_belong_to_route, :not_all_stop_points_selected - def local_id - "IBOO-#{self.referential.id}-#{self.route.line.objectid.local_id}-#{self.route.objectid.local_id}-#{self.id}" - end + def local_id + "IBOO-#{self.referential.id}-#{self.route.line.objectid.local_id}-#{self.route.objectid.local_id}-#{self.id}" + end - scope :order_by_stop_points_count, ->(direction) do - order("array_length(stop_point_ids, 1) #{direction}") - end + scope :order_by_stop_points_count, ->(direction) do + order("array_length(stop_point_ids, 1) #{direction}") + end - scope :order_by_route_name, ->(direction) do - joins(:route) - .order("routes.name #{direction}") - end + scope :order_by_route_name, ->(direction) do + joins(:route) + .order("routes.name #{direction}") + end - def checksum_attributes - self.stop_points.map(&:stop_area).map(&:user_objectid) - end + def checksum_attributes + self.stop_points.map(&:stop_area).map(&:user_objectid) + end - def stop_points_belong_to_route - errors.add(:stop_point_ids, I18n.t('activerecord.errors.models.routing_constraint_zone.attributes.stop_points.stop_points_not_from_route')) unless stop_points.all? { |sp| route.stop_points.include? sp } - end + def stop_points_belong_to_route + errors.add(:stop_point_ids, I18n.t('activerecord.errors.models.routing_constraint_zone.attributes.stop_points.stop_points_not_from_route')) unless stop_points.all? { |sp| route.stop_points.include? sp } + end - def not_all_stop_points_selected - errors.add(:stop_point_ids, I18n.t('activerecord.errors.models.routing_constraint_zone.attributes.stop_points.all_stop_points_selected')) if stop_points.length == route.stop_points.length - end + def not_all_stop_points_selected + errors.add(:stop_point_ids, I18n.t('activerecord.errors.models.routing_constraint_zone.attributes.stop_points.all_stop_points_selected')) if stop_points.length == route.stop_points.length + end - def stop_points_count - stop_points.count - end + def stop_points_count + stop_points.count + end - def route_name - route.name + def route_name + route.name + end end -end +end
\ No newline at end of file diff --git a/app/models/chouette/source_type.rb b/app/models/chouette/source_type.rb index 124a6c433..1554d846b 100644 --- a/app/models/chouette/source_type.rb +++ b/app/models/chouette/source_type.rb @@ -1,56 +1,58 @@ -class Chouette::SourceType < ActiveSupport::StringInquirer +module Chouette + class SourceType < ActiveSupport::StringInquirer - def initialize(text_code, numerical_code) - super text_code.to_s - @numerical_code = numerical_code - end + def initialize(text_code, numerical_code) + super text_code.to_s + @numerical_code = numerical_code + end - def self.new(text_code, numerical_code = nil) - if text_code and numerical_code - super - elsif self === text_code - text_code - else - if Fixnum === text_code - text_code, numerical_code = definitions.rassoc(text_code) + def self.new(text_code, numerical_code = nil) + if text_code and numerical_code + super + elsif self === text_code + text_code else - text_code, numerical_code = definitions.assoc(text_code.to_s) - end + if Fixnum === text_code + text_code, numerical_code = definitions.rassoc(text_code) + else + text_code, numerical_code = definitions.assoc(text_code.to_s) + end - super text_code, numerical_code + super text_code, numerical_code + end end - end - def to_i - @numerical_code - end + def to_i + @numerical_code + end - def inspect - "#{to_s}/#{to_i}" - end + def inspect + "#{to_s}/#{to_i}" + end - def name - camelize - end + def name + camelize + end - @@definitions = [ - ["public_and_private_utilities", 0], - ["road_authorities", 1], - ["transit_operator", 2], - ["public_transport", 3], - ["passenger_transport_coordinating_authority", 4], - ["travel_information_service_provider", 5], - ["travel_agency", 6], - ["individual_subject_of_travel_itinerary", 7], - ["other_information", 8] - ] - cattr_reader :definitions - - @@all = nil - def self.all - @@all ||= definitions.collect do |text_code, numerical_code| - new(text_code, numerical_code) + @@definitions = [ + ["public_and_private_utilities", 0], + ["road_authorities", 1], + ["transit_operator", 2], + ["public_transport", 3], + ["passenger_transport_coordinating_authority", 4], + ["travel_information_service_provider", 5], + ["travel_agency", 6], + ["individual_subject_of_travel_itinerary", 7], + ["other_information", 8] + ] + cattr_reader :definitions + + @@all = nil + def self.all + @@all ||= definitions.collect do |text_code, numerical_code| + new(text_code, numerical_code) + end end - end -end + end +end
\ No newline at end of file diff --git a/app/models/chouette/stif_codifligne_objectid.rb b/app/models/chouette/stif_codifligne_objectid.rb deleted file mode 100644 index 46109e24f..000000000 --- a/app/models/chouette/stif_codifligne_objectid.rb +++ /dev/null @@ -1,18 +0,0 @@ -class Chouette::StifCodifligneObjectid < String - - @@format = /^([A-Za-z_]+):([A-Za-z]+):([A-Za-z]+):([0-9A-Za-z_-]+)$/ - cattr_reader :format - - def parts - match(format).try(:captures) - end - - def object_type - parts.try(:third) - end - - def local_id - parts.try(:fourth) - end - -end diff --git a/app/models/chouette/stif_netex_objectid.rb b/app/models/chouette/stif_netex_objectid.rb deleted file mode 100644 index 93e7a1e85..000000000 --- a/app/models/chouette/stif_netex_objectid.rb +++ /dev/null @@ -1,42 +0,0 @@ -class Chouette::StifNetexObjectid < String - def valid? - parts.present? - end - - @@format = /^([A-Za-z_-]+):([A-Za-z]+):([0-9A-Za-z_-]+):([A-Za-z]+)$/ - cattr_reader :format - - def parts - match(format).try(:captures) - end - - def provider_id - parts.try(:first) - end - - def object_type - parts.try(:second) - end - - def local_id - parts.try(:third) - end - - def boiv_id - parts.try(:fourth) - end - - def short_id - local_id.try(:split, "-").try(:[], -1) - end - - def self.create(provider_id, object_type, local_id, boiv_id) - new [provider_id, object_type, local_id, boiv_id].join(":") - end - - def self.new(string) - string ||= "" - self === string ? string : super - end - -end diff --git a/app/models/chouette/stif_reflex_objectid.rb b/app/models/chouette/stif_reflex_objectid.rb deleted file mode 100644 index c41a9325a..000000000 --- a/app/models/chouette/stif_reflex_objectid.rb +++ /dev/null @@ -1,18 +0,0 @@ -class Chouette::StifReflexObjectid < String - - @@format = /^([A-Za-z_]+):([0-9A-Za-z_-]+):([A-Za-z]+):([0-9A-Za-z_-]+):([A-Za-z]+)$/ - cattr_reader :format - - def parts - match(format).try(:captures) - end - - def object_type - parts.try(:third) - end - - def local_id - parts.try(:fourth) - end - -end diff --git a/app/models/chouette/stop_area.rb b/app/models/chouette/stop_area.rb index 43bc82f7f..f907f6777 100644 --- a/app/models/chouette/stop_area.rb +++ b/app/models/chouette/stop_area.rb @@ -1,333 +1,336 @@ require 'geokit' require 'geo_ruby' -class Chouette::StopArea < Chouette::ActiveRecord - # FIXME http://jira.codehaus.org/browse/JRUBY-6358 - self.primary_key = "id" - - include Geokit::Mappable - include StifReflexAttributesSupport - include ProjectionFields - include StopAreaRestrictions - include StopAreaReferentialSupport - - extend Enumerize - enumerize :area_type, in: %i(zdep zder zdlp zdlr lda) - - with_options dependent: :destroy do |assoc| - assoc.has_many :stop_points - assoc.has_many :access_points - assoc.has_many :access_links - end - - has_and_belongs_to_many :routing_lines, :class_name => 'Chouette::Line', :foreign_key => "stop_area_id", :association_foreign_key => "line_id", :join_table => "routing_constraints_lines", :order => "lines.number" - has_and_belongs_to_many :routing_stops, :class_name => 'Chouette::StopArea', :foreign_key => "parent_id", :association_foreign_key => "child_id", :join_table => "stop_areas_stop_areas", :order => "stop_areas.name" - - belongs_to :stop_area_referential - validates_presence_of :stop_area_referential_id +module Chouette + class StopArea < Chouette::ActiveRecord + # FIXME http://jira.codehaus.org/browse/JRUBY-6358 + self.primary_key = "id" + + include Geokit::Mappable + # include StifReflexAttributesSupport + include ProjectionFields + include StopAreaRestrictions + include StopAreaReferentialSupport + include ObjectidSupport + + extend Enumerize + enumerize :area_type, in: %i(zdep zder zdlp zdlr lda) + + with_options dependent: :destroy do |assoc| + assoc.has_many :stop_points + assoc.has_many :access_points + assoc.has_many :access_links + end - acts_as_tree :foreign_key => 'parent_id', :order => "name" + has_and_belongs_to_many :routing_lines, :class_name => 'Chouette::Line', :foreign_key => "stop_area_id", :association_foreign_key => "line_id", :join_table => "routing_constraints_lines", :order => "lines.number" + has_and_belongs_to_many :routing_stops, :class_name => 'Chouette::StopArea', :foreign_key => "parent_id", :association_foreign_key => "child_id", :join_table => "stop_areas_stop_areas", :order => "stop_areas.name" - attr_accessor :stop_area_type - attr_accessor :children_ids - attr_writer :coordinates + belongs_to :stop_area_referential + validates_presence_of :stop_area_referential_id - after_update :journey_patterns_control_route_sections, - if: Proc.new { |stop_area| ['boarding_position', 'quay'].include? stop_area.stop_area_type } + acts_as_tree :foreign_key => 'parent_id', :order => "name" - validates_format_of :registration_number, :with => %r{\A[\d\w_\-]+\Z}, :allow_blank => true - validates_presence_of :name - validates_presence_of :latitude, :if => :longitude - validates_presence_of :longitude, :if => :latitude - validates_numericality_of :latitude, :less_than_or_equal_to => 90, :greater_than_or_equal_to => -90, :allow_nil => true - validates_numericality_of :longitude, :less_than_or_equal_to => 180, :greater_than_or_equal_to => -180, :allow_nil => true + attr_accessor :stop_area_type + attr_accessor :children_ids + attr_writer :coordinates - 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 + after_update :journey_patterns_control_route_sections, + if: Proc.new { |stop_area| ['boarding_position', 'quay'].include? stop_area.stop_area_type } - 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 + validates_format_of :registration_number, :with => %r{\A[\d\w_\-]+\Z}, :allow_blank => true + validates_presence_of :name + validates_presence_of :latitude, :if => :longitude + validates_presence_of :longitude, :if => :latitude + validates_numericality_of :latitude, :less_than_or_equal_to => 90, :greater_than_or_equal_to => -90, :allow_nil => true + validates_numericality_of :longitude, :less_than_or_equal_to => 180, :greater_than_or_equal_to => -180, :allow_nil => true - after_update :clean_invalid_access_links - before_save :coordinates_to_lat_lng + 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 - def combine_lat_lng - if self.latitude.nil? || self.longitude.nil? - "" - else - self.latitude.to_s+","+self.longitude.to_s + 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 - end - def coordinates - @coordinates || combine_lat_lng - end + after_update :clean_invalid_access_links + before_save :coordinates_to_lat_lng - def coordinates_to_lat_lng - if ! @coordinates.nil? - if @coordinates.empty? - self.latitude = nil - self.longitude = nil + def combine_lat_lng + if self.latitude.nil? || self.longitude.nil? + "" else - self.latitude = BigDecimal.new(@coordinates.split(",").first) - self.longitude = BigDecimal.new(@coordinates.split(",").last) + self.latitude.to_s+","+self.longitude.to_s end - @coordinates = nil end - end - def user_objectid - if objectid =~ /^.*:([0-9A-Za-z_-]+):STIF$/ - $1 - else - id.to_s + def coordinates + @coordinates || combine_lat_lng + end + + def coordinates_to_lat_lng + if ! @coordinates.nil? + if @coordinates.empty? + self.latitude = nil + self.longitude = nil + else + self.latitude = BigDecimal.new(@coordinates.split(",").first) + self.longitude = BigDecimal.new(@coordinates.split(",").last) + end + @coordinates = nil + end end - end - def children_in_depth - return [] if self.children.empty? + def user_objectid + if objectid =~ /^.*:([0-9A-Za-z_-]+):STIF$/ + $1 + else + id.to_s + end + end - self.children + self.children.map do |child| - child.children_in_depth - end.flatten.compact - end + def children_in_depth + return [] if self.children.empty? - def possible_children - case area_type - when "BoardingPosition" then [] - when "Quay" then [] - when "CommercialStopPoint" then Chouette::StopArea.where(:area_type => ['Quay', 'BoardingPosition']) - [self] - when "StopPlace" then Chouette::StopArea.where(:area_type => ['StopPlace', 'CommercialStopPoint']) - [self] + self.children + self.children.map do |child| + child.children_in_depth + end.flatten.compact end - end + def possible_children + case area_type + when "BoardingPosition" then [] + when "Quay" then [] + when "CommercialStopPoint" then Chouette::StopArea.where(:area_type => ['Quay', 'BoardingPosition']) - [self] + when "StopPlace" then Chouette::StopArea.where(:area_type => ['StopPlace', 'CommercialStopPoint']) - [self] + end - def possible_parents - case area_type - when "BoardingPosition" then Chouette::StopArea.where(:area_type => "CommercialStopPoint") - [self] - when "Quay" then Chouette::StopArea.where(:area_type => "CommercialStopPoint") - [self] - when "CommercialStopPoint" then Chouette::StopArea.where(:area_type => "StopPlace") - [self] - when "StopPlace" then Chouette::StopArea.where(:area_type => "StopPlace") - [self] end - end - def geometry_presenter - Chouette::Geometry::StopAreaPresenter.new self - end + def possible_parents + case area_type + when "BoardingPosition" then Chouette::StopArea.where(:area_type => "CommercialStopPoint") - [self] + when "Quay" then Chouette::StopArea.where(:area_type => "CommercialStopPoint") - [self] + when "CommercialStopPoint" then Chouette::StopArea.where(:area_type => "StopPlace") - [self] + when "StopPlace" then Chouette::StopArea.where(:area_type => "StopPlace") - [self] + end + end - def lines - [] - end + def geometry_presenter + Chouette::Geometry::StopAreaPresenter.new self + end - def routes - [] - end + def lines + [] + end - def self.commercial - where :area_type => "CommercialStopPoint" - end + def routes + [] + end - def self.stop_place - where :area_type => "StopPlace" - end + def self.commercial + where :area_type => "CommercialStopPoint" + end - def self.physical - where :area_type => [ "BoardingPosition", "Quay" ] - end + def self.stop_place + where :area_type => "StopPlace" + end + def self.physical + where :area_type => [ "BoardingPosition", "Quay" ] + end - def to_lat_lng - Geokit::LatLng.new(latitude, longitude) if latitude and longitude - end - def geometry - GeoRuby::SimpleFeatures::Point.from_lon_lat(longitude, latitude, 4326) if latitude and longitude - end + def to_lat_lng + Geokit::LatLng.new(latitude, longitude) if latitude and longitude + end - def geometry=(geometry) - geometry = geometry.to_wgs84 - self.latitude, self.longitude, self.long_lat_type = geometry.lat, geometry.lng, "WGS84" - end + def geometry + GeoRuby::SimpleFeatures::Point.from_lon_lat(longitude, latitude, 4326) if latitude and longitude + end - def position - geometry - end + def geometry=(geometry) + geometry = geometry.to_wgs84 + self.latitude, self.longitude, self.long_lat_type = geometry.lat, geometry.lng, "WGS84" + end - def position=(position) - position = nil if String === position && position == "" - position = Geokit::LatLng.normalize(position), 4326 if String === position - if position - self.latitude = position.lat - self.longitude = position.lng + def position + geometry end - end - def default_position - # for first StopArea ... the bounds is nil :( - Chouette::StopArea.bounds ? Chouette::StopArea.bounds.center : nil # FIXME #821 stop_area_referential.envelope.center - end + def position=(position) + position = nil if String === position && position == "" + position = Geokit::LatLng.normalize(position), 4326 if String === position + if position + self.latitude = position.lat + self.longitude = position.lng + end + end - def around(scope, distance) - db = "ST_GeomFromEWKB(ST_MakePoint(longitude, latitude, 4326))" - from = "ST_GeomFromText('POINT(#{self.longitude} #{self.latitude})', 4326)" - scope.where("ST_DWithin(#{db}, #{from}, ?, false)", distance) - end + def default_position + # for first StopArea ... the bounds is nil :( + Chouette::StopArea.bounds ? Chouette::StopArea.bounds.center : nil # FIXME #821 stop_area_referential.envelope.center + end - def self.near(origin, distance = 0.3) - origin = origin.to_lat_lng + def around(scope, distance) + db = "ST_GeomFromEWKB(ST_MakePoint(longitude, latitude, 4326))" + from = "ST_GeomFromText('POINT(#{self.longitude} #{self.latitude})', 4326)" + scope.where("ST_DWithin(#{db}, #{from}, ?, false)", distance) + end - lat_degree_units = units_per_latitude_degree(:kms) - lng_degree_units = units_per_longitude_degree(origin.lat, :kms) + def self.near(origin, distance = 0.3) + origin = origin.to_lat_lng - where "SQRT(POW(#{lat_degree_units}*(#{origin.lat}-latitude),2)+POW(#{lng_degree_units}*(#{origin.lng}-longitude),2)) <= #{distance}" - end + lat_degree_units = units_per_latitude_degree(:kms) + lng_degree_units = units_per_longitude_degree(origin.lat, :kms) - def self.bounds - # Give something like : - # [["113.5292500000000000", "22.1127580000000000", "113.5819330000000000", "22.2157050000000000"]] - min_and_max = connection.select_rows("select min(longitude) as min_lon, min(latitude) as min_lat, max(longitude) as max_lon, max(latitude) as max_lat from #{table_name} where latitude is not null and longitude is not null").first - return nil unless min_and_max + where "SQRT(POW(#{lat_degree_units}*(#{origin.lat}-latitude),2)+POW(#{lng_degree_units}*(#{origin.lng}-longitude),2)) <= #{distance}" + end - # Ignore [nil, nil, nil, nil] - min_and_max.compact! - return nil unless min_and_max.size == 4 + def self.bounds + # Give something like : + # [["113.5292500000000000", "22.1127580000000000", "113.5819330000000000", "22.2157050000000000"]] + min_and_max = connection.select_rows("select min(longitude) as min_lon, min(latitude) as min_lat, max(longitude) as max_lon, max(latitude) as max_lat from #{table_name} where latitude is not null and longitude is not null").first + return nil unless min_and_max - min_and_max.collect! { |n| n.to_f } + # Ignore [nil, nil, nil, nil] + min_and_max.compact! + return nil unless min_and_max.size == 4 - # We need something like : - # [[113.5292500000000000, 22.1127580000000000], [113.5819330000000000, 22.2157050000000000]] - coordinates = min_and_max.each_slice(2).to_a - GeoRuby::SimpleFeatures::Envelope.from_coordinates coordinates - end + min_and_max.collect! { |n| n.to_f } - def stop_area_type - area_type ? area_type : " " - end + # We need something like : + # [[113.5292500000000000, 22.1127580000000000], [113.5819330000000000, 22.2157050000000000]] + coordinates = min_and_max.each_slice(2).to_a + GeoRuby::SimpleFeatures::Envelope.from_coordinates coordinates + end - def stop_area_type=(stop_area_type) - self.area_type = (stop_area_type ? stop_area_type.camelcase : nil) - end + def stop_area_type + area_type ? area_type : " " + end - def children_ids=(children_ids) - children = children_ids.split(',').uniq - # remove unset children - self.children.each do |child| - if (! children.include? child.id) - child.update_attribute :parent_id, nil - end + def stop_area_type=(stop_area_type) + self.area_type = (stop_area_type ? stop_area_type.camelcase : nil) end - # add new children - Chouette::StopArea.find(children).each do |child| - child.update_attribute :parent_id, self.id + + def children_ids=(children_ids) + children = children_ids.split(',').uniq + # remove unset children + self.children.each do |child| + if (! children.include? child.id) + child.update_attribute :parent_id, nil + end + end + # add new children + Chouette::StopArea.find(children).each do |child| + child.update_attribute :parent_id, self.id + end end - end - def routing_stop_ids=(routing_stop_ids) - stops = routing_stop_ids.split(',').uniq - self.routing_stops.clear - Chouette::StopArea.find(stops).each do |stop| - self.routing_stops << stop + def routing_stop_ids=(routing_stop_ids) + stops = routing_stop_ids.split(',').uniq + self.routing_stops.clear + Chouette::StopArea.find(stops).each do |stop| + self.routing_stops << stop + end end - end - def routing_line_ids=(routing_line_ids) - lines = routing_line_ids.split(',').uniq - self.routing_lines.clear - Chouette::Line.find(lines).each do |line| - self.routing_lines << line + def routing_line_ids=(routing_line_ids) + lines = routing_line_ids.split(',').uniq + self.routing_lines.clear + Chouette::Line.find(lines).each do |line| + self.routing_lines << line + end end - end - def self.without_geometry - where("latitude is null or longitude is null") - end + def self.without_geometry + where("latitude is null or longitude is null") + end - def self.with_geometry - where("latitude is not null and longitude is not null") - end + def self.with_geometry + where("latitude is not null and longitude is not null") + end - def self.default_geometry! - count = 0 - where(nil).find_each do |stop_area| - Chouette::StopArea.unscoped do - count += 1 if stop_area.default_geometry! + def self.default_geometry! + count = 0 + where(nil).find_each do |stop_area| + Chouette::StopArea.unscoped do + count += 1 if stop_area.default_geometry! + end end + count end - count - end - - def default_geometry! - new_geometry = default_geometry - update_attribute :geometry, new_geometry if new_geometry - end - def default_geometry - children_geometries = children.with_geometry.map(&:geometry).uniq - GeoRuby::SimpleFeatures::Point.centroid children_geometries if children_geometries.present? - end + def default_geometry! + new_geometry = default_geometry + update_attribute :geometry, new_geometry if new_geometry + end - def generic_access_link_matrix - matrix = Array.new - access_points.each do |access_point| - matrix += access_point.generic_access_link_matrix - end - matrix - end + def default_geometry + children_geometries = children.with_geometry.map(&:geometry).uniq + GeoRuby::SimpleFeatures::Point.centroid children_geometries if children_geometries.present? + end - def detail_access_link_matrix - matrix = Array.new - access_points.each do |access_point| - matrix += access_point.detail_access_link_matrix - end - matrix - end + def generic_access_link_matrix + matrix = Array.new + access_points.each do |access_point| + matrix += access_point.generic_access_link_matrix + end + matrix + end - def children_at_base - list = Array.new - children_in_depth.each do |child| - if child.area_type == 'Quay' || child.area_type == 'BoardingPosition' - list << child + def detail_access_link_matrix + matrix = Array.new + access_points.each do |access_point| + matrix += access_point.detail_access_link_matrix end + matrix end - list - end - def parents - list = Array.new - if !parent.nil? - list << parent - list += parent.parents + def children_at_base + list = Array.new + children_in_depth.each do |child| + if child.area_type == 'Quay' || child.area_type == 'BoardingPosition' + list << child + end + end + list end - list - end - def clean_invalid_access_links - stop_parents = parents - access_links.each do |link| - unless stop_parents.include? link.access_point.stop_area - link.delete + def parents + list = Array.new + if !parent.nil? + list << parent + list += parent.parents end + list end - children.each do |child| - child.clean_invalid_access_links + + def clean_invalid_access_links + stop_parents = parents + access_links.each do |link| + unless stop_parents.include? link.access_point.stop_area + link.delete + end + end + children.each do |child| + child.clean_invalid_access_links + end end - end - def duplicate - sa = self.deep_clone :except => [:object_version, :parent_id, :registration_number] - sa.uniq_objectid - sa.name = I18n.t("activerecord.copy", :name => self.name) - sa - end + def duplicate + sa = self.deep_clone :except => [:object_version, :parent_id, :registration_number] + sa.uniq_objectid + sa.name = I18n.t("activerecord.copy", :name => self.name) + sa + end - def journey_patterns_control_route_sections - if self.changed_attributes['latitude'] || self.changed_attributes['longitude'] - self.stop_points.each do |stop_point| - stop_point.route.journey_patterns.completed.map{ |jp| jp.control! } + def journey_patterns_control_route_sections + if self.changed_attributes['latitude'] || self.changed_attributes['longitude'] + self.stop_points.each do |stop_point| + stop_point.route.journey_patterns.completed.map{ |jp| jp.control! } + end end end - end -end + end +end
\ No newline at end of file diff --git a/app/models/chouette/stop_point.rb b/app/models/chouette/stop_point.rb index 89c492b91..f4c9b3800 100644 --- a/app/models/chouette/stop_point.rb +++ b/app/models/chouette/stop_point.rb @@ -1,5 +1,5 @@ module Chouette - class StopPoint < TridentActiveRecord + class StopPoint < Chouette::TridentActiveRecord def self.policy_class RoutePolicy @@ -7,6 +7,7 @@ module Chouette include ForBoardingEnumerations include ForAlightingEnumerations + include ObjectidSupport # FIXME http://jira.codehaus.org/browse/JRUBY-6358 self.primary_key = "id" @@ -18,6 +19,7 @@ module Chouette acts_as_list :scope => :route, top_of_list: 0 + validates_presence_of :stop_area validate :stop_area_id_validation def stop_area_id_validation @@ -47,9 +49,12 @@ module Chouette self.class.create!(atts_for_create) end + def local_id + "IBOO-#{self.referential.id}-#{self.route.line.get_objectid.local_id}-#{self.route.id}-#{self.id}" + end + def self.area_candidates Chouette::StopArea.where(:area_type => ['Quay', 'BoardingPosition']) end - end -end +end
\ No newline at end of file diff --git a/app/models/chouette/time_table.rb b/app/models/chouette/time_table.rb index 72496273e..172b73101 100644 --- a/app/models/chouette/time_table.rb +++ b/app/models/chouette/time_table.rb @@ -1,570 +1,574 @@ -class Chouette::TimeTable < Chouette::TridentActiveRecord - include ChecksumSupport - include TimeTableRestrictions - # FIXME http://jira.codehaus.org/browse/JRUBY-6358 - self.primary_key = "id" +module Chouette + class TimeTable < Chouette::TridentActiveRecord + include ChecksumSupport + include TimeTableRestrictions + include ObjectidSupport + # FIXME http://jira.codehaus.org/browse/JRUBY-6358 + self.primary_key = "id" - acts_as_taggable + acts_as_taggable - attr_accessor :monday,:tuesday,:wednesday,:thursday,:friday,:saturday,:sunday - attr_accessor :tag_search + attr_accessor :monday,:tuesday,:wednesday,:thursday,:friday,:saturday,:sunday + attr_accessor :tag_search - def self.ransackable_attributes auth_object = nil - (column_names + ['tag_search']) + _ransackers.keys - end + def self.ransackable_attributes auth_object = nil + (column_names + ['tag_search']) + _ransackers.keys + end - has_and_belongs_to_many :vehicle_journeys, :class_name => 'Chouette::VehicleJourney' + has_and_belongs_to_many :vehicle_journeys, :class_name => 'Chouette::VehicleJourney' - has_many :dates, -> {order(:date)}, inverse_of: :time_table, :validate => :true, :class_name => "Chouette::TimeTableDate", :dependent => :destroy - has_many :periods, -> {order(:period_start)}, inverse_of: :time_table, :validate => :true, :class_name => "Chouette::TimeTablePeriod", :dependent => :destroy + has_many :dates, -> {order(:date)}, inverse_of: :time_table, :validate => :true, :class_name => "Chouette::TimeTableDate", :dependent => :destroy + has_many :periods, -> {order(:period_start)}, inverse_of: :time_table, :validate => :true, :class_name => "Chouette::TimeTablePeriod", :dependent => :destroy - belongs_to :calendar - belongs_to :created_from, class_name: 'Chouette::TimeTable' + belongs_to :calendar + belongs_to :created_from, class_name: 'Chouette::TimeTable' - scope :overlapping, -> (period_range) do - joins(" - LEFT JOIN time_table_periods ON time_tables.id = time_table_periods.time_table_id - LEFT JOIN time_table_dates ON time_tables.id = time_table_dates.time_table_id - ") - .where("(time_table_periods.period_start <= :end AND time_table_periods.period_end >= :begin) OR (time_table_dates.date BETWEEN :begin AND :end)", {begin: period_range.begin, end: period_range.end}) - end + scope :overlapping, -> (period_range) do + joins(" + LEFT JOIN time_table_periods ON time_tables.id = time_table_periods.time_table_id + LEFT JOIN time_table_dates ON time_tables.id = time_table_dates.time_table_id + ") + .where("(time_table_periods.period_start <= :end AND time_table_periods.period_end >= :begin) OR (time_table_dates.date BETWEEN :begin AND :end)", {begin: period_range.begin, end: period_range.end}) + end - after_save :save_shortcuts + after_save :save_shortcuts - def local_id - "IBOO-#{self.referential.id}-#{self.id}" - end + def local_id + "IBOO-#{self.referential.id}-#{self.id}" + end - def checksum_attributes - [].tap do |attrs| - attrs << self.int_day_types - attrs << self.dates.map(&:checksum).map(&:to_s).sort - attrs << self.periods.map(&:checksum).map(&:to_s).sort + def checksum_attributes + [].tap do |attrs| + attrs << self.int_day_types + attrs << self.dates.map(&:checksum).map(&:to_s).sort + attrs << self.periods.map(&:checksum).map(&:to_s).sort + end end - end - def self.object_id_key - "Timetable" - end + def self.object_id_key + "Timetable" + end - accepts_nested_attributes_for :dates, :allow_destroy => :true - accepts_nested_attributes_for :periods, :allow_destroy => :true - - validates_presence_of :comment - validates_associated :dates - validates_associated :periods - - def continuous_dates - in_days = self.dates.where(in_out: true).sort_by(&:date) - chunk = {} - group = nil - in_days.each_with_index do |date, index| - group ||= index - group = (date.date == in_days[index - 1].date + 1.day) ? group : group + 1 - chunk[group] ||= [] - chunk[group] << date - end - # Remove less than 2 continuous day chunk - chunk.values.delete_if {|dates| dates.count < 2} - end + accepts_nested_attributes_for :dates, :allow_destroy => :true + accepts_nested_attributes_for :periods, :allow_destroy => :true + + validates_presence_of :comment + validates_presence_of :objectid_format + validates_associated :dates + validates_associated :periods + + def continuous_dates + in_days = self.dates.where(in_out: true).sort_by(&:date) + chunk = {} + group = nil + in_days.each_with_index do |date, index| + group ||= index + group = (date.date == in_days[index - 1].date + 1.day) ? group : group + 1 + chunk[group] ||= [] + chunk[group] << date + end + # Remove less than 2 continuous day chunk + chunk.values.delete_if {|dates| dates.count < 2} + end - def convert_continuous_dates_to_periods - chunks = self.continuous_dates + def convert_continuous_dates_to_periods + chunks = self.continuous_dates - transaction do - chunks.each do |chunk| - self.periods.create!(period_start: chunk.first.date, period_end: chunk.last.date) - self.dates.delete(chunk) + transaction do + chunks.each do |chunk| + self.periods.create!(period_start: chunk.first.date, period_end: chunk.last.date) + self.dates.delete(chunk) + end end end - end - def state_update state - update_attributes(self.class.state_permited_attributes(state)) - self.tag_list = state['tags'].collect{|t| t['name']}.join(', ') - self.calendar_id = nil unless state['calendar'] + def state_update state + update_attributes(self.class.state_permited_attributes(state)) + self.tag_list = state['tags'].collect{|t| t['name']}.join(', ') + self.calendar_id = nil unless state['calendar'] - days = state['day_types'].split(',') - Date::DAYNAMES.map(&:underscore).each do |name| - prefix = human_attribute_name(name).first(2) - send("#{name}=", days.include?(prefix)) - end + days = state['day_types'].split(',') + Date::DAYNAMES.map(&:underscore).each do |name| + prefix = human_attribute_name(name).first(2) + send("#{name}=", days.include?(prefix)) + end - saved_dates = Hash[self.dates.collect{ |d| [d.id, d.date]}] - cmonth = Date.parse(state['current_periode_range']) + saved_dates = Hash[self.dates.collect{ |d| [d.id, d.date]}] + cmonth = Date.parse(state['current_periode_range']) - state['current_month'].each do |d| - date = Date.parse(d['date']) - checked = d['include_date'] || d['excluded_date'] - in_out = d['include_date'] ? true : false + state['current_month'].each do |d| + date = Date.parse(d['date']) + checked = d['include_date'] || d['excluded_date'] + in_out = d['include_date'] ? true : false - date_id = saved_dates.key(date) - time_table_date = self.dates.find(date_id) if date_id + date_id = saved_dates.key(date) + time_table_date = self.dates.find(date_id) if date_id - next if !checked && !time_table_date - # Destroy date if no longer checked - next if !checked && time_table_date.destroy + next if !checked && !time_table_date + # Destroy date if no longer checked + next if !checked && time_table_date.destroy - # Create new date - unless time_table_date - time_table_date = self.dates.create({in_out: in_out, date: date}) - end - # Update in_out - if in_out != time_table_date.in_out - time_table_date.update_attributes({in_out: in_out}) + # Create new date + unless time_table_date + time_table_date = self.dates.create({in_out: in_out, date: date}) + end + # Update in_out + if in_out != time_table_date.in_out + time_table_date.update_attributes({in_out: in_out}) + end end - end - self.state_update_periods state['time_table_periods'] - self.save - end + self.state_update_periods state['time_table_periods'] + self.save + end - def state_update_periods state_periods - state_periods.each do |item| - period = self.periods.find(item['id']) if item['id'] - next if period && item['deleted'] && period.destroy - period ||= self.periods.build + def state_update_periods state_periods + state_periods.each do |item| + period = self.periods.find(item['id']) if item['id'] + next if period && item['deleted'] && period.destroy + period ||= self.periods.build - period.period_start = Date.parse(item['period_start']) - period.period_end = Date.parse(item['period_end']) + period.period_start = Date.parse(item['period_start']) + period.period_end = Date.parse(item['period_end']) - if period.changed? - period.save - item['id'] = period.id + if period.changed? + period.save + item['id'] = period.id + end end + + state_periods.delete_if {|item| item['deleted']} end - state_periods.delete_if {|item| item['deleted']} - end + def self.state_permited_attributes item + item.slice('comment', 'color').to_hash + end - def self.state_permited_attributes item - item.slice('comment', 'color').to_hash - end + def presenter + @presenter ||= ::TimeTablePresenter.new( self) + end - def presenter - @presenter ||= ::TimeTablePresenter.new( self) - end + def self.start_validity_period + [Chouette::TimeTable.minimum(:start_date)].compact.min + end + def self.end_validity_period + [Chouette::TimeTable.maximum(:end_date)].compact.max + end - def self.start_validity_period - [Chouette::TimeTable.minimum(:start_date)].compact.min - end - def self.end_validity_period - [Chouette::TimeTable.maximum(:end_date)].compact.max - end + def add_exclude_date(in_out, date) + self.dates.create!({in_out: in_out, date: date}) + end - def add_exclude_date(in_out, date) - self.dates.create!({in_out: in_out, date: date}) - end + def actualize + self.dates.clear + self.periods.clear + from = self.calendar.convert_to_time_table + self.dates = from.dates + self.periods = from.periods + self.save + end - def actualize - self.dates.clear - self.periods.clear - from = self.calendar.convert_to_time_table - self.dates = from.dates - self.periods = from.periods - self.save - end + def month_inspect(date) + (date.beginning_of_month..date.end_of_month).map do |d| + { + day: I18n.l(d, format: '%A'), + date: d.to_s, + wday: d.wday, + wnumber: d.strftime("%W").to_s, + mday: d.mday, + include_date: include_in_dates?(d), + excluded_date: excluded_date?(d) + } + end + end - def month_inspect(date) - (date.beginning_of_month..date.end_of_month).map do |d| - { - day: I18n.l(d, format: '%A'), - date: d.to_s, - wday: d.wday, - wnumber: d.strftime("%W").to_s, - mday: d.mday, - include_date: include_in_dates?(d), - excluded_date: excluded_date?(d) - } + def save_shortcuts + shortcuts_update + self.update_column(:start_date, start_date) + self.update_column(:end_date, end_date) end - end - def save_shortcuts - shortcuts_update - self.update_column(:start_date, start_date) - self.update_column(:end_date, end_date) - end + def shortcuts_update(date=nil) + dates_array = bounding_dates + #if new_record? + if dates_array.empty? + self.start_date=nil + self.end_date=nil + else + self.start_date=dates_array.min + self.end_date=dates_array.max + end + #else + # if dates_array.empty? + # update_attributes :start_date => nil, :end_date => nil + # else + # update_attributes :start_date => dates_array.min, :end_date => dates_array.max + # end + #end + end - def shortcuts_update(date=nil) - dates_array = bounding_dates - #if new_record? - if dates_array.empty? - self.start_date=nil - self.end_date=nil + def validity_out_from_on?(expected_date) + return false unless self.end_date + self.end_date <= expected_date + end + + def validity_out_between?(starting_date, ending_date) + return false unless self.start_date + starting_date < self.end_date && + self.end_date <= ending_date + end + def self.validity_out_from_on?(expected_date,limit=0) + if limit==0 + Chouette::TimeTable.where("end_date <= ?", expected_date) else - self.start_date=dates_array.min - self.end_date=dates_array.max + Chouette::TimeTable.where("end_date <= ?", expected_date).limit( limit) end - #else - # if dates_array.empty? - # update_attributes :start_date => nil, :end_date => nil - # else - # update_attributes :start_date => dates_array.min, :end_date => dates_array.max - # end - #end - end - - def validity_out_from_on?(expected_date) - return false unless self.end_date - self.end_date <= expected_date - end - - def validity_out_between?(starting_date, ending_date) - return false unless self.start_date - starting_date < self.end_date && - self.end_date <= ending_date - end - def self.validity_out_from_on?(expected_date,limit=0) - if limit==0 - Chouette::TimeTable.where("end_date <= ?", expected_date) - else - Chouette::TimeTable.where("end_date <= ?", expected_date).limit( limit) end - end - def self.validity_out_between?(start_date, end_date,limit=0) - if limit==0 - Chouette::TimeTable.where( "? < end_date", start_date).where( "end_date <= ?", end_date) - else - Chouette::TimeTable.where( "? < end_date", start_date).where( "end_date <= ?", end_date).limit( limit) + def self.validity_out_between?(start_date, end_date,limit=0) + if limit==0 + Chouette::TimeTable.where( "? < end_date", start_date).where( "end_date <= ?", end_date) + else + Chouette::TimeTable.where( "? < end_date", start_date).where( "end_date <= ?", end_date).limit( limit) + end end - end - # Return days which intersects with the time table dates and periods - def intersects(days) - [].tap do |intersect_days| - days.each do |day| - intersect_days << day if include_day?(day) + # Return days which intersects with the time table dates and periods + def intersects(days) + [].tap do |intersect_days| + days.each do |day| + intersect_days << day if include_day?(day) + end end end - end - def include_day?(day) - include_in_dates?(day) || include_in_periods?(day) - end + def include_day?(day) + include_in_dates?(day) || include_in_periods?(day) + end - def include_in_dates?(day) - self.dates.any?{ |d| d.date === day && d.in_out == true } - end + def include_in_dates?(day) + self.dates.any?{ |d| d.date === day && d.in_out == true } + end - def excluded_date?(day) - self.dates.any?{ |d| d.date === day && d.in_out == false } - end + def excluded_date?(day) + self.dates.any?{ |d| d.date === day && d.in_out == false } + end - def include_in_periods?(day) - self.periods.any?{ |period| period.period_start <= day && - day <= period.period_end && - valid_days.include?(day.cwday) && - ! excluded_date?(day) } - end + def include_in_periods?(day) + self.periods.any?{ |period| period.period_start <= day && + day <= period.period_end && + valid_days.include?(day.cwday) && + ! excluded_date?(day) } + end - def include_in_overlap_dates?(day) - return false if self.excluded_date?(day) + def include_in_overlap_dates?(day) + return false if self.excluded_date?(day) - counter = self.dates.select{ |d| d.date === day}.size + self.periods.select{ |period| period.period_start <= day && day <= period.period_end && valid_days.include?(day.cwday) }.size - counter <= 1 ? false : true - end + counter = self.dates.select{ |d| d.date === day}.size + self.periods.select{ |period| period.period_start <= day && day <= period.period_end && valid_days.include?(day.cwday) }.size + counter <= 1 ? false : true + end - def periods_max_date - return nil if self.periods.empty? + def periods_max_date + return nil if self.periods.empty? - min_start = self.periods.map(&:period_start).compact.min - max_end = self.periods.map(&:period_end).compact.max - result = nil + min_start = self.periods.map(&:period_start).compact.min + max_end = self.periods.map(&:period_end).compact.max + result = nil - if max_end && min_start - max_end.downto( min_start) do |date| - if self.valid_days.include?(date.cwday) && !self.excluded_date?(date) - result = date - break + if max_end && min_start + max_end.downto( min_start) do |date| + if self.valid_days.include?(date.cwday) && !self.excluded_date?(date) + result = date + break + end end end + result end - result - end - def periods_min_date - return nil if self.periods.empty? - - min_start = self.periods.map(&:period_start).compact.min - max_end = self.periods.map(&:period_end).compact.max - result = nil - - if max_end && min_start - min_start.upto(max_end) do |date| - if self.valid_days.include?(date.cwday) && !self.excluded_date?(date) - result = date - break + def periods_min_date + return nil if self.periods.empty? + + min_start = self.periods.map(&:period_start).compact.min + max_end = self.periods.map(&:period_end).compact.max + result = nil + + if max_end && min_start + min_start.upto(max_end) do |date| + if self.valid_days.include?(date.cwday) && !self.excluded_date?(date) + result = date + break + end end end + result end - result - end - def bounding_dates - bounding_min = self.dates.select{|d| d.in_out}.map(&:date).compact.min - bounding_max = self.dates.select{|d| d.in_out}.map(&:date).compact.max + def bounding_dates + bounding_min = self.dates.select{|d| d.in_out}.map(&:date).compact.min + bounding_max = self.dates.select{|d| d.in_out}.map(&:date).compact.max - unless self.periods.empty? - bounding_min = periods_min_date if periods_min_date && - (bounding_min.nil? || (periods_min_date < bounding_min)) + unless self.periods.empty? + bounding_min = periods_min_date if periods_min_date && + (bounding_min.nil? || (periods_min_date < bounding_min)) - bounding_max = periods_max_date if periods_max_date && - (bounding_max.nil? || (bounding_max < periods_max_date)) - end + bounding_max = periods_max_date if periods_max_date && + (bounding_max.nil? || (bounding_max < periods_max_date)) + end - [bounding_min, bounding_max].compact - end + [bounding_min, bounding_max].compact + end - def display_day_types - %w(monday tuesday wednesday thursday friday saturday sunday).select{ |d| self.send(d) }.map{ |d| self.human_attribute_name(d).first(2)}.join(', ') - end + def display_day_types + %w(monday tuesday wednesday thursday friday saturday sunday).select{ |d| self.send(d) }.map{ |d| self.human_attribute_name(d).first(2)}.join(', ') + end - def day_by_mask(flag) - int_day_types & flag == flag - end + def day_by_mask(flag) + int_day_types & flag == flag + end - def self.day_by_mask(int_day_types,flag) - int_day_types & flag == flag - end + def self.day_by_mask(int_day_types,flag) + int_day_types & flag == flag + end - def valid_days - # Build an array with day of calendar week (1-7, Monday is 1). - [].tap do |valid_days| - valid_days << 1 if monday - valid_days << 2 if tuesday - valid_days << 3 if wednesday - valid_days << 4 if thursday - valid_days << 5 if friday - valid_days << 6 if saturday - valid_days << 7 if sunday + def valid_days + # Build an array with day of calendar week (1-7, Monday is 1). + [].tap do |valid_days| + valid_days << 1 if monday + valid_days << 2 if tuesday + valid_days << 3 if wednesday + valid_days << 4 if thursday + valid_days << 5 if friday + valid_days << 6 if saturday + valid_days << 7 if sunday + end end - end - def self.valid_days(int_day_types) - # Build an array with day of calendar week (1-7, Monday is 1). - [].tap do |valid_days| - valid_days << 1 if day_by_mask(int_day_types,4) - valid_days << 2 if day_by_mask(int_day_types,8) - valid_days << 3 if day_by_mask(int_day_types,16) - valid_days << 4 if day_by_mask(int_day_types,32) - valid_days << 5 if day_by_mask(int_day_types,64) - valid_days << 6 if day_by_mask(int_day_types,128) - valid_days << 7 if day_by_mask(int_day_types,256) + def self.valid_days(int_day_types) + # Build an array with day of calendar week (1-7, Monday is 1). + [].tap do |valid_days| + valid_days << 1 if day_by_mask(int_day_types,4) + valid_days << 2 if day_by_mask(int_day_types,8) + valid_days << 3 if day_by_mask(int_day_types,16) + valid_days << 4 if day_by_mask(int_day_types,32) + valid_days << 5 if day_by_mask(int_day_types,64) + valid_days << 6 if day_by_mask(int_day_types,128) + valid_days << 7 if day_by_mask(int_day_types,256) + end end - end - def monday - day_by_mask(4) - end - def tuesday - day_by_mask(8) - end - def wednesday - day_by_mask(16) - end - def thursday - day_by_mask(32) - end - def friday - day_by_mask(64) - end - def saturday - day_by_mask(128) - end - def sunday - day_by_mask(256) - end + def monday + day_by_mask(4) + end + def tuesday + day_by_mask(8) + end + def wednesday + day_by_mask(16) + end + def thursday + day_by_mask(32) + end + def friday + day_by_mask(64) + end + def saturday + day_by_mask(128) + end + def sunday + day_by_mask(256) + end - def set_day(day,flag) - if day == '1' || day == true - self.int_day_types |= flag - else - self.int_day_types &= ~flag + def set_day(day,flag) + if day == '1' || day == true + self.int_day_types |= flag + else + self.int_day_types &= ~flag + end + shortcuts_update end - shortcuts_update - end - def monday=(day) - set_day(day,4) - end - def tuesday=(day) - set_day(day,8) - end - def wednesday=(day) - set_day(day,16) - end - def thursday=(day) - set_day(day,32) - end - def friday=(day) - set_day(day,64) - end - def saturday=(day) - set_day(day,128) - end - def sunday=(day) - set_day(day,256) - end + def monday=(day) + set_day(day,4) + end + def tuesday=(day) + set_day(day,8) + end + def wednesday=(day) + set_day(day,16) + end + def thursday=(day) + set_day(day,32) + end + def friday=(day) + set_day(day,64) + end + def saturday=(day) + set_day(day,128) + end + def sunday=(day) + set_day(day,256) + end - def effective_days_of_period(period,valid_days=self.valid_days) - days = [] - period.period_start.upto(period.period_end) do |date| - if valid_days.include?(date.cwday) && !self.excluded_date?(date) - days << date + def effective_days_of_period(period,valid_days=self.valid_days) + days = [] + period.period_start.upto(period.period_end) do |date| + if valid_days.include?(date.cwday) && !self.excluded_date?(date) + days << date + end end - end - days - end + days + end - def effective_days(valid_days=self.valid_days) - days=self.effective_days_of_periods(valid_days) - self.dates.each do |d| - days |= [d.date] if d.in_out + def effective_days(valid_days=self.valid_days) + days=self.effective_days_of_periods(valid_days) + self.dates.each do |d| + days |= [d.date] if d.in_out + end + days.sort end - days.sort - end - def effective_days_of_periods(valid_days=self.valid_days) - days = [] - self.periods.each { |p| days |= self.effective_days_of_period(p,valid_days)} - days.sort - end + def effective_days_of_periods(valid_days=self.valid_days) + days = [] + self.periods.each { |p| days |= self.effective_days_of_period(p,valid_days)} + days.sort + end - def clone_periods - periods = [] - self.periods.each { |p| periods << p.copy} - periods.sort_by(&:period_start) - end + def clone_periods + periods = [] + self.periods.each { |p| periods << p.copy} + periods.sort_by(&:period_start) + end - def included_days - days = [] - self.dates.each do |d| - days |= [d.date] if d.in_out + def included_days + days = [] + self.dates.each do |d| + days |= [d.date] if d.in_out + end + days.sort end - days.sort - end - def excluded_days - days = [] - self.dates.each do |d| - days |= [d.date] unless d.in_out + def excluded_days + days = [] + self.dates.each do |d| + days |= [d.date] unless d.in_out + end + days.sort end - days.sort - end - # produce a copy of periods without anyone overlapping or including another - def optimize_overlapping_periods - periods = self.clone_periods - optimized = [] - i=0 - while i < periods.length - p1 = periods[i] - optimized << p1 - j= i+1 - while j < periods.length - p2 = periods[j] - if p1.contains? p2 - periods.delete p2 - elsif p1.overlap? p2 - p1.period_start = [p1.period_start,p2.period_start].min - p1.period_end = [p1.period_end,p2.period_end].max - periods.delete p2 - else - j += 1 + # produce a copy of periods without anyone overlapping or including another + def optimize_overlapping_periods + periods = self.clone_periods + optimized = [] + i=0 + while i < periods.length + p1 = periods[i] + optimized << p1 + j= i+1 + while j < periods.length + p2 = periods[j] + if p1.contains? p2 + periods.delete p2 + elsif p1.overlap? p2 + p1.period_start = [p1.period_start,p2.period_start].min + p1.period_end = [p1.period_end,p2.period_end].max + periods.delete p2 + else + j += 1 + end end + i+= 1 end - i+= 1 + optimized.sort { |a,b| a.period_start <=> b.period_start} end - optimized.sort { |a,b| a.period_start <=> b.period_start} - end - # add a peculiar day or switch it from excluded to included - def add_included_day(d) - if self.excluded_date?(d) - self.dates.each do |date| - if date.date === d - date.in_out = true - end - end - elsif !self.include_in_dates?(d) - self.dates << Chouette::TimeTableDate.new(:date => d, :in_out => true) + # add a peculiar day or switch it from excluded to included + def add_included_day(d) + if self.excluded_date?(d) + self.dates.each do |date| + if date.date === d + date.in_out = true + end + end + elsif !self.include_in_dates?(d) + self.dates << Chouette::TimeTableDate.new(:date => d, :in_out => true) + end end - end - # merge effective days from another timetable - def merge!(another_tt) - transaction do - days = [].tap do |array| - array.push(*self.effective_days, *another_tt.effective_days) - array.uniq! - end + # merge effective days from another timetable + def merge!(another_tt) + transaction do + days = [].tap do |array| + array.push(*self.effective_days, *another_tt.effective_days) + array.uniq! + end - self.dates.clear - self.periods.clear + self.dates.clear + self.periods.clear - days.each do |day| - self.dates << Chouette::TimeTableDate.new(date: day, in_out: true) + days.each do |day| + self.dates << Chouette::TimeTableDate.new(date: day, in_out: true) + end + self.save! end - self.save! + self.convert_continuous_dates_to_periods end - self.convert_continuous_dates_to_periods - end - def included_days_in_dates_and_periods - in_day = self.dates.select {|d| d.in_out }.map(&:date) - out_day = self.dates.select {|d| !d.in_out }.map(&:date) + def included_days_in_dates_and_periods + in_day = self.dates.select {|d| d.in_out }.map(&:date) + out_day = self.dates.select {|d| !d.in_out }.map(&:date) - in_periods = self.periods.map{|p| (p.period_start..p.period_end).to_a }.flatten - days = in_periods + in_day - days -= out_day - days - end + in_periods = self.periods.map{|p| (p.period_start..p.period_end).to_a }.flatten + days = in_periods + in_day + days -= out_day + days + end - # keep common dates with another_tt - def intersect!(another_tt) - transaction do - days = [].tap do |array| - array.push(*self.effective_days) - array.delete_if {|day| !another_tt.effective_days.include?(day) } - array.uniq! - end + # keep common dates with another_tt + def intersect!(another_tt) + transaction do + days = [].tap do |array| + array.push(*self.effective_days) + array.delete_if {|day| !another_tt.effective_days.include?(day) } + array.uniq! + end - self.dates.clear - self.periods.clear + self.dates.clear + self.periods.clear - days.sort.each do |d| - self.dates << Chouette::TimeTableDate.new(:date => d, :in_out => true) + days.sort.each do |d| + self.dates << Chouette::TimeTableDate.new(:date => d, :in_out => true) + end + self.save! end - self.save! + self.convert_continuous_dates_to_periods end - self.convert_continuous_dates_to_periods - end - # remove common dates with another_tt - def disjoin!(another_tt) - transaction do - days = [].tap do |array| - array.push(*self.effective_days) - array.delete_if {|day| another_tt.effective_days.include?(day) } - array.uniq! - end + # remove common dates with another_tt + def disjoin!(another_tt) + transaction do + days = [].tap do |array| + array.push(*self.effective_days) + array.delete_if {|day| another_tt.effective_days.include?(day) } + array.uniq! + end - self.dates.clear - self.periods.clear + self.dates.clear + self.periods.clear - days.sort.each do |d| - self.dates << Chouette::TimeTableDate.new(:date => d, :in_out => true) + days.sort.each do |d| + self.dates << Chouette::TimeTableDate.new(:date => d, :in_out => true) + end + self.save! end - self.save! + self.convert_continuous_dates_to_periods end - self.convert_continuous_dates_to_periods - end - def duplicate - tt = self.deep_clone :include => [:periods, :dates], :except => [:object_version, :objectid] - tt.tag_list.add(*self.tag_list) unless self.tag_list.empty? - tt.created_from = self - tt.comment = I18n.t("activerecord.copy", :name => self.comment) - tt + def duplicate + tt = self.deep_clone :include => [:periods, :dates], :except => [:object_version, :objectid] + tt.tag_list.add(*self.tag_list) unless self.tag_list.empty? + tt.created_from = self + tt.comment = I18n.t("activerecord.copy", :name => self.comment) + tt + end end -end +end
\ No newline at end of file diff --git a/app/models/chouette/time_table_date.rb b/app/models/chouette/time_table_date.rb index 1893eae91..b3b2fd561 100644 --- a/app/models/chouette/time_table_date.rb +++ b/app/models/chouette/time_table_date.rb @@ -1,22 +1,23 @@ -class Chouette::TimeTableDate < Chouette::ActiveRecord - include ChecksumSupport +module Chouette + class TimeTableDate < Chouette::ActiveRecord + include ChecksumSupport - self.primary_key = "id" - belongs_to :time_table, inverse_of: :dates - acts_as_list :scope => 'time_table_id = #{time_table_id}',:top_of_list => 0 + self.primary_key = "id" + belongs_to :time_table, inverse_of: :dates + acts_as_list :scope => 'time_table_id = #{time_table_id}',:top_of_list => 0 - validates_presence_of :date - validates_uniqueness_of :date, :scope => :time_table_id + validates_presence_of :date + validates_uniqueness_of :date, :scope => :time_table_id - scope :in_dates, -> { where(in_out: true) } + scope :in_dates, -> { where(in_out: true) } - def self.model_name - ActiveModel::Name.new Chouette::TimeTableDate, Chouette, "TimeTableDate" - end + def self.model_name + ActiveModel::Name.new Chouette::TimeTableDate, Chouette, "TimeTableDate" + end - def checksum_attributes - attrs = ['date', 'in_out'] - self.slice(*attrs).values + def checksum_attributes + attrs = ['date', 'in_out'] + self.slice(*attrs).values + end end -end - +end
\ No newline at end of file diff --git a/app/models/chouette/time_table_period.rb b/app/models/chouette/time_table_period.rb index ed136f3b9..ab3e79d7e 100644 --- a/app/models/chouette/time_table_period.rb +++ b/app/models/chouette/time_table_period.rb @@ -1,45 +1,46 @@ -class Chouette::TimeTablePeriod < Chouette::ActiveRecord - include ChecksumSupport +module Chouette + class TimeTablePeriod < Chouette::ActiveRecord + include ChecksumSupport - self.primary_key = "id" - belongs_to :time_table, inverse_of: :periods - acts_as_list :scope => 'time_table_id = #{time_table_id}',:top_of_list => 0 + self.primary_key = "id" + belongs_to :time_table, inverse_of: :periods + acts_as_list :scope => 'time_table_id = #{time_table_id}',:top_of_list => 0 - validates_presence_of :period_start, :period_end + validates_presence_of :period_start, :period_end - validate :start_must_be_before_end + validate :start_must_be_before_end - def checksum_attributes - attrs = ['period_start', 'period_end'] - self.slice(*attrs).values - end - - def self.model_name - ActiveModel::Name.new Chouette::TimeTablePeriod, Chouette, "TimeTablePeriod" - end + def checksum_attributes + attrs = ['period_start', 'period_end'] + self.slice(*attrs).values + end - def start_must_be_before_end - # security against nil values - if period_end.nil? || period_start.nil? - return + def self.model_name + ActiveModel::Name.new Chouette::TimeTablePeriod, Chouette, "TimeTablePeriod" end - if period_end <= period_start - errors.add(:period_end,I18n.t("activerecord.errors.models.time_table_period.start_must_be_before_end")) + + def start_must_be_before_end + # security against nil values + if period_end.nil? || period_start.nil? + return + end + if period_end <= period_start + errors.add(:period_end,I18n.t("activerecord.errors.models.time_table_period.start_must_be_before_end")) + end end - end - def copy - Chouette::TimeTablePeriod.new(:period_start => self.period_start,:period_end => self.period_end) - end + def copy + Chouette::TimeTablePeriod.new(:period_start => self.period_start,:period_end => self.period_end) + end - # Test to see if a period overlap this period - def overlap?(p) - (p.period_start >= self.period_start && p.period_start <= self.period_end) || (p.period_end >= self.period_start && p.period_end <= self.period_end) - end + # Test to see if a period overlap this period + def overlap?(p) + (p.period_start >= self.period_start && p.period_start <= self.period_end) || (p.period_end >= self.period_start && p.period_end <= self.period_end) + end - # Test to see if a period is included in this period - def contains?(p) - (p.period_start >= self.period_start && p.period_end <= self.period_end) + # Test to see if a period is included in this period + def contains?(p) + (p.period_start >= self.period_start && p.period_end <= self.period_end) + end end - -end +end
\ No newline at end of file diff --git a/app/models/chouette/timeband.rb b/app/models/chouette/timeband.rb index 9844dd1b1..21c81ab1c 100644 --- a/app/models/chouette/timeband.rb +++ b/app/models/chouette/timeband.rb @@ -1,5 +1,4 @@ module Chouette - class TimebandValidator < ActiveModel::Validator def validate(record) if record.end_time <= record.start_time @@ -9,10 +8,12 @@ module Chouette end class Timeband < Chouette::TridentActiveRecord + include ObjectidSupport + self.primary_key = "id" validates :start_time, :end_time, presence: true - validates_with TimebandValidator + validates_with Chouette::TimebandValidator default_scope { order(:start_time) } @@ -24,7 +25,5 @@ module Chouette fullname = "#{I18n.l(self.start_time, format: :hour)}-#{I18n.l(self.end_time, format: :hour)}" "#{self.name} (#{fullname})" if self.name end - end - -end +end
\ No newline at end of file diff --git a/app/models/chouette/trident_active_record.rb b/app/models/chouette/trident_active_record.rb index e8223e3d6..18b7bbf9b 100644 --- a/app/models/chouette/trident_active_record.rb +++ b/app/models/chouette/trident_active_record.rb @@ -1,18 +1,19 @@ -class Chouette::TridentActiveRecord < Chouette::ActiveRecord - include StifNetexAttributesSupport +module Chouette + class TridentActiveRecord < Chouette::ActiveRecord - self.abstract_class = true + self.abstract_class = true - def referential - @referential ||= Referential.where(:slug => Apartment::Tenant.current).first! - end + def referential + @referential ||= Referential.where(:slug => Apartment::Tenant.current).first! + end - def hub_restricted? - referential.data_format == "hub" - end + def hub_restricted? + referential.data_format == "hub" + end - def prefix - referential.prefix - end + def prefix + referential.prefix + end -end + end +end
\ No newline at end of file diff --git a/app/models/chouette/vehicle_journey.rb b/app/models/chouette/vehicle_journey.rb index e534d2bde..b68909795 100644 --- a/app/models/chouette/vehicle_journey.rb +++ b/app/models/chouette/vehicle_journey.rb @@ -1,7 +1,8 @@ module Chouette - class VehicleJourney < TridentActiveRecord + class VehicleJourney < Chouette::TridentActiveRecord include ChecksumSupport include VehicleJourneyRestrictions + include ObjectidSupport extend StifTransportModeEnumerations # FIXME http://jira.codehaus.org/browse/JRUBY-6358 self.primary_key = "id" @@ -57,7 +58,7 @@ module Chouette end def local_id - "IBOO-#{self.referential.id}-#{self.route.line.objectid.local_id}-#{self.id}" + "IBOO-#{self.referential.id}-#{self.route.line.get_objectid.local_id}-#{self.id}" end def checksum_attributes @@ -302,6 +303,5 @@ module Chouette ') .where('"time_tables_vehicle_journeys"."vehicle_journey_id" IS NULL') end - end -end +end
\ No newline at end of file diff --git a/app/models/chouette/vehicle_journey_at_stop.rb b/app/models/chouette/vehicle_journey_at_stop.rb index a4a4a02c8..6f0119e74 100644 --- a/app/models/chouette/vehicle_journey_at_stop.rb +++ b/app/models/chouette/vehicle_journey_at_stop.rb @@ -1,7 +1,7 @@ module Chouette class VehicleJourneyAtStop < ActiveRecord - include ForBoardingEnumerations - include ForAlightingEnumerations + include Chouette::ForBoardingEnumerations + include Chouette::ForAlightingEnumerations include ChecksumSupport DAY_OFFSET_MAX = 1 @@ -41,7 +41,7 @@ module Chouette :arrival_day_offset, I18n.t( 'vehicle_journey_at_stops.errors.day_offset_must_not_exceed_max', - short_id: vehicle_journey.objectid.short_id, + short_id: vehicle_journey.get_objectid.short_id, max: DAY_OFFSET_MAX + 1 ) ) @@ -52,7 +52,7 @@ module Chouette :departure_day_offset, I18n.t( 'vehicle_journey_at_stops.errors.day_offset_must_not_exceed_max', - short_id: vehicle_journey.objectid.short_id, + short_id: vehicle_journey.get_objectid.short_id, max: DAY_OFFSET_MAX + 1 ) ) @@ -76,4 +76,4 @@ module Chouette end end end -end +end
\ No newline at end of file diff --git a/app/models/chouette/vehicle_journey_at_stops_are_in_increasing_time_order_validator.rb b/app/models/chouette/vehicle_journey_at_stops_are_in_increasing_time_order_validator.rb index 95f0cdc3e..b4e6a047d 100644 --- a/app/models/chouette/vehicle_journey_at_stops_are_in_increasing_time_order_validator.rb +++ b/app/models/chouette/vehicle_journey_at_stops_are_in_increasing_time_order_validator.rb @@ -1,6 +1,5 @@ module Chouette - class VehicleJourneyAtStopsAreInIncreasingTimeOrderValidator < - ActiveModel::EachValidator + class VehicleJourneyAtStopsAreInIncreasingTimeOrderValidator < ActiveModel::EachValidator def validate_each(vehicle_journey, attribute, value) previous_at_stop = nil @@ -47,4 +46,4 @@ module Chouette valid end end -end +end
\ No newline at end of file diff --git a/app/models/chouette/vehicle_journey_at_stops_day_offset.rb b/app/models/chouette/vehicle_journey_at_stops_day_offset.rb index 9f577dded..b2cb90d11 100644 --- a/app/models/chouette/vehicle_journey_at_stops_day_offset.rb +++ b/app/models/chouette/vehicle_journey_at_stops_day_offset.rb @@ -39,4 +39,4 @@ module Chouette save end end -end +end
\ No newline at end of file diff --git a/app/models/chouette/vehicle_journey_frequency.rb b/app/models/chouette/vehicle_journey_frequency.rb index 41ba49082..53e85121f 100644 --- a/app/models/chouette/vehicle_journey_frequency.rb +++ b/app/models/chouette/vehicle_journey_frequency.rb @@ -1,5 +1,5 @@ module Chouette - class VehicleJourneyFrequency < VehicleJourney + class VehicleJourneyFrequency < Chouette::VehicleJourney after_initialize :fill_journey_category @@ -66,4 +66,4 @@ module Chouette errors.add(:base, I18n.t('vehicle_journey_frequency.require_at_least_one_frequency')) unless journey_frequencies.size > 0 end end -end +end
\ No newline at end of file diff --git a/app/models/concerns/default_netex_attributes_support.rb b/app/models/concerns/netex_attributes_support.rb index 4cf77ea65..d78528dbf 100644 --- a/app/models/concerns/default_netex_attributes_support.rb +++ b/app/models/concerns/netex_attributes_support.rb @@ -1,4 +1,4 @@ -module DefaultNetexAttributesSupport +module NetexAttributesSupport extend ActiveSupport::Concern included do diff --git a/app/models/concerns/objectid_formatter_support.rb b/app/models/concerns/objectid_formatter_support.rb new file mode 100644 index 000000000..2138ac89e --- /dev/null +++ b/app/models/concerns/objectid_formatter_support.rb @@ -0,0 +1,15 @@ +module ObjectidFormatterSupport + extend ActiveSupport::Concern + + included do + validates_presence_of :objectid_formater_class + + def objectid_formater + objectid_formater_class.new + end + + def objectid_formater_class + "Chouette::ObjectidFormatter::#{read_attribute(:objectid_format).camelcase}".constantize if read_attribute(:objectid_format) + end + end +end diff --git a/app/models/concerns/objectid_support.rb b/app/models/concerns/objectid_support.rb new file mode 100644 index 000000000..6822912f1 --- /dev/null +++ b/app/models/concerns/objectid_support.rb @@ -0,0 +1,34 @@ +module ObjectidSupport + extend ActiveSupport::Concern + + included do + before_validation :before_validation_objectid + after_commit :after_commit_objectid, on: :create, if: Proc.new {|model| model.read_attribute(:objectid).try(:include?, '__pending_id__')} + validates_presence_of :objectid_format, :objectid + validates_uniqueness_of :objectid, skip_validation: Proc.new {|model| model.read_attribute(:objectid).nil?} + + def before_validation_objectid + self.referential.objectid_formater.before_validation self + end + + def after_commit_objectid + self.referential.objectid_formater.after_commit self + end + + def get_objectid + self.referential.objectid_formater.get_objectid read_attribute(:objectid) if objectid_format && read_attribute(:objectid) + end + + def objectid + get_objectid.try(:to_s) + end + + def objectid_class + get_objectid.try(:class) + end + + def objectid_format + self.referential.objectid_format + end + end +end
\ No newline at end of file diff --git a/app/models/line_referential.rb b/app/models/line_referential.rb index 8bc6adec3..d8cf74bda 100644 --- a/app/models/line_referential.rb +++ b/app/models/line_referential.rb @@ -1,5 +1,7 @@ class LineReferential < ActiveRecord::Base + include ObjectidFormatterSupport extend StifTransportModeEnumerations + extend Enumerize has_many :line_referential_memberships has_many :organisations, through: :line_referential_memberships @@ -9,6 +11,7 @@ class LineReferential < ActiveRecord::Base has_many :networks, class_name: 'Chouette::Network' has_many :line_referential_syncs, -> { order created_at: :desc } has_many :workbenches + enumerize :objectid_format, in: %w(netex stif_netex stif_reflex stif_codifligne), default: 'netex' def add_member(organisation, options = {}) attributes = options.merge organisation: organisation @@ -19,6 +22,7 @@ class LineReferential < ActiveRecord::Base validates :sync_interval, presence: true # need to define precise validation rules validates_inclusion_of :sync_interval, :in => 1..30 + validates_presence_of :objectid_format def operating_lines lines.where(deactivated: false) diff --git a/app/models/referential.rb b/app/models/referential.rb index fad91fa7f..fa6bcbcf1 100644 --- a/app/models/referential.rb +++ b/app/models/referential.rb @@ -1,9 +1,12 @@ class Referential < ActiveRecord::Base include DataFormatEnumerations + include ObjectidFormatterSupport + extend Enumerize validates_presence_of :name validates_presence_of :slug validates_presence_of :prefix + validates_presence_of :objectid_format # Fixme #3657 # validates_presence_of :time_zone # validates_presence_of :upper_corner @@ -11,8 +14,6 @@ class Referential < ActiveRecord::Base validates_uniqueness_of :slug - validates_presence_of :line_referential - validates_presence_of :stop_area_referential validates_format_of :slug, :with => %r{\A[a-z][0-9a-z_]+\Z} validates_format_of :prefix, :with => %r{\A[0-9a-zA-Z_]+\Z} validates_format_of :upper_corner, :with => %r{\A-?[0-9]+\.?[0-9]*\,-?[0-9]+\.?[0-9]*\Z} @@ -55,6 +56,8 @@ class Referential < ActiveRecord::Base belongs_to :referential_suite + enumerize :objectid_format, in: %w(netex stif_netex stif_reflex stif_codifligne), default: 'netex' + scope :ready, -> { where(ready: true) } scope :in_periode, ->(periode) { where(id: referential_ids_in_periode(periode)) } scope :include_metadatas_lines, ->(line_ids) { where('referential_metadata.line_ids && ARRAY[?]::bigint[]', line_ids) } diff --git a/app/models/stop_area_referential.rb b/app/models/stop_area_referential.rb index dd206f9e9..159ee07b3 100644 --- a/app/models/stop_area_referential.rb +++ b/app/models/stop_area_referential.rb @@ -1,10 +1,14 @@ class StopAreaReferential < ActiveRecord::Base + extend Enumerize + include ObjectidFormatterSupport has_many :stop_area_referential_memberships has_many :organisations, through: :stop_area_referential_memberships has_many :stop_areas, class_name: 'Chouette::StopArea' has_many :stop_area_referential_syncs, -> {order created_at: :desc} has_many :workbenches + enumerize :objectid_format, in: %w(netex stif_netex stif_reflex stif_codifligne), default: 'netex' + validates_presence_of :objectid_format def add_member(organisation, options = {}) attributes = options.merge organisation: organisation diff --git a/app/models/workbench.rb b/app/models/workbench.rb index c304e8ba9..95e4d1b68 100644 --- a/app/models/workbench.rb +++ b/app/models/workbench.rb @@ -1,8 +1,11 @@ class Workbench < ActiveRecord::Base + include ObjectidFormatterSupport + extend Enumerize belongs_to :organisation belongs_to :line_referential belongs_to :stop_area_referential belongs_to :output, class_name: 'ReferentialSuite' + enumerize :objectid_format, in: %w(netex stif_netex stif_reflex stif_codifligne), default: 'netex' has_many :lines, -> (workbench) { Stif::MyWorkbenchScopes.new(workbench).line_scope(self) }, through: :line_referential has_many :networks, through: :line_referential @@ -17,6 +20,7 @@ class Workbench < ActiveRecord::Base validates :name, presence: true validates :organisation, presence: true validates :output, presence: true + validates_presence_of :objectid_format has_many :referentials has_many :referential_metadatas, through: :referentials, source: :metadatas |
