From f2389ee672067e576ada56bf117681b30e38d0d4 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Thu, 2 Jul 2015 13:03:50 +0800 Subject: [PATCH] User Invoice Updater finalizes user invoices using global preferences for payment method and shipping method --- app/jobs/update_user_invoices.rb | 13 ++++- app/models/billable_period.rb | 2 +- spec/factories.rb | 6 +- spec/jobs/update_user_invoices_spec.rb | 79 +++++++++++++++++++++++--- 4 files changed, 86 insertions(+), 14 deletions(-) diff --git a/app/jobs/update_user_invoices.rb b/app/jobs/update_user_invoices.rb index 74b4701e05..34c54469a4 100644 --- a/app/jobs/update_user_invoices.rb +++ b/app/jobs/update_user_invoices.rb @@ -24,6 +24,8 @@ UpdateUserInvoices = Struct.new("UpdateUserInvoices") do adjustment.update_attributes( label: adjustment_label_from(billable_period), amount: billable_period.bill ) end + invoice.save + finalize(invoice) if Date.today.day == 1 end @@ -43,13 +45,18 @@ UpdateUserInvoices = Struct.new("UpdateUserInvoices") do 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.strftime("%d/%m") - ends = billable_period.begins_at.strftime("%d/%m") + begins = billable_period.begins_at.strftime("%d/%m/%y") + ends = billable_period.ends_at.strftime("%d/%m/%y") - "#{enterprise.name} (#{category}) [#{begins}-#{ends}]" + "#{enterprise.name} (#{category}) [#{begins} - #{ends}]" end def finalize(invoice) + # 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 end diff --git a/app/models/billable_period.rb b/app/models/billable_period.rb index 9e8009f050..836901fe63 100644 --- a/app/models/billable_period.rb +++ b/app/models/billable_period.rb @@ -8,7 +8,7 @@ class BillablePeriod < ActiveRecord::Base # Will make this more sophisicated in the future in that it will use global config variables to calculate return 0 if trial? if ['own', 'any'].include? sells - bill = (turnover * 0.02) + bill = (turnover * 0.02).round(2) bill > 50 ? 50 : bill else 0 diff --git a/spec/factories.rb b/spec/factories.rb index f76e472324..fefde6da07 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -219,11 +219,11 @@ FactoryGirl.define do factory :billable_period do begins_at { Time.now.beginning_of_month } ends_at { Time.now.beginning_of_month + 1.month } - sells { ['none', 'own', 'any'].sample } - trial { [true, false].sample } + sells { 'any' } + trial { false } enterprise owner { FactoryGirl.create :user } - turnover { BigDecimal.new("#{rand(5000)}.#{rand(99)}") } + turnover { rand(100000).to_f/100 } end end diff --git a/spec/jobs/update_user_invoices_spec.rb b/spec/jobs/update_user_invoices_spec.rb index 34b02e913e..bc64de31d2 100644 --- a/spec/jobs/update_user_invoices_spec.rb +++ b/spec/jobs/update_user_invoices_spec.rb @@ -46,6 +46,7 @@ describe UpdateUserInvoices do before do allow(user).to receive(:current_invoice) { invoice } + allow(invoice).to receive(:save) allow(updater).to receive(:finalize) end @@ -65,6 +66,10 @@ describe UpdateUserInvoices do expect(adjustments.map(&:label)).to eq ["Old Item"] end + it "saves to invoice" do + expect(invoice).to have_received(:save).once + end + it "finalizes the invoice" do expect(updater).to have_received(:finalize).with(invoice) end @@ -87,6 +92,10 @@ describe UpdateUserInvoices do expect(adjustments.map(&:label)).to eq ["BP1 Item", "BP2 Item"] end + it "saves to invoice" do + expect(invoice).to have_received(:save).once + end + it "does not finalize the invoice" do expect(updater).to_not have_received(:finalize) end @@ -96,17 +105,73 @@ describe UpdateUserInvoices do describe "finalize" do let!(:pm) { create(:payment_method, name: "PM1") } let!(:sm) { create(:shipping_method, name: "ship1") } - let!(:enterprise) { create(:distributor_enterprise, payment_methods: [pm], shipping_methods: [sm]) } - let!(:order) { create(:order, distributor: enterprise, shipping_method: sm) } + let!(:accounts_distributor) { create(:distributor_enterprise, payment_methods: [pm], shipping_methods: [sm]) } + let!(:invoice) { create(:order, distributor: accounts_distributor) } before do - order.line_items.clear + Spree::Config.set({ accounts_distributor_id: accounts_distributor.id }) + Spree::Config.set({ default_accounts_payment_method_id: pm.id }) + Spree::Config.set({ default_accounts_shipping_method_id: sm.id }) + invoice.line_items.clear end - it "finalizes the order" do - expect(order.completed_at).to be nil - updater.finalize(order) - expect(order.completed_at).to_not be nil + it "creates payment, assigns shipping method and finalizes the order" do + expect(invoice.completed_at).to be nil + updater.finalize(invoice) + expect(invoice.completed_at).to_not be nil + expect(invoice.payments.count).to eq 1 + expect(invoice.payments.first.payment_method).to eq pm + expect(invoice.shipping_method).to eq sm + end + end + end + + describe "validation spec" do + let!(:start_of_july) { Time.now.beginning_of_year + 6.months } + + let!(:updater) { UpdateUserInvoices.new } + + let!(:pm) { create(:payment_method, name: "Default Payment Method") } + let!(:sm) { create(:shipping_method, name: "Default Shipping Method") } + let!(:accounts_distributor) { create(:distributor_enterprise, payment_methods: [pm], shipping_methods: [sm]) } + + let!(:user) { create(:user) } + 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) } + + before do + sm.calculator.set_preference(:amount, 0); sm.calculator.save! + + Spree::Config.set({ accounts_distributor_id: accounts_distributor.id }) + Spree::Config.set({ default_accounts_payment_method_id: pm.id }) + Spree::Config.set({ default_accounts_shipping_method_id: sm.id }) + end + + context "updating an invoice" do + travel_to(20.days) + + it "does not creates an invoice when one does not already exist, but does not finalize it" do + expect{updater.perform}.to change{Spree::Order.count}.from(0).to(1) + invoice = user.orders.first + expect(invoice.completed_at).to be_nil + expect(invoice.total).to eq billable_period2.bill + billable_period3.bill + expect(invoice.payments.count).to eq 0 + expect(invoice.state).to eq 'cart' + end + end + + context "finalizing an invoice" do + travel_to(3.hours) + + it "creates an invoice and finalizes it" do + expect{updater.perform}.to change{Spree::Order.count}.from(0).to(1) + invoice = user.orders.first + expect(invoice.completed_at).to_not be_nil + expect(invoice.total).to eq billable_period1.bill + expect(invoice.payments.count).to eq 1 + expect(invoice.payments.first.amount).to eq billable_period1.bill + expect(invoice.state).to eq 'complete' end end end