git-svn-id: file:///svn-source/pmgr/branches/yafr_20090716@360 97e9348a-65ac-dc4b-aefc-98561f571b83
321 lines
11 KiB
PHP
321 lines
11 KiB
PHP
<?php
|
|
class LedgerEntry extends AppModel {
|
|
|
|
var $belongsTo = array(
|
|
'Transaction',
|
|
'Account',
|
|
'Ledger',
|
|
);
|
|
|
|
var $hasOne = array(
|
|
'Payment',
|
|
);
|
|
|
|
var $hasMany = array(
|
|
);
|
|
|
|
var $hasAndBelongsToMany = array(
|
|
// The Debit half of the double entry matching THIS Credit (if it is one)
|
|
'DebitEntry' => array(
|
|
'className' => 'LedgerEntry',
|
|
'joinTable' => 'double_entries',
|
|
'linkalias' => 'DDE',
|
|
'foreignKey' => 'credit_entry_id',
|
|
'associationForeignKey' => 'debit_entry_id',
|
|
),
|
|
|
|
// The Credit half of the double entry matching THIS Debit (if it is one)
|
|
'CreditEntry' => array(
|
|
'className' => 'LedgerEntry',
|
|
'joinTable' => 'double_entries',
|
|
'linkalias' => 'CDE',
|
|
'foreignKey' => 'debit_entry_id',
|
|
'associationForeignKey' => 'credit_entry_id',
|
|
),
|
|
);
|
|
|
|
|
|
/**************************************************************************
|
|
**************************************************************************
|
|
**************************************************************************
|
|
* function: debitCreditFields
|
|
* - Returns the fields necessary to determine whether the queried
|
|
* entries are a debit, or a credit, and also the effect each have
|
|
* on the overall balance of the account/ledger.
|
|
*/
|
|
|
|
function debitCreditFields($sum = false, $entry_name = 'Entry', $account_name = 'Account') {
|
|
$fields = array
|
|
(
|
|
($sum ? 'SUM(' : '') .
|
|
"IF({$entry_name}.type = 'DEBIT'," .
|
|
" {$entry_name}.amount, NULL)" .
|
|
($sum ? ')' : '') . ' AS debit' . ($sum ? 's' : ''),
|
|
|
|
($sum ? 'SUM(' : '') .
|
|
"IF({$entry_name}.type = 'CREDIT'," .
|
|
" {$entry_name}.amount, NULL)" .
|
|
($sum ? ')' : '') . ' AS credit' . ($sum ? 's' : ''),
|
|
|
|
($sum ? 'SUM(' : '') .
|
|
"IF(${account_name}.type IN ('ASSET', 'EXPENSE')," .
|
|
" IF({$entry_name}.type = 'DEBIT', 1, -1)," .
|
|
" IF({$entry_name}.type = 'CREDIT', 1, -1))" .
|
|
" * IF({$entry_name}.amount, {$entry_name}.amount, 0)" .
|
|
($sum ? ')' : '') . ' AS balance',
|
|
);
|
|
|
|
if ($sum)
|
|
$fields[] = "COUNT({$entry_name}.id) AS entries";
|
|
|
|
return $fields;
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
**************************************************************************
|
|
**************************************************************************
|
|
* function: addCharge
|
|
* - Adds a new charge
|
|
*/
|
|
|
|
function addCharge($data, $transaction, $customer_id, $lease_id = null) {
|
|
// Create some models for convenience
|
|
$A = new Account();
|
|
|
|
// Assume this will succeed
|
|
$ret = true;
|
|
|
|
// Establish the key charge parameters
|
|
$charge = array_intersect_key($data, array('stamp'=>1, 'amount'=>1, 'account_id'=>1));
|
|
|
|
$charge['customer_id'] = $customer_id;
|
|
$charge['lease_id'] = $lease_id;
|
|
$charge['type'] = 'CHARGE';
|
|
|
|
$ids = $this->Entry->Ledger->Account->postLedgerEntry
|
|
($transaction,
|
|
$charge,
|
|
array('debit_ledger_id' => $A->currentLedgerID($data['account_id']),
|
|
'credit_ledger_id' => $A->currentLedgerID($A->accountReceivableAccountID())
|
|
) + $data
|
|
);
|
|
|
|
if ($ids['error'])
|
|
$ret = false;
|
|
|
|
return $ids['charge_id'];
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
**************************************************************************
|
|
**************************************************************************
|
|
* function: addPayment
|
|
* - Adds a new payment
|
|
*/
|
|
|
|
function addPayment($data, $transaction, $customer_id, $lease_id = null) {
|
|
// Create some models for convenience
|
|
$A = new Account();
|
|
|
|
// Assume this will succeed
|
|
$ret = true;
|
|
|
|
// Establish the key payment parameters
|
|
$payment = array_intersect_key($data, array('stamp'=>1, 'name'=>1, 'monetary_type'=>1,
|
|
'data1'=>1, 'data2'=>1, 'data3'=>1, 'data4'=>1,
|
|
'amount'=>1, 'account_id'=>1));
|
|
$payment['customer_id'] = $customer_id;
|
|
$payment['type'] = 'PAYMENT';
|
|
|
|
$ids = $this->Entry->Ledger->Account->postLedgerEntry
|
|
($transaction,
|
|
$payment,
|
|
array('debit_ledger_id' => $A->currentLedgerID($data['account_id']),
|
|
'credit_ledger_id' => $A->currentLedgerID($A->accountReceivableAccountID())
|
|
) + $data
|
|
);
|
|
|
|
if ($ids['error'])
|
|
$ret = false;
|
|
|
|
return $ids['payment_id'];
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
**************************************************************************
|
|
**************************************************************************
|
|
* function: reverse
|
|
* - Reverses the charges
|
|
*
|
|
* SAMPLE MOVE IN w/ PRE PAYMENT
|
|
* DEPOSIT RENT A/R RECEIPT CHECK PETTY BANK
|
|
* ------- ------- ------- ------- ------- ------- -------
|
|
* |25 | 25| | | | |
|
|
* | |20 20| | | | |
|
|
* | |20 20| | | | |
|
|
* | |20 20| | | | |
|
|
* | | |25 25| | | |
|
|
* | | |20 20| | | |
|
|
* | | |20 20| | | |
|
|
* | | |20 20| | | |
|
|
* | | | |85 85| | |
|
|
* | | | | |85 | 85|
|
|
|
|
* MOVE OUT and REFUND FINAL MONTH
|
|
* DEPOSIT RENT C/P RECEIPT CHECK PETTY BANK
|
|
* ------- ------- ------- ------- ------- ------- -------
|
|
* 25| | |25 | | | | t20 e20a
|
|
* | 20| |20 | | | | t20 e20b
|
|
|
|
* -ONE REFUND CHECK-
|
|
* | | 25| |25 | | | t30 e30a
|
|
* | | 20| |20 | | | t30 e30b
|
|
* | | | 45| | | |45 t40 e40
|
|
* -OR MULTIPLE-
|
|
* | | 15| |15 | | | t50a e50a
|
|
* | | | 15| | |15 | t60a e60a
|
|
* | | 30| |30 | | | t50b e50b
|
|
* | | | 30| | | |30 t60b e60b
|
|
* | | | | | | |
|
|
|
|
|
|
OPTION 1
|
|
* |-25 | -25| | | | |
|
|
* | |-20 -20| | | | |
|
|
* | | |-25 -25| | | |
|
|
* | | |-20 -20| | | |
|
|
|
|
OPTION 2
|
|
* |-25 | | -25| | | |
|
|
* | |-20 | -20| | | |
|
|
* | | | |-15 | -15| |
|
|
* | | | |-30 | | -30|
|
|
* | | | | | | |
|
|
*
|
|
*/
|
|
function reverse($ledger_entries, $stamp = null) {
|
|
pr(array('Entry::reverse',
|
|
compact('ledger_entries', 'stamp')));
|
|
|
|
// If the user only wants to reverse one ID, we'll allow it
|
|
if (!is_array($ledger_entries))
|
|
$ledger_entries = $this->find
|
|
('all', array
|
|
('contain' => false,
|
|
'conditions' => array('Entry.id' => $ledger_entries)));
|
|
|
|
$A = new Account();
|
|
|
|
$ar_account_id = $A->accountReceivableAccountID();
|
|
$receipt_account_id = $A->receiptAccountID();
|
|
|
|
$transaction_id = null;
|
|
foreach ($ledger_entries AS $entry) {
|
|
$entry = $entry['Entry'];
|
|
$amount = -1*$entry['amount'];
|
|
|
|
if (isset($entry['credit_account_id']))
|
|
$refund_account_id = $entry['credit_account_id'];
|
|
elseif (isset($entry['CreditLedger']['Account']['id']))
|
|
$refund_account_id = $entry['CreditLedger']['Account']['id'];
|
|
elseif (isset($entry['credit_ledger_id']))
|
|
$refund_account_id = $this->Ledger->accountID($entry['credit_ledger_id']);
|
|
else
|
|
return null;
|
|
|
|
// post new refund in the income account
|
|
$ids = $A->postEntry
|
|
(array('transaction_id' => $transaction_id),
|
|
null,
|
|
array('debit_ledger_id' => $A->currentLedgerID($ar_account_id),
|
|
'credit_ledger_id' => $A->currentLedgerID($refund_account_id),
|
|
'effective_date' => $entry['effective_date'],
|
|
'through_date' => $entry['through_date'],
|
|
'amount' => $amount,
|
|
'lease_id' => $entry['lease_id'],
|
|
'customer_id' => $entry['customer_id'],
|
|
'comment' => "Refund; Entry #{$entry['id']}",
|
|
),
|
|
array('debit' => array
|
|
(array('Entry' =>
|
|
array('id' => $entry['id'],
|
|
'amount' => $amount))),
|
|
)
|
|
);
|
|
|
|
if ($ids['error'])
|
|
return null;
|
|
$transaction_id = $ids['transaction_id'];
|
|
|
|
pr(array('checkpoint' => 'Posted Refund Ledger Entry',
|
|
compact('ids', 'amount', 'refund_account_id', 'ar_account_id')));
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
**************************************************************************
|
|
**************************************************************************
|
|
* function: stats
|
|
* - Returns summary data from the requested ledger entry
|
|
*/
|
|
function stats($id = null, $query = null, $set = null) {
|
|
$this->queryInit($query);
|
|
unset($query['group']);
|
|
|
|
if (!isset($query['link']['DoubleEntry']))
|
|
$query['link']['DoubleEntry'] = array();
|
|
/* if (!isset($query['link']['DoubleEntry']['fields'])) */
|
|
/* $query['link']['DoubleEntry']['fields'] = array(); */
|
|
|
|
if (isset($id))
|
|
$query['conditions'][] = array('Entry.id' => $id);
|
|
|
|
if (isset($set))
|
|
$set = strtoupper($set);
|
|
|
|
//pr(array('stats()', compact('id', 'query', 'set')));
|
|
|
|
$rtypes = array('charge', 'payment',
|
|
// 'debit', 'credit',
|
|
);
|
|
|
|
$stats = array();
|
|
foreach($rtypes AS $rtype) {
|
|
$Rtype = ucfirst($rtype);
|
|
|
|
if (($rtype == 'charge' && (!isset($set) || $set == 'PAYMENT')) ||
|
|
($rtype == 'payment' && (!isset($set) || $set == 'CHARGE'))
|
|
/* ($rtype == 'debit' && (!isset($set) || $set == 'CREDIT')) || */
|
|
/* ($rtype == 'credit' && (!isset($set) || $set == 'DEBIT')) */
|
|
) {
|
|
|
|
$rquery = $query;
|
|
$rquery['link'][$Rtype] =
|
|
array('fields' => array("SUM(COALESCE(Applied{$Rtype}.amount,0)) AS reconciled"));
|
|
|
|
$rquery['fields'] = array();
|
|
//$rquery['fields'][] = "SUM(DoubleEntry.amount) AS total";
|
|
$rquery['fields'][] = "SUM(DoubleEntry.amount) - SUM(COALESCE(Applied{$Rtype}.amount,0)) AS balance";
|
|
$rquery['conditions'][] = array("Applied{$Rtype}.id !=" => null);
|
|
|
|
$result = $this->find('first', $rquery);
|
|
//pr(compact('Rtype', 'rquery', 'result'));
|
|
|
|
$sumfld = $Rtype;
|
|
$stats[$sumfld] = $result[0];
|
|
/* if (!isset($stats[$sumfld]['applied'])) */
|
|
/* $stats[$sumfld]['applied'] = 0; */
|
|
}
|
|
}
|
|
|
|
return $stats;
|
|
}
|
|
|
|
}
|