aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorZog2018-01-05 15:47:06 +0100
committerZog2018-01-31 16:15:24 +0100
commita3314251d25528022569e2b700ffe41f6aa802c4 (patch)
tree0cc6fdc53eb8f53feec0930fffc7fe154d767266 /app
parent9f2ec5875d6abced927737ab48a88192844fc10a (diff)
downloadchouette-core-5372-clean-referential-after-cloning.tar.bz2
Refs #5797 @3h; Automatically clean referentials5372-clean-referential-after-cloning
Automatically trigger a CleanUp operation on referentials when the metadatas change. Also jupdate the CleanUp operation to use the referential metadatas dates insterad of arbitrary one.
Diffstat (limited to 'app')
-rw-r--r--app/controllers/clean_ups_controller.rb2
-rw-r--r--app/models/clean_up.rb103
-rw-r--r--app/models/referential.rb4
3 files changed, 90 insertions, 19 deletions
diff --git a/app/controllers/clean_ups_controller.rb b/app/controllers/clean_ups_controller.rb
index ec28aa0fc..266f4b8ce 100644
--- a/app/controllers/clean_ups_controller.rb
+++ b/app/controllers/clean_ups_controller.rb
@@ -15,6 +15,6 @@ class CleanUpsController < ChouetteController
end
def clean_up_params
- params.require(:clean_up).permit(:date_type, :begin_date, :end_date)
+ params.require(:clean_up).permit(:date_type, :begin_date, :end_date).update({mode: :manual})
end
end
diff --git a/app/models/clean_up.rb b/app/models/clean_up.rb
index 7aab7f32e..cf665793b 100644
--- a/app/models/clean_up.rb
+++ b/app/models/clean_up.rb
@@ -5,13 +5,20 @@ class CleanUp < ActiveRecord::Base
has_one :clean_up_result
enumerize :date_type, in: %i(between before after)
+ enumerize :mode, in: %i(manual auto)
- validates_presence_of :begin_date, message: :presence
- validates_presence_of :end_date, message: :presence, if: Proc.new {|cu| cu.date_type == 'between'}
- validates_presence_of :date_type, message: :presence
+ validates_presence_of :referential, message: :presence
+ validates_presence_of :mode, message: :presence
+ validates_presence_of :begin_date, message: :presence, if: :manual?
+ validates_presence_of :end_date, message: :presence, if: Proc.new {|cu| cu.mode == 'manual' && cu.date_type == 'between'}
+ validates_presence_of :date_type, message: :presence, if: :manual?
validate :end_date_must_be_greater_that_begin_date
after_commit :perform_cleanup, :on => :create
+ def manual?
+ mode == 'manual'
+ end
+
def end_date_must_be_greater_that_begin_date
if self.end_date && self.date_type == 'between' && self.begin_date >= self.end_date
errors.add(:base, I18n.t('activerecord.errors.models.clean_up.invalid_period'))
@@ -22,6 +29,12 @@ class CleanUp < ActiveRecord::Base
CleanUpWorker.perform_async(self.id)
end
+ def date_type_with_mode
+ manual? ? date_type_without_mode : "based_on_referential"
+ end
+
+ alias_method_chain :date_type, :mode
+
def clean
{}.tap do |result|
processed = send("destroy_time_tables_#{self.date_type}")
@@ -34,9 +47,20 @@ class CleanUp < ActiveRecord::Base
self.overlapping_periods.each do |period|
exclude_dates_in_overlapping_period(period)
end
+ self.destroy_lines_related_objects_based_on_referential unless manual?
end
end
+ def destroy_lines_related_objects_based_on_referential
+ remaining_line_ids = referential.metadatas.pluck(:line_ids).flatten.uniq
+ Chouette::Route.where.not(line_id: remaining_line_ids).destroy_all
+ end
+
+ def destroy_time_tables_based_on_referential
+ time_tables = Chouette::TimeTable.none
+ self.destroy_time_tables(time_tables)
+ end
+
def destroy_time_tables_between
time_tables = Chouette::TimeTable.where('end_date < ? AND start_date > ?', self.end_date, self.begin_date)
self.destroy_time_tables(time_tables)
@@ -52,6 +76,11 @@ class CleanUp < ActiveRecord::Base
self.destroy_time_tables(time_tables)
end
+ def destroy_time_tables_dates_based_on_referential
+ query = referential_metadata_periodes_query "(date < ? OR date > ?)", "AND"
+ Chouette::TimeTableDate.in_dates.where(*query).destroy_all
+ end
+
def destroy_time_tables_dates_before
Chouette::TimeTableDate.in_dates.where('date < ?', self.begin_date).destroy_all
end
@@ -64,6 +93,11 @@ class CleanUp < ActiveRecord::Base
Chouette::TimeTableDate.in_dates.where('date > ? AND date < ?', self.begin_date, self.end_date).destroy_all
end
+ def destroy_time_tables_periods_based_on_referential
+ query = referential_metadata_periodes_query "(period_end < ? OR period_start > ?)", "AND"
+ Chouette::TimeTablePeriod.where(*query).destroy_all
+ end
+
def destroy_time_tables_periods_before
Chouette::TimeTablePeriod.where('period_end < ?', self.begin_date).destroy_all
end
@@ -77,28 +111,48 @@ class CleanUp < ActiveRecord::Base
end
def overlapping_periods
- self.end_date = self.begin_date if self.date_type != 'between'
- Chouette::TimeTablePeriod.where('(period_start, period_end) OVERLAPS (?, ?)', self.begin_date, self.end_date)
+ if manual?
+ self.end_date = self.begin_date if self.date_type != 'between'
+ Chouette::TimeTablePeriod.where('(period_start, period_end) OVERLAPS (?, ?)', self.begin_date, self.end_date)
+ else
+ periods_query = [
+ (['(period_start, period_end) OVERLAPS (?, ?)'] * referential_metadata_periodes_boundaries.size).join(' OR '),
+ *referential_metadata_periodes_boundaries.flatten
+ ]
+
+ Chouette::TimeTablePeriod.where(*periods_query)
+ end
end
def exclude_dates_in_overlapping_period(period)
days_in_period = period.period_start..period.period_end
- day_out = period.time_table.dates.where(in_out: false).map(&:date)
- # check if day is greater or less then cleanup date
- if date_type != 'between'
- operator = date_type == 'after' ? '>' : '<'
- to_exclude_days = days_in_period.map do |day|
- day if day.public_send(operator, self.begin_date)
+ day_out = period.time_table.dates.where(in_out: false).pluck(:date)
+
+ if manual?
+ # check if day is greater or less then cleanup date
+ if date_type != 'between'
+ operator = date_type == 'after' ? '>' : '<'
+ to_exclude_days = days_in_period.map do |day|
+ day if day.public_send(operator, self.begin_date)
+ end
+ else
+ days_in_cleanup_periode = (self.begin_date..self.end_date)
+ to_exclude_days = days_in_period & days_in_cleanup_periode
end
else
- days_in_cleanup_periode = (self.begin_date..self.end_date)
- to_exclude_days = days_in_period & days_in_cleanup_periode
+ # Here the behaviour is the opposite:
+ # We want to KEEP dates overlapping the referential metadatas
+ to_keep_days = referential_metadata_periodes.map do |metadata_period|
+ (days_in_period & (metadata_period.begin..metadata_period.end)).to_a
+ end.flatten
+ to_exclude_days = days_in_period.to_a - to_keep_days
end
- to_exclude_days.to_a.compact.each do |day|
+
+ to_exclude_days.to_a.compact.uniq.each do |day|
# we ensure day is not already an exclude date
# and that day is not equal to the boundariy date of the clean up
- if !day_out.include?(day) && day != self.begin_date && day != self.end_date
+ unless day_out.include?(day) || (manual? && (day == self.begin_date || day == self.end_date))
self.add_exclude_date(period.time_table, day)
end
end
@@ -162,4 +216,23 @@ class CleanUp < ActiveRecord::Base
update_attribute(:ended_at, Time.now)
CleanUpResult.create(clean_up: self, message_key: :failed, message_attributes: message_attributes)
end
+
+ private
+ def referential_metadata_periodes
+ referential.metadatas.map(&:periodes).flatten
+ end
+
+ def referential_metadata_periodes_boundaries
+ referential_metadata_periodes.map do |periode|
+ [periode.begin, periode.end]
+ end
+ end
+
+ def referential_metadata_periodes_query subquery, operator
+ boundaries = referential_metadata_periodes_boundaries
+ [
+ ([subquery] * boundaries.size).join(" #{operator} "),
+ *boundaries.flatten
+ ]
+ end
end
diff --git a/app/models/referential.rb b/app/models/referential.rb
index eefd0b77d..e0c08f14d 100644
--- a/app/models/referential.rb
+++ b/app/models/referential.rb
@@ -415,9 +415,7 @@ class Referential < ActiveRecord::Base
end
def perform_cleanup
- remaining_line_ids = self.metadatas.reload.pluck(:line_ids).flatten.uniq
- switch
- Chouette::Route.where.not(line_id: remaining_line_ids).destroy_all
+ CleanUp.new(referential: self, mode: :auto, date_type: :before).save!
end
private