array('numeric'), 'name' => array('notempty'), 'tillable' => array('boolean') ); var $belongsTo = array( ); var $hasMany = array( 'LedgerEntry', ); /************************************************************************** ************************************************************************** ************************************************************************** * function: nsf * - Flags the ledger entry as having insufficient funds * - NOTE: nsf only works if given the monetary source id * to transaction e3, below * - NOTE: In order to show that the rent formerly considered * "collected" is now recognized in reverse, we must * credit A/R with a negative amount in order to * reconcile it against the Rent<->A/R ledger entry. * * FEE RENT A/R RECEIPT CHECK NSF BANK * ------- ------- ------- ------- ------- ------- ------- * | |30 30| | | | | t1 e1a : R e2/e7a : * | |20 20| | | | | t1 e1b : R e2/e7b : * | | | | | | | * | | |30 30| | | | t2 e2a : R e3 : R e1a * | | |20 20| | | | t2 e2b : R e3 : R e1b * | | | |50 50| | | t2 e3 : R e4 : R e2 * | | | | | | | * | | | | |50 | 50| t3 e4 : : R e3 * | | | | | | | * | | | | | |-50 -50| t4 e5 : : R e6 * | | | |-50 | -50| | t5 e6 : R e5 : R e7a/e7b * | | |-30 -30| | | | t6 e7a : R e6 : R e1a * | | |-20 -20| | | | t6 e7b : R e6 : R e1b * |35 | 35| | | | | t6 e8 * */ function nsf($id, $stamp = null) { pr(array('MonetarySource::nsf', compact('id'))); $A = new Account(); // Get the LedgerEntries that use this monetary source $source = $this->find ('first', array('contain' => array(/* e3 */ 'LedgerEntry' => array('Transaction.id', 'MonetarySource.id', 'Customer.id', 'Lease.id', /* e3 debit */ 'DebitLedger' => /* e.g. CHECK Ledger */ array('fields' => array(), 'Account' => /* e.g. CHECK Account */ array('fields' => array('id', 'name'), 'conditions' => array('Account.payable' => 1, 'Account.type' => 'ASSET'), ), ), /* e3 credit */ 'CreditLedger' => /* i.e. RECEIPT Ledger */ array('fields' => array('id'), 'Account' => /* i.e. RECEIPT Account */ array('fields' => array('id', 'name'), 'conditions' => array('Account.id' => $A->receiptAccountID()), ), ), /* e2 */ 'DebitReconciliationLedgerEntry' => array(/* e2 credit */ 'CreditLedger' => /* i.e. A/R Ledger */ array('fields' => array(), 'Account' => /* i.e. A/R Account */ array('fields' => array(), 'conditions' => array('Account.id' => $A->accountReceivableAccountID()), ), ), /* e1 */ // STUPID CakePHP bug screws up CLASS contains CLASS. // Use the same class, but with different name. 'DebitReconciliationLedgerEntry2', ), /* e4 */ 'CreditReconciliationLedgerEntry' => array(/* e4 debit */ 'DebitLedger' => /* e.g. BANK Ledger */ array('fields' => array('id'), 'Account' => /* e.g. BANK Account */ array('fields' => array('id', 'name'), 'conditions' => array('Account.depositable' => 1), ), ), ), ), ), 'conditions' => array(array('MonetarySource.id' => $id)), )); pr($source); $nsf_account_id = $A->nsfAccountID(); $nsf_fee_account_id = $A->nsfChargeAccountID(); $ar_account_id = $A->accountReceivableAccountID(); $receipt_account_id = $A->receiptAccountID(); $t4_id = null; $t5_id = null; foreach ($source['LedgerEntry'] AS $e3) { // We expect only a single e4 entry $e4 = $e3['CreditReconciliationLedgerEntry']; if (count($e4) < 1) continue; if (count($e4) > 1) die('Too many e4 entries'); // Pullup e4 from the single member array $e4 = $e4[0]; // e3 amount $amount = -$e3['amount']; // e4 account $bank_account_id = $e4['DebitLedger']['account_id']; // post new e5 $e5_ids = $A->postLedgerEntry (array('transaction_id' => $t4_id), null, array('debit_ledger_id' => $A->currentLedgerID($bank_account_id), 'credit_ledger_id' => $A->currentLedgerID($nsf_account_id), 'effective_date' => $stamp, 'amount' => $amount, 'lease_id' => $e3['lease_id'], 'customer_id' => $e3['customer_id'], 'comment' => "NSF Bank Reversal; Monetary Source #{$id}", ) ); if ($e5_ids['error']) return null; $t4_id = $e5_ids['transaction_id']; pr(array('checkpoint' => 'Posted Ledger Entry e5', compact('e5_ids', 'amount'))); // post new e6... this will be our crossover point // from typical positive entries to negative entries. // Therefore, no reconciliation on this account. $e6_ids = $A->postLedgerEntry (array('transaction_id' => $t5_id), array('monetary_source_id' => $e3['monetary_source_id']), array('debit_ledger_id' => $A->currentLedgerID($nsf_account_id), 'credit_ledger_id' => $A->currentLedgerID($receipt_account_id), 'effective_date' => $stamp, 'amount' => $amount, 'lease_id' => $e3['lease_id'], 'customer_id' => $e3['customer_id'], 'comment' => "NSF tracker; Monetary Source #{$id}", ), array('debit' => array (array('LedgerEntry' => array('id' => $e5_ids['id'], 'amount' => $amount))), ) ); if ($e6_ids['error']) return null; $t5_id = $e6_ids['transaction_id']; pr(array('checkpoint' => 'Posted Ledger Entry e6', compact('e6_ids', 'amount'))); $t6_id = null; foreach ($e3['DebitReconciliationLedgerEntry'] AS $e2) { foreach ($e2['DebitReconciliationLedgerEntry2'] AS $e1) { $amount = -1*$e1['Reconciliation']['amount']; // post new e7 $e7_ids = $A->postLedgerEntry (array('transaction_id' => $t6_id), null, array('debit_ledger_id' => $A->currentLedgerID($receipt_account_id), 'credit_ledger_id' => $A->currentLedgerID($ar_account_id), 'effective_date' => $stamp, 'amount' => $amount, 'lease_id' => $e1['lease_id'], 'customer_id' => $e1['customer_id'], 'comment' => "NSF Receipt; Monetary Source #{$id}", ), array('debit' => array (array('LedgerEntry' => array('id' => $e6_ids['id'], 'amount' => $amount))), 'credit' => array (array('LedgerEntry' => array('id' => $e1['id'], 'amount' => $amount))), ) ); if ($e7_ids['error']) return null; $t6_id = $e7_ids['transaction_id']; pr(array('checkpoint' => 'Posted Ledger Entry e7', compact('e7_ids', 'amount'))); } } } // Cheat for now $customer_id = $source['LedgerEntry'][0]['customer_id']; $lease_id = null; // post new e8 $e8_ids = $A->postLedgerEntry (array('transaction_id' => $t6_id), null, array('debit_ledger_id' => $A->currentLedgerID($ar_account_id), 'credit_ledger_id' => $A->currentLedgerID($nsf_fee_account_id), 'effective_date' => $stamp, 'amount' => 35, 'lease_id' => $lease_id, 'customer_id' => $customer_id, 'comment' => "NSF Fee; Monetary Source #{$id}", ) ); if ($e8_ids['error']) return null; pr(array('checkpoint' => 'Posted Ledger Entry e8', compact('e8_ids'))); return true; } } ?>