Billable Period Updater does not run when end_date is in the future

This commit is contained in:
Rob Harrington
2015-07-08 15:29:41 +08:00
parent fb01f6d32a
commit cc26321ab2
2 changed files with 87 additions and 28 deletions

View File

@@ -1,9 +1,7 @@
UpdateBillablePeriods = Struct.new("UpdateBillablePeriods") do
UpdateBillablePeriods = Struct.new("UpdateBillablePeriods", :year, :month) do
def perform
# If it is the first of the month, calculate turnover for the previous month up until midnight last night
# Otherwise, calculate turnover for the current month
start_date = (Time.now - 1.day).beginning_of_month
end_date = Time.now.beginning_of_day
return unless end_date <= Time.now
job_start_time = Time.now
enterprises = Enterprise.select([:id, :name, :owner_id, :sells, :shop_trial_start_date, :created_at])
@@ -32,7 +30,7 @@ UpdateBillablePeriods = Struct.new("UpdateBillablePeriods") do
split_for_trial(enterprise, begins_at, ends_at, trial_start, trial_expiry)
clean_up_untouched_billable_periods_for(enterprise, start_date, job_start_time)
clean_up_untouched_billable_periods_for(enterprise, job_start_time)
end
end
@@ -76,14 +74,14 @@ UpdateBillablePeriods = Struct.new("UpdateBillablePeriods") do
billable_period.touch
end
def clean_up_untouched_billable_periods_for(enterprise, start_of_month, job_start_time)
def clean_up_untouched_billable_periods_for(enterprise, job_start_time)
# Snag and then delete any BillablePeriods which overlap
obsolete_billable_periods = enterprise.billable_periods.where('ends_at >= (?) AND updated_at < (?)', start_of_month, job_start_time)
obsolete_billable_periods = enterprise.billable_periods.where('ends_at >= (?) AND updated_at < (?)', start_date, job_start_time)
if obsolete_billable_periods.any?
current_billable_periods = enterprise.billable_periods.where('ends_at >= (?) AND updated_at >= (?)', start_of_month, job_start_time)
current_billable_periods = enterprise.billable_periods.where('ends_at >= (?) AND updated_at >= (?)', start_date, job_start_time)
Delayed::Worker.logger.info "#{enterprise.name} #{start_of_month.strftime("%F %T")} #{job_start_time.strftime("%F %T")}"
Delayed::Worker.logger.info "#{enterprise.name} #{start_date.strftime("%F %T")} #{job_start_time.strftime("%F %T")}"
Delayed::Worker.logger.info "#{obsolete_billable_periods.first.updated_at.strftime("%F %T")}"
Bugsnag.notify(RuntimeError.new("Obsolete BillablePeriods"), {
@@ -94,4 +92,26 @@ UpdateBillablePeriods = Struct.new("UpdateBillablePeriods") do
obsolete_billable_periods.each(&:delete)
end
private
def start_date
# Start at the beginning of the specified month
# or at the beginning of the month (prior to midnight last night) if none specified
@start_date ||= if month && year
Time.new(year, month)
else
(Time.now - 1.day).beginning_of_month
end
end
def end_date
# Stop at the end of the specified month
# or at midnight last night if no month is specified
@end_date ||= if month && year
Time.new(year, month) + 1.month
else
Time.now.beginning_of_day
end
end
end

View File

@@ -14,31 +14,67 @@ describe UpdateBillablePeriods do
let!(:enterprise) { create(:supplier_enterprise, created_at: start_of_july - 1.month, sells: 'any') }
before do
expect(updater).to receive(:clean_up_untouched_billable_periods_for).once
allow(Enterprise).to receive(:select) { [enterprise] }
end
context "on the first of the month" do
travel_to(3.hours)
context "when no arguments are passed to the job" do
before do
expect(updater).to receive(:clean_up_untouched_billable_periods_for).once
end
it "processes the previous month" do
expect(updater).to receive(:split_for_trial)
.with(enterprise, start_of_july - 1.month, start_of_july, nil, nil)
updater.perform
context "on the first of the month" do
travel_to(3.hours)
it "processes the previous month" do
expect(updater).to receive(:split_for_trial)
.with(enterprise, start_of_july - 1.month, start_of_july, nil, nil)
updater.perform
end
end
context "on all other days" do
travel_to(1.day + 3.hours)
it "processes the current month up until previous midnight" do
expect(updater).to receive(:split_for_trial)
.with(enterprise, start_of_july, start_of_july + 1.day, nil, nil)
updater.perform
end
end
end
context "on all other days" do
travel_to(1.day + 3.hours)
context "when a specfic year and month are passed as arguments" do
let!(:updater) { UpdateBillablePeriods.new(Time.now.year, 6) }
it "processes the current month up until previous midnight" do
expect(updater).to receive(:split_for_trial)
.with(enterprise, start_of_july, start_of_july + 1.day, nil, nil)
updater.perform
before do
allow(updater).to receive(:split_for_trial)
end
context "that ends in the past" do
travel_to(3.hours)
it "processes the previous month" do
expect(updater).to receive(:split_for_trial)
.with(enterprise, start_of_july - 1.month, start_of_july, nil, nil)
updater.perform
end
end
context "that ends in the future" do
travel_to(-1.day)
it "does not run" do
expect(updater).to_not receive(:split_for_trial)
updater.perform
end
end
end
context "when an enterprise is created before the beginning of the current month" do
before do
expect(updater).to receive(:clean_up_untouched_billable_periods_for).once
end
travel_to(28.days)
context "when no alterations to sells or owner have been made during the current month" do
@@ -142,6 +178,7 @@ describe UpdateBillablePeriods do
context "when an enterprise is created during the current month" do
before do
expect(updater).to receive(:clean_up_untouched_billable_periods_for).once
enterprise.update_attribute(:created_at, start_of_july + 10.days)
end
@@ -157,6 +194,7 @@ describe UpdateBillablePeriods do
pending "when an enterprise is deleted during the current month" do
before do
expect(updater).to receive(:clean_up_untouched_billable_periods_for).once
enterprise.update_attribute(:deleted_at, start_of_july + 20.days)
end
@@ -409,15 +447,16 @@ describe UpdateBillablePeriods do
end
context "cleaning up untouched billable periods" do
let(:now) { Time.now }
let(:job_start_time) { Time.now }
let(:enterprise) { create(:enterprise) }
let!(:bp1) { create(:billable_period, enterprise: enterprise, updated_at: now + 2.seconds, begins_at: start_of_july, ends_at: start_of_july + 5.days ) }
let!(:bp2) { create(:billable_period, enterprise: enterprise, updated_at: now + 2.seconds, begins_at: start_of_july + 5.days, ends_at: start_of_july + 10.days ) }
let!(:bp3) { create(:billable_period, enterprise: enterprise, updated_at: now - 5.seconds, begins_at: start_of_july, ends_at: start_of_july + 10.days ) }
let!(:bp1) { create(:billable_period, enterprise: enterprise, updated_at: job_start_time + 2.seconds, begins_at: start_of_july, ends_at: start_of_july + 5.days ) }
let!(:bp2) { create(:billable_period, enterprise: enterprise, updated_at: job_start_time + 2.seconds, begins_at: start_of_july + 5.days, ends_at: start_of_july + 10.days ) }
let!(:bp3) { create(:billable_period, enterprise: enterprise, updated_at: job_start_time - 5.seconds, begins_at: start_of_july, ends_at: start_of_july + 10.days ) }
before do
allow(Bugsnag).to receive(:notify)
updater.clean_up_untouched_billable_periods_for(enterprise, start_of_july, now)
allow(updater).to receive(:start_date) { start_of_july }
updater.clean_up_untouched_billable_periods_for(enterprise, job_start_time)
end
it "soft deletes untouched billable_periods" do