Bill Item Update handles enterprises created part-way through the month

This commit is contained in:
Rob Harrington
2015-06-25 17:36:57 +08:00
parent af2bc99c71
commit b736e209ca
2 changed files with 226 additions and 23 deletions

View File

@@ -5,11 +5,11 @@ UpdateBillItems = Struct.new(:lala) do
start_date = (Time.now - 1.day).beginning_of_month
end_date = Time.now.beginning_of_day
enterprises = Enterprise.select([:id, :name, :owner_id, :sells, :shop_trial_start_date])
enterprises = Enterprise.select([:id, :name, :owner_id, :sells, :shop_trial_start_date, :created_at])
# Cycle through users
# Cycle through enterprises
enterprises.each do |enterprise|
# Cycle through owned_enterprises
# Cycle through previous versions of this enterprise
versions = enterprise.versions.where('created_at >= (?)', start_date)
bill_items = []
@@ -17,7 +17,7 @@ UpdateBillItems = Struct.new(:lala) do
trial_expiry = enterprise.shop_trial_expiry
versions.each do |version|
begins_at = bill_items.last.andand.ends_at || start_date
begins_at = bill_items.last.andand.ends_at || [start_date, enterprise.created_at].max
ends_at = version.created_at
split_for_trial(version.reify, begins_at, ends_at, trial_start, trial_expiry).each do |bill_item|
@@ -26,7 +26,7 @@ UpdateBillItems = Struct.new(:lala) do
end
# Update / create bill_item for current start
begins_at = bill_items.last.andand.ends_at || start_date
begins_at = bill_items.last.andand.ends_at || [start_date, enterprise.created_at].max
ends_at = end_date
split_for_trial(enterprise, begins_at, ends_at, trial_start, trial_expiry).each do |bill_item|

View File

@@ -5,18 +5,22 @@ describe UpdateBillItems do
# Chose july to test with because June has 30 days and so is easy to calculate end date for shop trial
let!(:start_of_july) { Time.now.beginning_of_year + 6.months }
let!(:enterprise) { create(:supplier_enterprise, sells: 'any') }
let!(:order1) { create(:order, completed_at: start_of_july + 5.days, distributor: enterprise) }
let!(:order2) { create(:order, completed_at: start_of_july + 15.days, distributor: enterprise) }
let!(:order3) { create(:order, completed_at: start_of_july + 25.days, distributor: enterprise) }
before do
order1.line_items = [ create(:line_item, price: 12.56, order: order1) ]
order2.line_items = [ create(:line_item, price: 87.44, order: order2) ]
order3.line_items = [ create(:line_item, price: 50.00, order: order3) ]
[order1, order2, order3].each(&:update!)
end
context "where the enterprise existed at the beginning of the current billing period", versioning: true do
let!(:enterprise) { create(:supplier_enterprise, created_at: start_of_july - 2.months, sells: 'any') }
let!(:order1) { create(:order, completed_at: start_of_july + 5.days, distributor: enterprise) }
let!(:order2) { create(:order, completed_at: start_of_july + 15.days, distributor: enterprise) }
let!(:order3) { create(:order, completed_at: start_of_july + 25.days, distributor: enterprise) }
before do
order1.line_items = [ create(:line_item, price: 12.56, order: order1) ]
order2.line_items = [ create(:line_item, price: 87.44, order: order2) ]
order3.line_items = [ create(:line_item, price: 50.00, order: order3) ]
[order1, order2, order3].each(&:update!)
enterprise.update_attribute(:created_at, start_of_july - 2.months)
end
context "where the sells property of the enterprise has not been altered within the current billing period" do
@@ -88,7 +92,7 @@ describe UpdateBillItems do
context "where the sells property of the enterprise has been altered within the current billing period" do
before do
Timecop.travel(start_of_july + 10.days) do
Timecop.freeze(start_of_july + 10.days) do
# NOTE: Sells is changed between when order1 and order2 are placed
enterprise.update_attribute(:sells, 'own')
end
@@ -110,6 +114,7 @@ describe UpdateBillItems do
it "splits the billing period into a separate item for each sells value" do
expect(bill_items.count).to eq 2
expect(bill_items.map(&:sells)).to eq ['any', 'own']
expect(bill_items.map(&:trial)).to eq [false, false]
end
it "splits the turnover for the month to date" do
@@ -121,10 +126,6 @@ describe UpdateBillItems do
context "where a trial ended during the current billing period, after sells was changed" do
before do
enterprise.update_attribute(:shop_trial_start_date, start_of_july - 10.days)
Timecop.travel(start_of_july + 10.days) do
# NOTE: Sells is changed between when order1 and order2 are placed
enterprise.update_attribute(:sells, 'own')
end
UpdateBillItems.new('lala').perform
end
@@ -208,10 +209,212 @@ describe UpdateBillItems do
end
end
context "where the enterprise was created after the beginning of the current billing period" do
context "where the enterprise was created after the beginning of the current billing period", versioning: true do
before do
enterprise.update_attribute(:created_at, start_of_july + 7.days)
end
context "where the sells property of the enterprise has not been altered within the current billing period" do
before do
Timecop.travel(start_of_july + 28.days)
end
after do
Timecop.return
end
context "where no trial information has been set" do
before do
UpdateBillItems.new('lala').perform
end
let(:bill_items) { BillItem.order(:id) }
it "creates a single bill item" do
expect(bill_items.count).to eq 1
expect(bill_items.map(&:sells)).to eq ['any']
expect(bill_items.map(&:trial)).to eq [false]
expect(bill_items.map(&:begins_at)).to eq [start_of_july + 7.days]
expect(bill_items.map(&:ends_at)).to eq [start_of_july + 28.days]
end
it "ignores orders completed before the enterprise was created" do
expect(bill_items.first.turnover).to eq (order2.total + order3.total)
end
end
context "where a trial ended during the current billing period" do
before do
enterprise.update_attribute(:shop_trial_start_date, start_of_july - 10.days)
UpdateBillItems.new('lala').perform
end
let(:bill_items) { BillItem.order(:id) }
it "splits out the trial period into a separate bill item" do
expect(bill_items.count).to eq 2
expect(bill_items.map(&:sells)).to eq ['any', 'any']
expect(bill_items.map(&:trial)).to eq [true, false]
expect(bill_items.map(&:begins_at)).to eq [start_of_july + 7.days, start_of_july + 20.days]
expect(bill_items.map(&:ends_at)).to eq [start_of_july + 20.days, start_of_july + 28.days]
end
it "splits out the trial period into a separate bill item" do
expect(bill_items.first.turnover).to eq order2.total
expect(bill_items.last.turnover).to eq order3.total
end
end
context "where the trial began part-way through the current billing period" do
before do
enterprise.update_attribute(:shop_trial_start_date, start_of_july + 10.days)
UpdateBillItems.new('lala').perform
end
let(:bill_items) { BillItem.order(:id) }
it "splits out the trial period into a separate bill item" do
expect(bill_items.count).to eq 2
expect(bill_items.map(&:sells)).to eq ['any', 'any']
expect(bill_items.map(&:trial)).to eq [false, true]
expect(bill_items.map(&:begins_at)).to eq [start_of_july + 7.days, start_of_july + 10.days]
expect(bill_items.map(&:ends_at)).to eq [start_of_july + 10.days, start_of_july + 28.days]
end
it "splits the turnover for the month to date" do
expect(bill_items.first.turnover).to eq 0
expect(bill_items.last.turnover).to eq order2.total + order3.total
end
end
end
context "where the sells property of the enterprise has been altered within the current billing period" do
before do
Timecop.freeze(start_of_july + 10.days) do
# NOTE: Sells is changed between when order1 and order2 are placed
enterprise.update_attribute(:sells, 'own')
end
Timecop.travel(start_of_july + 28.days)
end
after do
Timecop.return
end
context "where no trial information has been set" do
before do
UpdateBillItems.new('lala').perform
end
let(:bill_items) { BillItem.order(:id) }
it "splits the billing period into a separate item for each sells value" do
expect(bill_items.count).to eq 2
expect(bill_items.map(&:sells)).to eq ['any', 'own']
expect(bill_items.map(&:trial)).to eq [false, false]
expect(bill_items.map(&:begins_at)).to eq [start_of_july + 7.days, start_of_july + 10.days]
expect(bill_items.map(&:ends_at)).to eq [start_of_july + 10.days, start_of_july + 28.days]
end
it "splits the turnover for the month to date" do
expect(bill_items.first.turnover).to eq 0
expect(bill_items.last.turnover).to eq order2.total + order3.total
end
end
context "where a trial ended during the current billing period, after sells was changed" do
before do
enterprise.update_attribute(:shop_trial_start_date, start_of_july - 10.days)
UpdateBillItems.new('lala').perform
end
let(:bill_items) { BillItem.order(:id) }
it "splits out the distinct sells periods and trial period into separate bill items" do
expect(bill_items.count).to eq 3
expect(bill_items.map(&:sells)).to eq ['any', 'own', 'own']
expect(bill_items.map(&:trial)).to eq [true, true, false]
expect(bill_items.map(&:begins_at)).to eq [start_of_july + 7.days, start_of_july + 10.days, start_of_july + 20.days]
expect(bill_items.map(&:ends_at)).to eq [start_of_july + 10.days, start_of_july + 20.days, start_of_july + 28.days]
end
it "splits out the trial period into a separate bill item" do
expect(bill_items.first.turnover).to eq 0
expect(bill_items.second.turnover).to eq order2.total
expect(bill_items.last.turnover).to eq order3.total
end
end
context "where a trial ended during the current billing period, before sells was changed" do
before do
enterprise.update_attribute(:shop_trial_start_date, start_of_july - 22.days)
UpdateBillItems.new('lala').perform
end
let(:bill_items) { BillItem.order(:id) }
it "splits out the distinct sells periods and trial period into separate bill items" do
expect(bill_items.count).to eq 3
expect(bill_items.map(&:sells)).to eq ['any', 'any', 'own']
expect(bill_items.map(&:trial)).to eq [true, false, false]
expect(bill_items.map(&:begins_at)).to eq [start_of_july + 7.days, start_of_july + 8.days, start_of_july + 10.days]
expect(bill_items.map(&:ends_at)).to eq [start_of_july + 8.days, start_of_july + 10.days, start_of_july + 28.days]
end
it "splits out the trial period into a separate bill item" do
expect(bill_items.first.turnover).to eq 0
expect(bill_items.second.turnover).to eq 0
expect(bill_items.last.turnover).to eq (order2.total + order3.total)
end
end
context "where the trial began part-way through the current billing period, after sells was changed" do
before do
enterprise.update_attribute(:shop_trial_start_date, start_of_july + 18.days)
UpdateBillItems.new('lala').perform
end
let(:bill_items) { BillItem.order(:id) }
it "splits out the distinct sells periods and trial period into separate bill items" do
expect(bill_items.count).to eq 3
expect(bill_items.map(&:sells)).to eq ['any', 'own', 'own']
expect(bill_items.map(&:trial)).to eq [false, false, true]
expect(bill_items.map(&:begins_at)).to eq [start_of_july + 7.days, start_of_july + 10.days, start_of_july + 18.days]
expect(bill_items.map(&:ends_at)).to eq [start_of_july + 10.days, start_of_july + 18.days, start_of_july + 28.days]
end
it "splits out the trial period into a separate bill item" do
expect(bill_items.first.turnover).to eq 0
expect(bill_items.second.turnover).to eq order2.total
expect(bill_items.last.turnover).to eq order3.total
end
end
context "where the trial began part-way through the current billing period, before sells was changed" do
before do
enterprise.update_attribute(:shop_trial_start_date, start_of_july + 8.days)
UpdateBillItems.new('lala').perform
end
let(:bill_items) { BillItem.order(:id) }
it "splits out the distinct sells periods and trial period into separate bill items" do
expect(bill_items.count).to eq 3
expect(bill_items.map(&:sells)).to eq ['any', 'any', 'own']
expect(bill_items.map(&:trial)).to eq [false, true, true]
expect(bill_items.map(&:begins_at)).to eq [start_of_july + 7.days, start_of_july + 8.days, start_of_july + 10.days]
expect(bill_items.map(&:ends_at)).to eq [start_of_july + 8.days, start_of_july + 10.days, start_of_july + 28.days]
end
it "splits out the trial period into a separate bill item" do
expect(bill_items.first.turnover).to eq 0
expect(bill_items.second.turnover).to eq 0
expect(bill_items.last.turnover).to eq (order2.total + order3.total)
end
end
end
end
end
end