WIP: Basic structure for daily job to update user invoices

This commit is contained in:
Rob Harrington
2015-06-29 13:07:51 +08:00
parent 550434dfe8
commit b4e58a1a79
3 changed files with 112 additions and 0 deletions

View File

@@ -0,0 +1,59 @@
UpdateUserInvoices = Struct.new("UpdateUserInvoices") do
def perform
# If it is the first of the month, update invoices for the previous month up until midnight last night
# Otherwise, update invoices for the current month
start_date = (Time.now - 1.day).beginning_of_month
end_date = Time.now.beginning_of_day
# Find all users that have owned an enterprise at some point in the current billing period (this month)
enterprise_users = Spree::User.joins(:billable_periods)
.where('billable_periods.begins_at >= (?) AND billable_periods.ends_at <= (?)', start_date, end_date)
.select('DISTINCT spree_users.*')
enterprise_users.each do |user|
update_invoice_for(user, user.billable_periods.where('begins_at >= (?) AND ends_at <= (?)', start_date, end_date))
end
end
def update_invoice_for(user, billable_periods)
invoice = user.current_invoice
billable_periods.each do |billable_period|
adjustment = invoice.adjustments.where(source: billable_period).first
adjustment ||= invoice.adjustments.new( adjustment_attrs_from(billable_period) )
adjustment.label = adjustment_label_from(billable_period)
adjustment.amount = billable_period.bill
adjustment.save
end
finalize(invoice)
end
def adjustment_attrs_from(billable_period)
{ :source => billable_period,
:originator => billable_period,
:mandatory => mandatory,
:locked => true }
end
def adjustment_label_from(billable_period)
category = enterprise.version_at(billable_period.begins_at).reify.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")
"#{enterprise.name} (#{category}) [#{begins}-#{ends}]"
end
def finalize(invoice)
if Date.today.day == 1
while @order.state != "complete"
@order.next
end
user.current_invoice.process
# Mark current invoice as completed
# Create a new invoice
user.current_invoice = new_invoice_for(user)
end
end
end

View File

@@ -7,6 +7,7 @@ Spree.user_class.class_eval do
has_many :enterprises, through: :enterprise_roles
has_many :owned_enterprises, class_name: 'Enterprise', foreign_key: :owner_id, inverse_of: :owner
has_many :owned_groups, class_name: 'EnterpriseGroup', foreign_key: :owner_id, inverse_of: :owner
has_many :billable_periods, foreign_key: :owner_id, inverse_of: :owner
has_one :cart
has_many :customers

View File

@@ -0,0 +1,52 @@
require 'spec_helper'
def travel_to(time)
around { |example| Timecop.travel(start_of_july + time) { example.run } }
end
describe UpdateUserInvoices do
describe "units specs" do
let!(:start_of_july) { Time.now.beginning_of_year + 6.months }
let!(:updater) { UpdateUserInvoices.new }
describe "perform" do
let!(:user) { create(:user) }
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) }
before do
allow(updater).to receive(:update_invoice_for)
end
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
updater.perform
expect(updater).to have_received(:update_invoice_for).once
.with(user, [old_billable_period])
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
updater.perform
expect(updater).to have_received(:update_invoice_for).once
.with(user, [billable_period1, billable_period2])
end
end
end
describe "update_invoice_for" do
let!(:user) { create(:user) }
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) }
end
end
end