aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/models/chouette/time_table.rb4
-rw-r--r--app/models/clean_up.rb39
-rw-r--r--spec/models/clean_up_spec.rb80
3 files changed, 123 insertions, 0 deletions
diff --git a/app/models/chouette/time_table.rb b/app/models/chouette/time_table.rb
index 2d329bcc6..151570f20 100644
--- a/app/models/chouette/time_table.rb
+++ b/app/models/chouette/time_table.rb
@@ -135,6 +135,10 @@ class Chouette::TimeTable < Chouette::TridentActiveRecord
[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 actualize
self.dates.clear
self.periods.clear
diff --git a/app/models/clean_up.rb b/app/models/clean_up.rb
index b14067b73..a2b150ecc 100644
--- a/app/models/clean_up.rb
+++ b/app/models/clean_up.rb
@@ -19,6 +19,9 @@ class CleanUp < ActiveRecord::Base
result['time_table'] = send("destroy_time_tables_#{self.date_type}").try(:count)
result['time_table_date'] = send("destroy_time_tables_dates_#{self.date_type}").try(:count)
result['time_table_period'] = send("destroy_time_tables_periods_#{self.date_type}").try(:count)
+ self.overlapping_periods.each do |period|
+ exclude_dates_in_overlapping_period(period)
+ end
end
end
@@ -61,6 +64,42 @@ class CleanUp < ActiveRecord::Base
Chouette::TimeTablePeriod.where('period_start >= ? AND period_end <= ?', self.begin_date, self.end_date).destroy_all
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)
+ 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)
+ end
+ else
+ days_in_cleanup_periode = (self.begin_date..self.end_date)
+ to_exclude_days = days_in_period & days_in_cleanup_periode
+ end
+
+ to_exclude_days.to_a.compact.each do |day|
+ # we ensure day is not already an exclude date
+ if !day_out.include?(day)
+ self.add_exclude_date(period.time_table, day)
+ end
+ end
+ end
+
+ def add_exclude_date(time_table, day)
+ day_in = time_table.dates.where(in_out: true).map(&:date)
+ unless day_in.include?(day)
+ time_table.add_exclude_date(false, day)
+ else
+ time_table.dates.where(date: day).take.update_attribute(:in_out, false)
+ end
+ end
+
def destroy_time_tables(time_tables)
time_tables.each do |time_table|
time_table.vehicle_journeys.map(&:destroy)
diff --git a/spec/models/clean_up_spec.rb b/spec/models/clean_up_spec.rb
index d6aa7652c..b4cf5e1af 100644
--- a/spec/models/clean_up_spec.rb
+++ b/spec/models/clean_up_spec.rb
@@ -6,6 +6,86 @@ RSpec.describe CleanUp, :type => :model do
it { should validate_presence_of(:date_type) }
it { should belong_to(:referential) }
+ context '#exclude_dates_in_overlapping_period with :before date_type' do
+ let(:time_table) { create(:time_table) }
+ let(:period) { time_table.periods[0] }
+ let(:cleaner) { create(:clean_up, date_type: :before) }
+
+ it 'should add exclude date into period for overlapping period' do
+ days_in_period = (period.period_start..period.period_end).count
+ cleaner.begin_date = period.period_end
+
+ expect { cleaner.exclude_dates_in_overlapping_period(period) }.to change {
+ time_table.dates.where(in_out: false).count
+ }.by(days_in_period - 1)
+ end
+
+ it 'should not add exclude date if no overlapping found' do
+ cleaner.begin_date = period.period_start
+ expect { cleaner.exclude_dates_in_overlapping_period(period) }.to_not change {
+ time_table.dates.where(in_out: false).count
+ }
+ end
+ end
+
+ context '#exclude_dates_in_overlapping_period with :after date_type' do
+ let(:time_table) { create(:time_table) }
+ let(:period) { time_table.periods[0] }
+ let(:cleaner) { create(:clean_up, date_type: :after) }
+
+ it 'should add exclude date into period for overlapping period' do
+ days_in_period = (period.period_start..period.period_end).count
+ cleaner.begin_date = period.period_start + 1.day
+ expect { cleaner.exclude_dates_in_overlapping_period(period) }.to change {
+ time_table.dates.where(in_out: false).count
+ }.by(days_in_period - 2)
+ end
+
+ it 'should not add exclude date if no overlapping found' do
+ cleaner.begin_date = period.period_end
+ expect { cleaner.exclude_dates_in_overlapping_period(period) }.to_not change {
+ time_table.dates.where(in_out: false).count
+ }
+ end
+ end
+
+ context '#exclude_dates_in_overlapping_period with :between date_type' do
+ let(:time_table) { create(:time_table) }
+ let(:period) { time_table.periods[0] }
+ let(:cleaner) { create(:clean_up, date_type: :between, begin_date: period.period_start + 3.day, end_date: period.period_end) }
+
+ it 'should add exclude date into period for overlapping period' do
+ expected_day_out = (cleaner.begin_date..cleaner.end_date).count
+ expect { cleaner.exclude_dates_in_overlapping_period(period) }.to change {
+ time_table.dates.where(in_out: false).count
+ }.by(expected_day_out)
+ end
+
+ it 'should not add exclude date if no overlapping found' do
+ cleaner.begin_date = period.period_end + 1.day
+ cleaner.end_date = cleaner.begin_date + 1.day
+
+ expect { cleaner.exclude_dates_in_overlapping_period(period) }.to_not change {
+ time_table.dates.where(in_out: false).count
+ }
+ end
+ end
+
+ context '#overlapping_periods' do
+ let(:cleaner) { create(:clean_up, date_type: :before, end_date: nil) }
+ let(:time_table) { create(:time_table) }
+
+ it 'should detect overlapping periods' do
+ cleaner.begin_date = time_table.periods[0].period_start
+ expect(cleaner.overlapping_periods).to include(time_table.periods[0])
+ end
+
+ it 'should not return none overlapping periods' do
+ cleaner.begin_date = time_table.periods[0].period_start - 1.day
+ expect(cleaner.overlapping_periods).to_not include(time_table.periods[0])
+ end
+ end
+
context '#clean' do
let(:cleaner) { create(:clean_up, date_type: :before) }