aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/models/merge.rb103
-rw-r--r--app/models/referential.rb30
-rw-r--r--spec/models/merge_spec.rb32
3 files changed, 160 insertions, 5 deletions
diff --git a/app/models/merge.rb b/app/models/merge.rb
index 7c5a5d68c..21ef9fa5f 100644
--- a/app/models/merge.rb
+++ b/app/models/merge.rb
@@ -70,6 +70,109 @@ class Merge < ActiveRecord::Base
end
# let's merge data :)
+
+ # Routes
+
+ referential_routes = referential.switch do
+ referential.routes.all.to_a
+ end
+
+ new.switch do
+ referential_routes.each do |route|
+ existing_route = new.routes.find_by line_id: route.line_id, checksum: route.checksum
+ unless existing_route
+ attributes = route.attributes.merge(
+ id: nil,
+ objectid: "merge:route:#{route.checksum}", #FIXME
+ # line_id is the same
+ # all other primary must be changed
+ opposite_route_id: nil #FIXME
+ )
+ new_route = new.routes.create! attributes
+
+ # FIXME Route checksum changes if stop points are not defined
+ if new_route.checksum != route.checksum
+ raise "Checksum has changed: #{route.inspect} #{new_route.inspect}"
+ end
+ end
+ end
+ end
+
+ referential_routes_checksums = Hash[referential_routes.map { |r| [ r.id, r.checksum ] }]
+
+ # Stop Points
+
+ referential_stop_points = referential.switch do
+ referential.stop_points.all.to_a
+ end
+
+ new.switch do
+ referential_stop_points.each do |stop_point|
+ # find parent route by checksum
+ associated_route_checksum = referential_routes_checksums[stop_point.route_id]
+ existing_associated_route = new.routes.find_by checksum: associated_route_checksum
+
+ existing_stop_point = new.stop_points.find_by route_id: existing_associated_route.id, checksum: stop_point.checksum
+ unless existing_stop_point
+ attributes = stop_point.attributes.merge(
+ id: nil,
+
+ objectid: "merge:stop_point:#{existing_associated_route.checksum}-#{stop_point.checksum}", #FIXME
+
+ # all other primary must be changed
+ route_id: existing_associated_route.id,
+ )
+
+ new_stop_point = new.stop_points.create! attributes
+ if new_stop_point.checksum != stop_point.checksum
+ raise "Checksum has changed: #{stop_point.inspect} #{new_stop_point.inspect}"
+ end
+ end
+ end
+ end
+
+ referential_stop_points_checksums = Hash[referential_stop_points.map { |r| [ r.id, r.checksum ] }]
+
+ # JourneyPatterns
+
+ referential_journey_patterns = referential.switch do
+ referential.journey_patterns.all.to_a
+ end
+
+ new.switch do
+ referential_journey_patterns.each do |journey_pattern|
+ # find parent route by checksum
+ associated_route_checksum = referential_routes_checksums[journey_pattern.route_id]
+ existing_associated_route = new.routes.find_by checksum: associated_route_checksum
+
+ existing_journey_pattern = new.journey_patterns.find_by route_id: existing_associated_route.id, checksum: journey_pattern.checksum
+
+ unless existing_journey_pattern
+ attributes = journey_pattern.attributes.merge(
+ id: nil,
+
+ objectid: "merge:journey_pattern:#{existing_associated_route.checksum}-#{journey_pattern.checksum}", #FIXME
+
+ # all other primary must be changed
+ route_id: existing_associated_route.id,
+
+ departure_stop_point_id: nil, # FIXME
+ arrival_stop_point_id: nil
+ )
+
+ stop_points = journey_pattern.stop_point_ids.map do |stop_point_id|
+ associated_stop_point_checksum = referential_stop_points_checksums[stop_point_id]
+ new.stop_points.find_by checksum: associated_stop_point_checksum
+ end
+ attributes.merge!(stop_points: stop_points)
+
+ new_journey_pattern = new.journey_patterns.create! attributes
+ if new_journey_pattern.checksum != journey_pattern.checksum
+ raise "Checksum has changed: #{journey_pattern.inspect} #{new_journey_pattern.inspect}"
+ end
+ end
+ end
+ end
end
def save_current
diff --git a/app/models/referential.rb b/app/models/referential.rb
index 4fa353a37..8087ea61e 100644
--- a/app/models/referential.rb
+++ b/app/models/referential.rb
@@ -144,6 +144,18 @@ class Referential < ActiveRecord::Base
Chouette::PurchaseWindow.all
end
+ def routes
+ Chouette::Route.all
+ end
+
+ def journey_patterns
+ Chouette::JourneyPattern.all
+ end
+
+ def stop_points
+ Chouette::StopPoint.all
+ end
+
before_validation :define_default_attributes
def define_default_attributes
@@ -151,10 +163,22 @@ class Referential < ActiveRecord::Base
self.objectid_format ||= workbench.objectid_format if workbench
end
- def switch
+ def switch(&block)
raise "Referential not created" if new_record?
- Apartment::Tenant.switch!(slug)
- self
+
+ unless block_given?
+ Rails.logger.debug "Referential switch to #{slug}"
+ Apartment::Tenant.switch! slug
+ self
+ else
+ result = nil
+ Apartment::Tenant.switch slug do
+ Rails.logger.debug "Referential switch to #{slug}"
+ result = yield
+ end
+ Rails.logger.debug "Referential back"
+ result
+ end
end
def self.new_from(from, functional_scope)
diff --git a/spec/models/merge_spec.rb b/spec/models/merge_spec.rb
index caa623357..92ffc8267 100644
--- a/spec/models/merge_spec.rb
+++ b/spec/models/merge_spec.rb
@@ -3,8 +3,36 @@ require "rails_helper"
RSpec.describe Merge do
it "should work" do
- referential_metadata = FactoryGirl.create(:referential_metadata)
- referential = FactoryGirl.create :workbench_referential, metadatas: [referential_metadata]
+ stop_area_referential = FactoryGirl.create :stop_area_referential
+ 10.times { FactoryGirl.create :stop_area, stop_area_referential: stop_area_referential }
+
+ line_referential = FactoryGirl.create :line_referential
+ company = FactoryGirl.create :company, line_referential: line_referential
+ 10.times { FactoryGirl.create :line, line_referential: line_referential, company: company, network: nil }
+
+ workbench = FactoryGirl.create :workbench, line_referential: line_referential, stop_area_referential: stop_area_referential
+
+ referential_metadata = FactoryGirl.create(:referential_metadata, lines: line_referential.lines.limit(3))
+
+ referential = FactoryGirl.create :referential,
+ workbench: workbench,
+ organisation: workbench.organisation,
+ metadatas: [referential_metadata]
+
+ referential.switch do
+ line_referential.lines.each do |line|
+ 3.times do
+ stop_areas = stop_area_referential.stop_areas.order("random()").limit(5)
+ FactoryGirl.create :route, line: line, stop_areas: stop_areas
+ end
+ end
+
+ referential.routes.each do |route|
+ 3.times do
+ FactoryGirl.create :journey_pattern, route: route, stop_points: route.stop_points.sample(3)
+ end
+ end
+ end
merge = Merge.create!(workbench: referential.workbench, referentials: [referential, referential])
merge.merge!