I've already written most of the functional parts to a custom billing system for my business (Wireless ISP,) but have stumped myself with a bit of it.
Here's the basic overview: It's a recurring billing system for my customers that automatically generates and sends invoices to each customer every month. However, I need to allow check/cash payments since I deal with local customers and also need to allow pre-payment so I can't just use something like Stripe's recurring billing. Essentially the payments are not directly associated with invoices to allow for these type of payments.
models/invoice.rb
class Invoice < ActiveRecord::Base
belongs_to :customer
has_many :line_items
has_many :invoice_payments
has_many :payments, through: :invoice_payments
models/payment.rb
class Payment < ActiveRecord::Base
belongs_to :customer
models/customer.rb
class Customer < ActiveRecord::Base
has_many :subscriptions, dependent: :destroy
has_many :services, through: :subscriptions
has_many :invoices, :order => 'id DESC'
has_many :payments
I need a method that will automatically associate all unapplied payments to all unpaid invoices. Right now I'm putting that as def apply_unapplied_payments
on the customer model, but will likely abstract it out later in to its own module in lib/.
This is what I've done so far in models/customer.rb
def apply_unapplied_payments
unpaid_invoices = invoices.find_by_status("unpaid")
unapplied_payments = payments.where("invoice_id is null")
unpaid_invoices.each do |invoice|
# find the oldest unapplied payment
# apply payment to this invoice
# if payment > invoice, keep whatever amount is left and move to next invoice
# apply leftover amount to invoice, if invoice is still unpaid, move to next unapplied payment
end
customer.update_balance
end
Any suggestions for what to fill in the pseudocode with? I'm open to any level of refactoring, so please let me know if you can think of a better way to handle this!