Method: Client#recommend_payment_assignments_for

Defined in:
app/models/client.rb

#recommend_payment_assignments_for(amount) ⇒ Object

Returns an array of unsaved InvoicePayment objects, with unset invoice_ids, and ‘recommended’ amounts. If the provided amount exactly equals an payment’s unalloated amount, we return a InvoicePayment for the oldest such matching payment. Otherwise, we start applying the amount to payments in ascending order by issued_date.



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'app/models/client.rb', line 133

def recommend_payment_assignments_for(amount)
  amount = amount.to_money
  
  pymnts = unassigned_payments(
    :all,
    # Using this order forces the closest-amount match to be above anything else, followed by date sorting
    :order => '(amount_unallocated_in_cents = %d) DESC, paid_on ASC, created_at ASC' % amount.cents
  )

  current_client_balance = pymnts.inject(Money.new(0)){|total, pmnt| total - pmnt.amount_unallocated}

  pymnts.collect{ |unallocated_pmnt|
    if amount > 0 or current_client_balance < 0
      assignment = (unallocated_pmnt.amount_unallocated > amount) ?
        amount :
        unallocated_pmnt.amount_unallocated
      
      current_client_balance += assignment
      amount -= assignment
      
      InvoicePayment.new :payment => unallocated_pmnt, :amount => assignment if assignment > 0
    end
  }.compact
end