mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
WIP: Basic structure for daily job to update user invoices
This commit is contained in:
59
app/jobs/update_user_invoices.rb
Normal file
59
app/jobs/update_user_invoices.rb
Normal 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
|
||||
@@ -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
|
||||
|
||||
|
||||
52
spec/jobs/update_user_invoices_spec.rb
Normal file
52
spec/jobs/update_user_invoices_spec.rb
Normal 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
|
||||
Reference in New Issue
Block a user