From 79497d28d2bf7e0dc4af9bb0936287610fe3219b Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Sat, 12 Sep 2015 11:43:33 +1000 Subject: [PATCH] Associating billable periods with the relevant adjustment, and moving labelling logic to model --- app/jobs/update_user_invoices.rb | 27 +--------------- app/models/billable_period.rb | 44 ++++++++++++++++++++++++++ spec/jobs/update_user_invoices_spec.rb | 5 +-- spec/models/billable_period_spec.rb | 27 ++++++++++++++++ 4 files changed, 75 insertions(+), 28 deletions(-) create mode 100644 spec/models/billable_period_spec.rb diff --git a/app/jobs/update_user_invoices.rb b/app/jobs/update_user_invoices.rb index 9567c1e0e9..ae5010d367 100644 --- a/app/jobs/update_user_invoices.rb +++ b/app/jobs/update_user_invoices.rb @@ -40,38 +40,13 @@ class UpdateUserInvoices }) else billable_periods.reject{ |bp| bp.turnover == 0 }.each do |billable_period| - adjustment = invoice.adjustments.where(source_id: billable_period).first - adjustment ||= invoice.adjustments.new( adjustment_attrs_from(billable_period), :without_protection => true) - adjustment.update_attributes( label: adjustment_label_from(billable_period), amount: billable_period.bill ) - current_adjustments << adjustment + current_adjustments << billable_period.ensure_correct_adjustment_for(invoice) end end clean_up_and_save(invoice, current_adjustments) end - def adjustment_attrs_from(billable_period) - # We should ultimately have an EnterprisePackage model, which holds all info about shop type, producer, trials, etc. - # It should also implement a calculator that we can use here by specifying the package as the originator of the - # adjustment, meaning that adjustments are created and updated using Spree's existing architecture. - - { source: billable_period, - originator: nil, - mandatory: true, - locked: false - } - end - - def adjustment_label_from(billable_period) - enterprise = billable_period.enterprise.version_at(billable_period.begins_at) - category = enterprise.category.to_s.titleize - category += (billable_period.trial ? " Trial" : "") - begins = billable_period.begins_at.localtime.strftime("%d/%m/%y") - ends = billable_period.ends_at.localtime.strftime("%d/%m/%y") - - "#{enterprise.name} (#{category}) [#{begins} - #{ends}]" - end - def clean_up_and_save(invoice, current_adjustments) # Snag and then delete any obsolete adjustments obsolete_adjustments = invoice.adjustments.where('source_type = (?) AND id NOT IN (?)', "BillablePeriod", current_adjustments) diff --git a/app/models/billable_period.rb b/app/models/billable_period.rb index c7a9074a87..e8dbecd09c 100644 --- a/app/models/billable_period.rb +++ b/app/models/billable_period.rb @@ -1,5 +1,6 @@ class BillablePeriod < ActiveRecord::Base belongs_to :enterprise + has_one :adjustment, :as => :source, class_name: "Spree::Adjustment" #, :dependent => :destroy belongs_to :owner, class_name: 'Spree::User', foreign_key: :owner_id default_scope where(deleted_at: nil) @@ -23,7 +24,50 @@ class BillablePeriod < ActiveRecord::Base end end + def adjustment_label + enterprise_version = enterprise.version_at(begins_at) + category = enterprise_version.category.to_s.titleize + category += (trial ? " Trial" : "") + begins = begins_at.localtime.strftime("%d/%m/%y") + ends = ends_at.localtime.strftime("%d/%m/%y") + + "#{enterprise_version.name} (#{category}) [#{begins} - #{ends}]" + end + def delete self.update_column(:deleted_at, Time.now) end + + def ensure_correct_adjustment_for(invoice) + if adjustment + # adjustment.originator = enterprise.package + adjustment.update_attributes( label: adjustment_label, amount: bill ) + else + self.adjustment = invoice.adjustments.new( adjustment_attrs, :without_protection => true ) + end + + if Spree::Config.account_bill_inc_tax + adjustment.set_included_tax! Spree::Config.account_bill_tax_rate + else + adjustment.set_included_tax! 0 + end + + adjustment + end + + private + + def adjustment_attrs + # We should ultimately have an EnterprisePackage model, which holds all info about shop type, producer, trials, etc. + # It should also implement a calculator that we can use here by specifying the package as the originator of the + # adjustment, meaning that adjustments are created and updated using Spree's existing architecture. + + { label: adjustment_label, + amount: bill, + source: self, + originator: nil, # enterprise.package + mandatory: true, + locked: false + } + end end diff --git a/spec/jobs/update_user_invoices_spec.rb b/spec/jobs/update_user_invoices_spec.rb index 233aa31359..e730108e03 100644 --- a/spec/jobs/update_user_invoices_spec.rb +++ b/spec/jobs/update_user_invoices_spec.rb @@ -104,7 +104,7 @@ describe UpdateUserInvoices do travel_to(3.hours) before do - allow(updater).to receive(:adjustment_label_from).exactly(1).times.and_return("Old Item") + allow(old_billable_period).to receive(:adjustment_label) { "Old Item" } allow(old_billable_period).to receive(:bill) { 666.66 } end @@ -159,7 +159,8 @@ describe UpdateUserInvoices do travel_to(20.days) before do - allow(updater).to receive(:adjustment_label_from).exactly(2).times.and_return("BP1 Item", "BP2 Item") + allow(billable_period1).to receive(:adjustment_label) { "BP1 Item" } + allow(billable_period2).to receive(:adjustment_label) { "BP2 Item" } allow(billable_period1).to receive(:bill) { 123.45 } allow(billable_period2).to receive(:bill) { 543.21 } end diff --git a/spec/models/billable_period_spec.rb b/spec/models/billable_period_spec.rb new file mode 100644 index 0000000000..1d5cd19507 --- /dev/null +++ b/spec/models/billable_period_spec.rb @@ -0,0 +1,27 @@ +require 'spec_helper' + +describe Customer, type: :model do + describe 'ensure_correct_adjustment' do + let!(:start_of_july) { Time.now.beginning_of_year + 6.months } + let!(:user) { create(:user) } + let!(:invoice) { create(:order, user: user) } + let!(:billable_period) { create(:billable_period, owner: user, begins_at: start_of_july, ends_at: start_of_july + 12.days) } + + before do + allow(billable_period).to receive(:bill) { 99 } + allow(billable_period).to receive(:adjustment_label) { "Label for adjustment" } + Spree::Config.set({ account_bill_inc_tax: true }) + Spree::Config.set({ account_bill_tax_rate: 0.1 }) + end + + context "when no adjustment currently exists" do + it "creates an adjustment on the given order" do + expect(invoice.total_tax).to eq 0.0 + expect(billable_period.adjustment).to be nil + billable_period.ensure_correct_adjustment_for(invoice) + expect(billable_period.adjustment).to be_a Spree::Adjustment + expect(invoice.total_tax).to eq 9.0 + end + end + end +end