. * * Originally authored by Deon George * * @author Deon George * @copyright 2009 Deon George * @link http://osb.leenooks.net * @license http://www.gnu.org/licenses/ * @package AgileBill * @subpackage Modules:Payment */ /** * The main AgileBill Payment Class * * @package AgileBill * @subpackage Modules:Payment */ class payment_item extends OSB_module { public function allocate($VAR) { return $this->doAllocate($VAR); } /** * Allocate a payment to invoices * * @uses invoice * @uses payment */ public function doAllocate($VAR) { $db = DB(); # Get the payment invoices for this account. include_once(PATH_MODULES.'payment/payment.inc.php'); $po = new payment; # Get our payment information if (! $payment = $po->sPaymentsBal($VAR['payment_id'])) return false; # Check that our allocation is correct. $total = round(array_sum($VAR['payment_item_allocate']),2); if ($total > $payment['total_amt']) { global $C_debug; $C_debug->alert(sprintf('%s: (%3.2f/%3.2f) ?',_('Payment over allocated'),$total,$payment['total_amt'])); return false; } # If this payment has been allocated to some invoices, collect those details $payment_items = $this->sPaymentAllocation($VAR['payment_id']); # Get the unpaid invoices for this account. include_once(PATH_MODULES.'invoice/invoice.inc.php'); $io = new invoice; $invoices = $io->sInvoicesAcc($payment['account_id'],array_keys($VAR['payment_item_allocate'])); # Apply the new allocation foreach ($VAR['payment_item_allocate'] as $invoice => $alloc) { if (! trim($alloc)) continue; # Sanity check if (! isset($invoices[$invoice])) { global $C_debug; $C_debug->alert(sprintf('Payment for invoice doesnt exist? (%s)?',$invoices['invoice'])); # This payment has been processed if (isset($payment_items[$invoice])) unset($payment_items[$invoice]); continue; } elseif ((isset($payment_items[$invoice]) && $invoices[$invoice]['balance']+$payment_items[$invoice] < $alloc) || (! isset($payment_items[$invoice]) && $invoices[$invoice]['balance'] < $alloc)) { global $C_debug; $C_debug->alert(sprintf('Over allocation for invoice %s - remaining balance is %s?',$invoice,$invoices[$invoice]['balance'])); # This payment has been processed if (isset($payment_items[$invoice])) unset($payment_items[$invoice]); continue; } # Have we already applied payments to this invoice in the past if (isset($payment_items[$invoice])) { if ($alloc != $payment_items[$invoice]) { # Record the adjusted payment details $db->Execute(sqlUpdate('payment_item',array('date_last'=>time(),'alloc_amt'=>$alloc),array('where'=>array('payment_id'=>$VAR['payment_id'],'invoice_id'=>$invoice,'alloc_amt'=>$payment_items[$invoice])))); # Adjust the invoice balance $db->Execute(sqlUpdate('invoice',array('billed_amt'=>$invoices[$invoice]['billed_amt']+$alloc-$payment_items[$invoice]),array('where'=>array('id'=>$invoice,'billed_amt'=>$invoices[$invoice]['billed_amt'])))); } # This payment has been processed unset($payment_items[$invoice]); # New payment allocation } else { # Reduce the invoice balance $db->Execute(sqlUpdate('invoice',array('billed_amt'=>$invoices[$invoice]['billed_amt']+$alloc),array('where'=>array('id'=>$invoice)))); # Record the payment $db->Execute(sqlInsert($db,'payment_item',array('date_orig'=>time(),'date_last'=>time(),'payment_id'=>$VAR['payment_id'],'invoice_id'=>$invoice,'alloc_amt'=>$alloc))); } } # Any left over payments need to be reversed foreach ($payment_items as $invoice => $alloc) { if (! $alloc) continue; $db->Execute(sqlUpdate('payment_item',array('date_last'=>time(),'alloc_amt'=>0),array('where'=>array('payment_id'=>$VAR['payment_id'],'invoice_id'=>$invoice,'alloc_amt'=>$payment_items[$invoice])))); $db->Execute(sqlUpdate('invoice',array('billed_amt'=>$invoices[$invoice]['billed_amt']-$alloc),array('where'=>array('id'=>$invoice,'billed_amt'=>$invoices[$invoice]['billed_amt'])))); } # Force the refresh of the account balances $io->sInvoicesBal(null,true); } /** * Get the payment allocation for a payment ID * * @param $payment_id Payment ID to retrieve * @return array Invoices and the payment location */ public function sPaymentAllocation($payment_id) { static $sPaymentAllocation = array(); if (! isset($sPaymentsBalance[$payment_id])) { $db = DB(); $rs = $db->Execute(sqlSelect('payment_item','invoice_id,alloc_amt',array('where'=>array('payment_id'=>$payment_id)))); if ($rs && $rs->RecordCount()) { while (! $rs->EOF) { $sPaymentsBalance[$payment_id][$rs->fields['invoice_id']] = $rs->fields['alloc_amt']; $rs->MoveNext(); } } } return $sPaymentsBalance[$payment_id]; } } ?>