From 13adb61b3af8a66f14aaf0cb02e2c0cbc6a22e7e Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Thu, 17 Sep 2015 18:49:12 +1000 Subject: [PATCH] Refactoring invoice update process to use new AccountInvoice model --- app/jobs/finalize_account_invoices.rb | 19 +- app/jobs/update_account_invoices.rb | 53 ++-- app/models/spree/user_decorator.rb | 6 - spec/factories.rb | 2 +- spec/jobs/finalize_account_invoices_spec.rb | 49 ++-- spec/jobs/update_account_invoices_spec.rb | 259 ++++++++------------ spec/models/spree/user_spec.rb | 36 --- 7 files changed, 163 insertions(+), 261 deletions(-) diff --git a/app/jobs/finalize_account_invoices.rb b/app/jobs/finalize_account_invoices.rb index 597e2994a3..75335a7aba 100644 --- a/app/jobs/finalize_account_invoices.rb +++ b/app/jobs/finalize_account_invoices.rb @@ -1,5 +1,5 @@ class FinalizeAccountInvoices - attr_reader :start_date, :end_date + attr_reader :year, :month, :start_date, :end_date def initialize(year = nil, month = nil) ref_point = Time.now - 1.month @@ -17,21 +17,18 @@ class FinalizeAccountInvoices def perform return unless settings_are_valid? - invoices = Spree::Order.where('distributor_id = (?) AND created_at >= (?) AND created_at < (?) AND completed_at IS NULL', - @accounts_distributor, start_date, end_date) - invoices.each do |invoice| - finalize(invoice) - end + invoice_orders = AccountInvoice.where(year: year, month: month).map(&:order) + invoice_orders.select{ |order| order.present? && order.completed_at.nil? }.each{ |order| finalize(order) } end - def finalize(invoice) + def finalize(invoice_order) # TODO: When we implement per-customer and/or per-user preferences around shipping and payment methods # we can update these to read from those preferences - invoice.payments.create(payment_method_id: Spree::Config.default_accounts_payment_method_id, amount: invoice.total) - invoice.update_attribute(:shipping_method_id, Spree::Config.default_accounts_shipping_method_id) - while invoice.state != "complete" - invoice.next + invoice_order.payments.create(payment_method_id: Spree::Config.default_accounts_payment_method_id, amount: invoice_order.total) + invoice_order.update_attribute(:shipping_method_id, Spree::Config.default_accounts_shipping_method_id) + while invoice_order.state != "complete" + invoice_order.next end end diff --git a/app/jobs/update_account_invoices.rb b/app/jobs/update_account_invoices.rb index 9ac8c4cccf..ec0b4052d2 100644 --- a/app/jobs/update_account_invoices.rb +++ b/app/jobs/update_account_invoices.rb @@ -1,5 +1,5 @@ class UpdateAccountInvoices - attr_reader :start_date, :end_date + attr_reader :year, :month, :start_date, :end_date def initialize(year = nil, month = nil) ref_point = Time.now - 1.day @@ -17,43 +17,34 @@ class UpdateAccountInvoices def perform return unless settings_are_valid? - # Find all users that have owned an enterprise at some point in the relevant period - enterprise_users = Spree::User.joins(:billable_periods) - .where('billable_periods.begins_at >= (?) AND billable_periods.ends_at <= (?) AND deleted_at IS NULL', start_date, end_date) - .select('DISTINCT spree_users.*') - - enterprise_users.each do |user| - billable_periods = user.billable_periods.where('begins_at >= (?) AND ends_at <= (?) AND deleted_at IS NULL', start_date, end_date).order(:enterprise_id, :begins_at) - update_invoice_for(user, billable_periods) - end + account_invoices = AccountInvoice.where(year: year, month: month) + account_invoices.each { |account_invoice| update(account_invoice) } end - def update_invoice_for(user, billable_periods) + def update(account_invoice) current_adjustments = [] - invoice = user.invoice_for(start_date, end_date) + unless account_invoice.order + account_invoice.order = account_invoice.user.orders.new(distributor_id: Spree::Config[:accounts_distributor_id]) + end - if invoice.persisted? && invoice.created_at != start_date - Bugsnag.notify(RuntimeError.new("InvoiceDateConflict"), { - start_date: start_date, - end_date: end_date, - existing_invoice: invoice.as_json - }) - elsif invoice.complete? + if account_invoice.order.complete? Bugsnag.notify(RuntimeError.new("InvoiceAlreadyFinalized"), { - invoice: invoice.as_json + invoice_order: account_invoice.order.as_json }) else - billable_periods.reject{ |bp| bp.turnover == 0 }.each do |billable_period| - current_adjustments << billable_period.ensure_correct_adjustment_for(invoice) + account_invoice.billable_periods.order(:enterprise_id, :begins_at).reject{ |bp| bp.turnover == 0 }.each do |billable_period| + current_adjustments << billable_period.ensure_correct_adjustment_for(account_invoice.order) end end - clean_up_and_save(invoice, current_adjustments) + account_invoice.save if current_adjustments.any? + + clean_up(account_invoice.order, current_adjustments) end - def clean_up_and_save(invoice, current_adjustments) + def clean_up(invoice_order, current_adjustments) # Snag and then delete any obsolete adjustments - obsolete_adjustments = invoice.adjustments.where('source_type = (?) AND id NOT IN (?)', "BillablePeriod", current_adjustments) + obsolete_adjustments = invoice_order.adjustments.where('source_type = (?) AND id NOT IN (?)', "BillablePeriod", current_adjustments) if obsolete_adjustments.any? Bugsnag.notify(RuntimeError.new("Obsolete Adjustments"), { @@ -64,16 +55,12 @@ class UpdateAccountInvoices obsolete_adjustments.destroy_all end - if current_adjustments.any? - # Invoices should be "created" at the beginning of the period to which they apply - invoice.created_at = start_date unless invoice.persisted? - invoice.save - else + if current_adjustments.empty? Bugsnag.notify(RuntimeError.new("Empty Persisted Invoice"), { - invoice: invoice.as_json - }) if invoice.persisted? + invoice_order: invoice_order.as_json + }) if invoice_order.persisted? - invoice.destroy + invoice_order.destroy end end diff --git a/app/models/spree/user_decorator.rb b/app/models/spree/user_decorator.rb index acaea63d7f..1b31230fea 100644 --- a/app/models/spree/user_decorator.rb +++ b/app/models/spree/user_decorator.rb @@ -48,12 +48,6 @@ Spree.user_class.class_eval do owned_enterprises(:reload).size < enterprise_limit end - def invoice_for(start_date, end_date) - existing = orders.where('distributor_id = (?) AND created_at >= (?) AND created_at < (?)', - Spree::Config[:accounts_distributor_id], start_date, end_date).first - existing || orders.new(distributor_id: Spree::Config[:accounts_distributor_id]) - end - private def limit_owned_enterprises diff --git a/spec/factories.rb b/spec/factories.rb index 2b2f30aa39..e0c8831b52 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -226,7 +226,7 @@ FactoryGirl.define do turnover { rand(100000).to_f/100 } account_invoice do AccountInvoice.where(user_id: owner_id, year: begins_at.year, month: begins_at.month).first || - FactoryGirl.create(user: owner, year: begins_at.year, month: begins_at.month) + FactoryGirl.create(:account_invoice, user: owner, year: begins_at.year, month: begins_at.month) end end diff --git a/spec/jobs/finalize_account_invoices_spec.rb b/spec/jobs/finalize_account_invoices_spec.rb index ae65540881..d057ad54fb 100644 --- a/spec/jobs/finalize_account_invoices_spec.rb +++ b/spec/jobs/finalize_account_invoices_spec.rb @@ -9,14 +9,21 @@ describe FinalizeAccountInvoices do describe "unit specs" do let!(:finalizer) { FinalizeAccountInvoices.new } let!(:start_of_july) { Time.now.beginning_of_year + 6.months } + let!(:year) { Time.now.year } describe "perform" do let!(:accounts_distributor) { create(:distributor_enterprise) } - let!(:invoice1) { create(:order, distributor: accounts_distributor, created_at: start_of_july - 10.days, completed_at: nil) } - let!(:invoice2) { create(:order, distributor: accounts_distributor, created_at: start_of_july - 10.days, completed_at: start_of_july - 10.days) } - let!(:invoice3) { create(:order, distributor: accounts_distributor, created_at: start_of_july, completed_at: nil) } - let!(:invoice4) { create(:order, distributor: accounts_distributor, created_at: start_of_july + 10.days, completed_at: nil) } - let!(:invoice5) { create(:order, distributor: accounts_distributor, created_at: start_of_july - 30.days, completed_at: nil) } + + #Invoice from June + let!(:account_invoice1) { create(:account_invoice, year: year, month: 6, order: create(:order, completed_at: nil))} + + # We don't care when it was completed, in the future or past + let!(:account_invoice2) { create(:account_invoice, year: year, month: 6, order: create(:order, completed_at: start_of_july - 10.days))} + let!(:account_invoice3) { create(:account_invoice, year: year, month: 6, order: create(:order, completed_at: start_of_july + 10.days))} + + # Invoices from July + let!(:account_invoice4) { create(:account_invoice, year: year, month: 7, order: create(:order, completed_at: nil))} + let!(:account_invoice5) { create(:account_invoice, year: year, month: 7, order: create(:order, completed_at: start_of_july + 10.days))} before do allow(Enterprise).to receive(:find_by_id) { accounts_distributor } @@ -70,38 +77,38 @@ describe FinalizeAccountInvoices do context "and no date arguments are passed to the job" do travel_to(3.days) - it "finalizes the uncompleted orders for accounts_distributor created in the previous calendar month" do + it "finalizes the uncompleted orders from account_invoices for the previous calendar month" do finalizer.perform - expect(finalizer).to have_received(:finalize).with(invoice1) - expect(finalizer).to_not have_received(:finalize).with(invoice3) - expect(finalizer).to_not have_received(:finalize).with(invoice2) - expect(finalizer).to_not have_received(:finalize).with(invoice4) - expect(finalizer).to have_received(:finalize).with(invoice5) + expect(finalizer).to have_received(:finalize).with(account_invoice1.order) + expect(finalizer).to_not have_received(:finalize).with(account_invoice2.order) + expect(finalizer).to_not have_received(:finalize).with(account_invoice3.order) + expect(finalizer).to_not have_received(:finalize).with(account_invoice4.order) + expect(finalizer).to_not have_received(:finalize).with(account_invoice5.order) end end - context "and specfic start and end dates are passed as arguments" do - let!(:finalizer) { FinalizeAccountInvoices.new(Time.now.year, 6) } + context "an a specific year and month are passed as arguments" do + let!(:finalizer) { FinalizeAccountInvoices.new(Time.now.year, 7) } before do allow(finalizer).to receive(:finalizer) end context "that ends in the past" do - travel_to(3.hours) + travel_to(1.month + 3.hours) - it "finalizes the uncompleted orders for accounts_distributor created in the specified calendar month" do + it "finalizes the uncompleted orders from account_invoices for the specified calendar month" do finalizer.perform - expect(finalizer).to have_received(:finalize).with(invoice1) - expect(finalizer).to_not have_received(:finalize).with(invoice3) - expect(finalizer).to_not have_received(:finalize).with(invoice2) - expect(finalizer).to_not have_received(:finalize).with(invoice4) - expect(finalizer).to have_received(:finalize).with(invoice5) + expect(finalizer).to_not have_received(:finalize).with(account_invoice1.order) + expect(finalizer).to_not have_received(:finalize).with(account_invoice2.order) + expect(finalizer).to_not have_received(:finalize).with(account_invoice3.order) + expect(finalizer).to have_received(:finalize).with(account_invoice4.order) + expect(finalizer).to_not have_received(:finalize).with(account_invoice5.order) end end context "that ends in the future" do - travel_to -1.day + travel_to 3.days it "does not finalize any orders" do finalizer.perform diff --git a/spec/jobs/update_account_invoices_spec.rb b/spec/jobs/update_account_invoices_spec.rb index 88f96d6ce6..a91523f00a 100644 --- a/spec/jobs/update_account_invoices_spec.rb +++ b/spec/jobs/update_account_invoices_spec.rb @@ -14,12 +14,14 @@ describe UpdateAccountInvoices do let!(:old_billable_period) { create(:billable_period, owner: user, begins_at: start_of_july - 1.month, ends_at: start_of_july) } let!(:billable_period1) { create(:billable_period, owner: user, begins_at: start_of_july, ends_at: start_of_july + 12.days) } let!(:billable_period2) { create(:billable_period, owner: user, begins_at: start_of_july + 12.days, ends_at: start_of_july + 20.days) } + let(:june_account_invoice) { old_billable_period.account_invoice } + let(:july_account_invoice) { billable_period1.account_invoice } describe "perform" do let(:accounts_distributor) { double(:accounts_distributor) } before do allow(Enterprise).to receive(:find_by_id) { accounts_distributor } - allow(updater).to receive(:update_invoice_for) + allow(updater).to receive(:update) allow(Bugsnag).to receive(:notify) end @@ -34,7 +36,7 @@ describe UpdateAccountInvoices do it "snags errors and doesn't run" do expect(Bugsnag).to have_received(:notify).with(RuntimeError.new("InvalidJobSettings"), anything) - expect(updater).to_not have_received(:update_invoice_for) + expect(updater).to_not have_received(:update) end end end @@ -43,85 +45,86 @@ describe UpdateAccountInvoices do context "on the first of the month" do travel_to(3.hours) - it "updates the user's current invoice with billable_periods from the previous month" do + it "updates invoices from the previous month" do updater.perform - expect(updater).to have_received(:update_invoice_for).once - .with(user, [old_billable_period]) + expect(updater).to have_received(:update).once + .with(june_account_invoice) + expect(updater).to_not have_received(:update) + .with(july_account_invoice) end end context "on other days" do travel_to(20.days) - it "updates the user's current invoice with billable_periods from the current month" do + it "updates invoices from the current month" do updater.perform - expect(updater).to have_received(:update_invoice_for).once - .with(user, [billable_period1, billable_period2]) + expect(updater).to have_received(:update).once + .with(july_account_invoice) end end - context "when specfic start and end dates are passed as arguments" do + context "when specfic a specific month (and year) are passed as arguments" do let!(:updater) { UpdateAccountInvoices.new(Time.now.year, 7) } before do - allow(updater).to receive(:update_invoice_for) + allow(updater).to receive(:update) end context "that just ended (in the past)" do travel_to(1.month) - it "updates the user's invoice with billable_periods from the previous month" do + it "updates invoices from the previous month" do updater.perform - expect(updater).to have_received(:update_invoice_for).once - .with(user, [billable_period1, billable_period2]) + expect(updater).to have_received(:update).once + .with(july_account_invoice) end end context "that starts in the past and ends in the future (ie. current_month)" do travel_to 30.days - it "updates the user's invoice with billable_periods from that current month" do + it "updates invoices from that current month" do updater.perform - expect(updater).to have_received(:update_invoice_for).once - .with(user, [billable_period1, billable_period2]) + expect(updater).to have_received(:update).once + .with(july_account_invoice) end end context "that starts in the future" do travel_to -1.days - it "snags an error and does not update the user's invoice" do + it "snags an error and does not update invoices" do updater.perform expect(Bugsnag).to have_received(:notify).with(RuntimeError.new("InvalidJobSettings"), anything) - expect(updater).to_not have_received(:update_invoice_for) + expect(updater).to_not have_received(:update) end end end end end - describe "update_invoice_for" do - let(:invoice) { create(:order, user: user) } - + describe "update" do before do - allow(user).to receive(:invoice_for) { invoice } - allow(updater).to receive(:clean_up_and_save) + allow(june_account_invoice).to receive(:save).and_call_original + allow(july_account_invoice).to receive(:save).and_call_original + allow(updater).to receive(:clean_up) allow(updater).to receive(:finalize) allow(Bugsnag).to receive(:notify) end - context "on the first of the month" do - travel_to(3.hours) + context "where an order for the invoice already exists" do + let!(:invoice_order) { create(:order, user: user) } before do - allow(old_billable_period).to receive(:adjustment_label) { "Old Item" } - allow(old_billable_period).to receive(:bill) { 666.66 } + expect(Spree::Order).to_not receive(:new) + allow(june_account_invoice).to receive(:order) { invoice_order } end - context "where the invoice was not created at start_date" do + context "where the order is already complete" do before do - invoice.update_attribute(:created_at, start_of_july - 1.month + 1.day) - updater.update_invoice_for(user, [old_billable_period]) + allow(invoice_order).to receive(:complete?) { true } + updater.update(june_account_invoice) end it "snags a bug" do @@ -129,110 +132,65 @@ describe UpdateAccountInvoices do end end - context "where the invoice was created at start_date" do + context "where the order is not complete" do before do - invoice.update_attribute(:created_at, start_of_july - 1.month) + allow(invoice_order).to receive(:complete?) { false } + updater.update(june_account_invoice) end - context "where the invoice is already complete" do - before do - allow(invoice).to receive(:complete?) { true } - updater.update_invoice_for(user, [old_billable_period]) - end - - it "snags a bug" do - expect(Bugsnag).to have_received(:notify) - end + it "creates adjustments for each billing item" do + adjustments = invoice_order.adjustments + expect(adjustments.map(&:source_id)).to eq [old_billable_period.id] + expect(adjustments.map(&:amount)).to eq [old_billable_period.bill] + expect(adjustments.map(&:label)).to eq [old_billable_period.adjustment_label] end - context "where the invoice is not complete" do - before do - allow(invoice).to receive(:complete?) { false } - updater.update_invoice_for(user, [old_billable_period]) - end + it "saves the order" do + expect(june_account_invoice).to have_received(:save) + expect(june_account_invoice.order).to be_persisted + end - it "creates adjustments for each billing item" do - adjustments = invoice.adjustments - expect(adjustments.map(&:source_id)).to eq [old_billable_period.id] - expect(adjustments.map(&:amount)).to eq [666.66] - expect(adjustments.map(&:label)).to eq ["Old Item"] - end - - it "cleans up and saves the invoice" do - expect(updater).to have_received(:clean_up_and_save).with(invoice, anything).once - end + it "cleans up the order" do + expect(updater).to have_received(:clean_up).with(invoice_order, anything).once end end end - context "on other days" do - travel_to(20.days) - + context "where an order for the invoice does not already exist" do + let!(:accounts_distributor) { create(:distributor_enterprise) } before do - 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 } + Spree::Config.set({ accounts_distributor_id: accounts_distributor.id }) + updater.update(july_account_invoice) end - context "where the invoice was not created at start_date" do - before do - invoice.update_attribute(:created_at, start_of_july + 1.day) - updater.update_invoice_for(user, [billable_period1, billable_period2]) - end - - it "snags a bug" do - expect(Bugsnag).to have_received(:notify) - end + it "creates adjustments for each billing item" do + adjustments = july_account_invoice.order.adjustments + expect(adjustments.map(&:source_id)).to eq [billable_period1.id, billable_period2.id] + expect(adjustments.map(&:amount)).to eq [billable_period1.bill, billable_period2.bill] + expect(adjustments.map(&:label)).to eq [billable_period1.adjustment_label, billable_period2.adjustment_label] end - context "where the invoice was created at start_date" do - before do - invoice.update_attribute(:created_at, start_of_july) - end + it "saves the order" do + expect(july_account_invoice).to have_received(:save) + expect(july_account_invoice.order).to be_persisted + end - context "where the invoice is already complete" do - before do - allow(invoice).to receive(:complete?) { true } - updater.update_invoice_for(user, [billable_period1, billable_period2]) - end - - it "snags a bug" do - expect(Bugsnag).to have_received(:notify) - end - end - - context "where the invoice is not complete" do - before do - allow(invoice).to receive(:complete?) { false } - updater.update_invoice_for(user, [billable_period1, billable_period2]) - end - - it "creates adjustments for each billing item" do - adjustments = invoice.adjustments - expect(adjustments.map(&:source_id)).to eq [billable_period1.id, billable_period2.id] - expect(adjustments.map(&:amount)).to eq [123.45, 543.21] - expect(adjustments.map(&:label)).to eq ["BP1 Item", "BP2 Item"] - end - - it "cleans up and saves the invoice" do - expect(updater).to have_received(:clean_up_and_save).with(invoice, anything).once - end - end + it "cleans up order" do + expect(updater).to have_received(:clean_up).with(july_account_invoice.order, anything).once end end end - describe "clean_up_and_save" do - let!(:invoice) { create(:order) } - let!(:obsolete1) { create(:adjustment, adjustable: invoice) } - let!(:obsolete2) { create(:adjustment, adjustable: invoice) } - let!(:current1) { create(:adjustment, adjustable: invoice) } - let!(:current2) { create(:adjustment, adjustable: invoice) } + describe "clean_up" do + let!(:invoice_order) { create(:order) } + let!(:obsolete1) { create(:adjustment, adjustable: invoice_order) } + let!(:obsolete2) { create(:adjustment, adjustable: invoice_order) } + let!(:current1) { create(:adjustment, adjustable: invoice_order) } + let!(:current2) { create(:adjustment, adjustable: invoice_order) } before do - allow(invoice).to receive(:save) - allow(invoice).to receive(:destroy) + allow(invoice_order).to receive(:save) + allow(invoice_order).to receive(:destroy) allow(Bugsnag).to receive(:notify) end @@ -244,35 +202,27 @@ describe UpdateAccountInvoices do before do allow(obsolete_adjustments).to receive(:destroy_all) - allow(invoice).to receive(:adjustments) { double(:adjustments, where: obsolete_adjustments) } - updater.clean_up_and_save(invoice, current_adjustments) + allow(invoice_order).to receive(:adjustments) { double(:adjustments, where: obsolete_adjustments) } + updater.clean_up(invoice_order, current_adjustments) end it "destroys obsolete adjustments and snags a bug" do expect(obsolete_adjustments).to have_received(:destroy_all) expect(Bugsnag).to have_received(:notify).with(RuntimeError.new("Obsolete Adjustments"), anything) end - - it "saves the invoice" do - expect(invoice).to have_received(:save) - end end context "and obsolete adjustments are not present" do let!(:obsolete_adjustments) { [] } before do - allow(invoice).to receive(:adjustments) { double(:adjustments, where: obsolete_adjustments) } - updater.clean_up_and_save(invoice, current_adjustments) + allow(invoice_order).to receive(:adjustments) { double(:adjustments, where: obsolete_adjustments) } + updater.clean_up(invoice_order, current_adjustments) end it "has no bugs to snag" do expect(Bugsnag).to_not have_received(:notify) end - - it "saves the invoice" do - expect(invoice).to have_received(:save) - end end end @@ -284,8 +234,8 @@ describe UpdateAccountInvoices do before do allow(obsolete_adjustments).to receive(:destroy_all) - allow(invoice).to receive(:adjustments) { double(:adjustments, where: obsolete_adjustments) } - updater.clean_up_and_save(invoice, current_adjustments) + allow(invoice_order).to receive(:adjustments) { double(:adjustments, where: obsolete_adjustments) } + updater.clean_up(invoice_order, current_adjustments) end it "destroys obsolete adjustments and snags a bug" do @@ -293,8 +243,8 @@ describe UpdateAccountInvoices do expect(Bugsnag).to have_received(:notify).with(RuntimeError.new("Obsolete Adjustments"), anything) end - it "destroys the invoice and snags a bug" do - expect(invoice).to have_received(:destroy) + it "destroys the order and snags a bug" do + expect(invoice_order).to have_received(:destroy) expect(Bugsnag).to have_received(:notify).with(RuntimeError.new("Empty Persisted Invoice"), anything) end end @@ -303,16 +253,16 @@ describe UpdateAccountInvoices do let!(:obsolete_adjustments) { [] } before do - allow(invoice).to receive(:adjustments) { double(:adjustments, where: obsolete_adjustments) } - updater.clean_up_and_save(invoice, current_adjustments) + allow(invoice_order).to receive(:adjustments) { double(:adjustments, where: obsolete_adjustments) } + updater.clean_up(invoice_order, current_adjustments) end it "has no bugs to snag" do expect(Bugsnag).to_not have_received(:notify).with(RuntimeError.new("Obsolete Adjustments"), anything) end - it "destroys the invoice and snags a bug" do - expect(invoice).to have_received(:destroy) + it "destroys the order and snags a bug" do + expect(invoice_order).to have_received(:destroy) expect(Bugsnag).to have_received(:notify).with(RuntimeError.new("Empty Persisted Invoice"), anything) end end @@ -331,64 +281,67 @@ describe UpdateAccountInvoices do let!(:billable_period1) { create(:billable_period, sells: 'any', owner: user, begins_at: start_of_july - 1.month, ends_at: start_of_july) } let!(:billable_period2) { create(:billable_period, owner: user, begins_at: start_of_july, ends_at: start_of_july + 10.days) } let!(:billable_period3) { create(:billable_period, owner: user, begins_at: start_of_july + 12.days, ends_at: start_of_july + 20.days) } + let!(:july_account_invoice) { billable_period2.account_invoice } before do Spree::Config.set({ accounts_distributor_id: accounts_distributor.id }) end - context "when no invoice currently exists" do + context "when no invoice_order currently exists" do context "when relevant billable periods exist" do travel_to(20.days) - it "creates an invoice" do + it "creates an invoice_order" do expect{updater.perform}.to change{Spree::Order.count}.from(0).to(1) - invoice = user.orders.first - expect(invoice.completed_at).to be_nil - billable_adjustments = invoice.adjustments.where('source_type = (?)', 'BillablePeriod') + invoice_order = july_account_invoice.reload.order + expect(user.orders.first).to eq invoice_order + expect(invoice_order.completed_at).to be_nil + billable_adjustments = invoice_order.adjustments.where('source_type = (?)', 'BillablePeriod') expect(billable_adjustments.map(&:amount)).to eq [billable_period2.bill, billable_period3.bill] - expect(invoice.total).to eq billable_period2.bill + billable_period3.bill - expect(invoice.payments.count).to eq 0 - expect(invoice.state).to eq 'cart' + expect(invoice_order.total).to eq billable_period2.bill + billable_period3.bill + expect(invoice_order.payments.count).to eq 0 + expect(invoice_order.state).to eq 'cart' end end context "when no relevant billable periods exist" do travel_to(1.month + 5.days) - it "does not create an invoice" do + it "does not create an order" do expect{updater.perform}.to_not change{Spree::Order.count}.from(0) end end end - context "when an invoice currently exists" do - let!(:invoice) { create(:order, user: user, distributor: accounts_distributor, created_at: start_of_july) } - let!(:billable_adjustment) { create(:adjustment, adjustable: invoice, source_type: 'BillablePeriod') } + context "when an order already exists" do + let!(:invoice_order) { create(:order, user: user, distributor: accounts_distributor, created_at: start_of_july) } + let!(:billable_adjustment) { create(:adjustment, adjustable: invoice_order, source_type: 'BillablePeriod') } before do - invoice.line_items.clear + invoice_order.line_items.clear + july_account_invoice.update_attribute(:order, invoice_order) end context "when relevant billable periods exist" do travel_to(20.days) - it "updates the invoice, and clears any obsolete invoices" do + it "updates the order, and clears any obsolete invoices" do expect{updater.perform}.to_not change{Spree::Order.count} - invoice = user.orders.first - expect(invoice.completed_at).to be_nil - billable_adjustments = invoice.adjustments.where('source_type = (?)', 'BillablePeriod') + invoice_order = user.orders.first + expect(invoice_order.completed_at).to be_nil + billable_adjustments = invoice_order.adjustments.where('source_type = (?)', 'BillablePeriod') expect(billable_adjustments).to_not include billable_adjustment expect(billable_adjustments.map(&:amount)).to eq [billable_period2.bill, billable_period3.bill] - expect(invoice.total).to eq billable_period2.bill + billable_period3.bill - expect(invoice.payments.count).to eq 0 - expect(invoice.state).to eq 'cart' + expect(invoice_order.total).to eq billable_period2.bill + billable_period3.bill + expect(invoice_order.payments.count).to eq 0 + expect(invoice_order.state).to eq 'cart' end end context "when no relevant billable periods exist" do travel_to(1.month + 5.days) - it "destroys the invoice" do + it "destroys the order" do expect{updater.perform}.to_not change{Spree::Order.count}.from(1).to(0) end end diff --git a/spec/models/spree/user_spec.rb b/spec/models/spree/user_spec.rb index e2eecb5b64..7fefd56afb 100644 --- a/spec/models/spree/user_spec.rb +++ b/spec/models/spree/user_spec.rb @@ -79,40 +79,4 @@ describe Spree.user_class do end end end - - describe "invoice_for" do - let!(:user) { create(:user) } - let!(:accounts_distributor) { create(:distributor_enterprise) } - let!(:start_of_month) { Time.now.beginning_of_month } - - before do - Spree::Config.accounts_distributor_id = accounts_distributor.id - end - - context "where no relevant invoice exists for the given period" do - # Created during previous month - let!(:order1) { create(:order, user: user, created_at: start_of_month - 3.hours, completed_at: nil, distributor: accounts_distributor) } - # Incorrect distributor - let!(:order3) { create(:order, user: user, created_at: start_of_month + 3.hours, completed_at: nil, distributor: create(:distributor_enterprise)) } - # Incorrect user - let!(:order4) { create(:order, user: create(:user), created_at: start_of_month + 3.hours, completed_at: nil, distributor: accounts_distributor) } - - it "creates a new invoice" do - current_invoice = user.invoice_for(start_of_month, start_of_month + 20.days) - expect(current_invoice).to be_a_new Spree::Order - expect(current_invoice.completed_at).to be nil - expect(current_invoice.distributor).to eq accounts_distributor - expect(current_invoice.user).to eq user - end - end - - context "where an invoice exists for the current month" do - let!(:order) { create(:order, user: user, created_at: start_of_month + 3.hours, completed_at: nil, distributor: accounts_distributor) } - - it "returns the existing invoice" do - current_invoice = user.invoice_for(start_of_month, start_of_month + 20.days) - expect(current_invoice).to eq order - end - end - end end