Finally, finally... a working version for payment entry. The current schema is working well, and seems to handle our technical needs. However, it does seem to be very confusing with the extra accounts. Nonetheless, it does work and so I'll keep going down this path. This checkin also includes a mechanism to close the books on an account (by closing the underlying ledger) and start a new ledger. One of the decisions worth revisiting is separating out ledger entries that are really part of the same transaction. Without this change, inspecting a transaction results in the transaction total being off by a factor of two, since all money movement is in their twice (once for the expected reason, and again to hit the invoice/receipt ledger).

git-svn-id: file:///svn-source/pmgr/branches/invoice_receipt_20090629/site@195 97e9348a-65ac-dc4b-aefc-98561f571b83
This commit is contained in:
abijah
2009-07-01 08:17:31 +00:00
parent 3550bf775c
commit dfe20e7ef9
16 changed files with 412 additions and 202 deletions

View File

@@ -137,7 +137,16 @@ class AppModel extends Model {
*/
function dateFormatBeforeSave($dateString) {
return date('Y-m-d', strtotime($dateString));
/* $time = ''; */
/* if (preg_match('/(\d+(:\d+))/', $dateString, $match)) */
/* $time = ' '.$match[1]; */
/* $dateString = preg_replace('/(\d+(:\d+))/', '', $dateString); */
/* return date('Y-m-d', strtotime($dateString)) . $time; */
if (preg_match('/:/', $dateString))
return date('Y-m-d H:i:s', strtotime($dateString));
else
return date('Y-m-d', strtotime($dateString));
}
}

View File

@@ -119,6 +119,25 @@ class AccountsController extends AppController {
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: newledger
* - Close the current account ledger and create a new one,
* carrying forward any balance if necessary.
*/
function newledger($id = null) {
if (!$this->Account->closeCurrentLedger($id)) {
$this->Session->setFlash(__('Unable to create new Ledger.', true));
}
if ($id)
$this->redirect(array('action'=>'view', $id));
else
$this->redirect(array('action'=>'index'));
}
/**************************************************************************
**************************************************************************
**************************************************************************
@@ -160,8 +179,14 @@ class AccountsController extends AppController {
$stats = $this->Account->stats($id, true);
$stats = $stats['Ledger'];
$this->sidemenu_links[] =
array('name' => 'Operations', 'header' => true);
$this->sidemenu_links[] =
array('name' => 'New Ledger', 'url' => array('action' => 'newledger', $id));
// Prepare to render
$title = 'Account: ' . $account['Account']['name'];
$this->set(compact('account', 'title', 'stats'));
}
}

View File

@@ -103,186 +103,204 @@ class TransactionsController extends AppController {
*/
function postReceipt() {
$this->autoRender = false;
if (!$this->RequestHandler->isPost()) {
echo('<H2>THIS IS NOT A POST FOR SOME REASON</H2>');
return;
}
//pr(array('thisdata' => $this->data));
if (isset($this->data['customer_id'])) {
$C = new Customer();
$C->recursive = -1;
$customer = $C->find
('first',
array('contain' => array('Account.CurrentLedger.id'),
'fields' => false,
'conditions' => array('Customer.id', $this->data['customer_id']),
));
$ledger_id = $customer['Account']['CurrentLedger']['id'];
}
else {
// Payment by Unit, Lease, etc
$ledger_id = 0;
$this->layout = null;
$this->autoLayout = false;
$this->autoRender = false;
Configure::write('debug', '0');
// Sanitize the transaction data
if (!$this->data['Transaction']['comment'])
$this->data['Transaction']['comment'] = null;
if(empty($this->data['Transaction']['stamp'])) {
die("Time/Date not valid");
}
pr($this->data['Transaction']);
$amount = 0;
foreach ($this->data['LedgerEntry'] AS &$entry) {
$reconciled = $C->reconcileNewLedgerEntry($this->data['customer_id'],
'credit',
$entry['amount']);
pr(compact('entry', 'reconciled'));
foreach ($reconciled['debit']['entry'] AS $rec) {
$entry['DebitReconciliationLedgerEntry'] =
array('amount' => $rec['applied'],
//'debit_ledger_entry_id'
'credit_ledger_entry_id' => $rec['id']
);
}
$amount += isset($entry['amount']) ? $entry['amount'] : 0;
$entry['debit_ledger_id'] = 6; // Cash/Payments
$entry['credit_ledger_id'] = $ledger_id;
}
pr($this->data);
$T = new Transaction();
$T->create();
if ($T->saveAll($this->data,
array(
'validate' => false,
//'fieldList' => array(),
//'callbacks' => true,
))) {
$tid = $T->id;
$this->Session->setFlash(__("New Transaction Created ($tid)!", true));
//$this->redirect(array('action'=>'view', $mid));
}
else {
$this->autoRender = false;
pr(array('checkpoint' => "saveAll failed"));
}
pr($T->data);
// Create some models for convenience
$A = new Account();
$C = new Customer();
$LE = new LedgerEntry();
/* $reconciled = $C->reconcileNewLedgerEntry($this->data['customer_id'], */
/* 'credit', */
/* $amount); */
/* pr(compact('amount', 'unreconciled', 'reconciled')); */
/* return; */
// Create a transaction for the receipt
$receipt_transaction = new Transaction();
$receipt_transaction->create();
if (!$receipt_transaction->save($this->data['Transaction'],
array('validate' => false,
))) {
pr(array('checkpoint' => "receipt transaction save failed"));
die("Unknown Database Failure");
}
pr("New Transaction Created ({$receipt_transaction->id})!");
$receipt_transaction->read();
pr($receipt_transaction->data);
// Create a transaction for the splits
$split_transaction = new Transaction();
$split_transaction->create();
if (!$split_transaction->save($this->data['Transaction'],
array('validate' => false,
))) {
pr(array('checkpoint' => "split transaction save failed"));
die("Unknown Database Failure");
}
pr("New Transaction Created ({$split_transaction->id})!");
$split_transaction->read();
pr($split_transaction->data);
// Go through the entered payments
foreach ($this->data['LedgerEntry'] AS &$entry) {
// Get the Monetary Source squared away
if ($entry['monetary_type_name'] === 'Cash') {
// No distinguishing features of Cash, just
// use the shared monetary source
$entry['monetary_source_id'] =
$this->Transaction->LedgerEntry->MonetarySource->nameToID('Cash');
unset($entry['MonetarySource']);
}
else {
// The monetary source needs to be unique
// Create a new one dedicated to this entry
$entry['MonetarySource']['monetary_type_id'] =
$this->Transaction->LedgerEntry->MonetarySource->MonetaryType
->nameToID($entry['monetary_type_name']);
$entry['MonetarySource']['name'] =
$this->Transaction->LedgerEntry->MonetarySource->MonetaryType
->nameToID($entry['monetary_type_name']);
// Give it a fancy name based on the check number
$entry['MonetarySource']['name'] = $entry['monetary_type_name'];
if ($entry['monetary_type_name'] === 'Check' ||
$entry['monetary_type_name'] === 'Money Order') {
$entry['MonetarySource']['name'] .=
' #' . $entry['MonetarySource']['data1'];
}
}
// This entry of physical money is part of the receipt transaction
// debit: Cash/Check/Etc credit: Receipt
$entry['transaction_id'] = $receipt_transaction->id;
// Receipt must debit the "money" asset (bank, cash, check, etc)...
$entry['debit_ledger_id']
= $A->currentLedgerID($A->nameToID($entry['monetary_type_name']));
// ...and credit the Receipt ledger
$entry['credit_ledger_id']
= $A->currentLedgerID($A->receiptAccountID());
$entry['customer_id']
= $this->data['customer_id'];
// Create it
$receipt_entry = new LedgerEntry();
$receipt_entry->create();
if (!$receipt_entry->saveAll($entry,
array('validate' => false,
))) {
pr(array('checkpoint' => "receipt entry saveAll failed"));
die("Unknown Database Failure");
}
pr("New Receipt LedgerEntry Created ({$receipt_entry->id})!");
$receipt_entry->read();
pr($receipt_entry->data);
$reconciled = $C->reconcileNewLedgerEntry($this->data['customer_id'],
'credit',
$entry['amount']);
pr(compact('entry', 'reconciled'));
continue;
foreach ($reconciled['debit']['entry'] AS $rec) {
$data = array('LedgerEntry' =>
array('DebitReconciliationLedgerEntry' =>
array('amount' => $rec['applied'],
//'debit_ledger_entry_id'
'credit_ledger_entry_id' => $rec['id']
),
),
);
//'DebitReconciliationLedgerEntry' => array(
//pr(compact('amount', 'unreconciled', 'reconciled'));
foreach (array_merge($reconciled['debit']['entry'], array
(array('id' => null,
'applied' => $reconciled['debit']['unapplied'],
'customer_id' => $this->data['customer_id'],
'lease_id' => null))) AS $rec) {
pr(array('checkpoint' => "Handle Reconciled Entry",
compact('rec'),
));
if (!$rec['applied'])
continue;
// Create an entry to handle the splitting of the funds ("Payment")
// Payment must debit the Receipt ledger, and credit the A/R ledger
// debit: Receipt credit: A/R
$split_entry_data = array
('debit_ledger_id' => $A->currentLedgerID($A->receiptAccountID()),
'credit_ledger_id' => $A->currentLedgerID($A->accountReceivableAccountID()),
'transaction_id' => $split_transaction->id,
'amount' => $rec['applied'],
'lease_id' => $rec['lease_id'],
'customer_id' => $rec['customer_id'],
);
// Create a new split entry from the data
$split_entry = new LedgerEntry();
$split_entry->create();
if (!$split_entry->save($split_entry_data,
array('validate' => false,
))) {
pr(array('checkpoint' => "split entry save failed"));
die("Unknown Database Failure");
}
pr("New Split LedgerEntry Created ({$split_entry->id})!");
$split_entry->read();
pr($split_entry->data);
// Reconcile the Receipt account. Our two entries look like:
// debit: Cash/Check/Etc credit: Receipt
// debit: Receipt credit: A/R
// Since this is from the perspective of the Receipt account,
// the debit entry is the Receipt<->A/R, and the credit
// entry is the actual receipt ledger entry.
$R = new Reconciliation();
$R->create();
if (!$R->save(array('debit_ledger_entry_id' => $split_entry->id,
'credit_ledger_entry_id' => $receipt_entry->id,
'amount' => $rec['applied']),
array('validate' => false,
))) {
pr(array('checkpoint' => "receipt reconcile save failed"));
die("Unknown Database Failure");
}
pr("New Receipt Reconciliation Created ({$R->id})!");
$R->read();
pr($R->data);
// Only reconcile the A/R account if we have an entry
// to reconcile with, otherwise, just go on.
if (!$rec['id'])
continue;
// Reconcile the A/R account. Our two entries look like:
// debit: Receipt credit: A/R
// debit: A/R credit: Invoice
// Since this is from the perspective of the A/R account,
// the debit entry is the Invoice<->A/R, and the credit
// entry is the Receipt<->A/R.
$R = new Reconciliation();
$R->create();
if (!$R->save(array('debit_ledger_entry_id' => $rec['id'],
'credit_ledger_entry_id' => $split_entry->id,
'amount' => $rec['applied']),
array('validate' => false,
))) {
pr(array('checkpoint' => "split reconcile save failed"));
die("Unknown Database Failure");
}
pr("New Split Reconciliation Created ({$R->id})!");
$R->read();
pr($R->data);
}
}
}
function saveTest() {
$data =
array(
/* 'Customer' => array */
/* ('id' => 7, */
/* ), */
'LedgerEntry' => array
(
'0' => array(
'amount' => 100,
'debit_ledger_id' => 1,
'credit_ledger_id' => 2,
'MonetarySource' => array('name' => 'testmoney', 'monetary_type_id' => 2),
),
'1' => array(
'amount' => 101,
'debit_ledger_id' => 1,
'credit_ledger_id' => 2,
'MonetarySource' => array('name' => 'testmoney2', 'monetary_type_id' => 2),
),
),
'Transaction' => array
(
'stamp' => '06/18/2009',
'comment' => 'no comment',
),
);
$data =
/* array( */
/* 'LedgerEntry' => array */
/* ( */
/* '0' => */
array(
'amount' => 100,
'debit_ledger_id' => 1,
'credit_ledger_id' => 2,
'transaction_id' => 66,
'DebitReconciliationLedgerEntry' =>
array('amount' => 44,
//'debit_ledger_entry_id'
'credit_ledger_entry_id' => 17,
),
/* ), */
/* ), */
);
//$M = new Transaction();
$M = new LedgerEntry();
$M->create();
$retval = $M->saveAll($data,
array(
'validate' => false,
'fieldList' => array(),
'callbacks' => true,
));
$mid = $M->id;
pr(compact('retval', 'mid'));
if ($mid) {
$this->Session->setFlash(__("New Transaction Created ($mid)!", true));
//$this->redirect(array('action'=>'view', $mid));
}
else {
$this->autoRender = false;
pr(array('checkpoint' => "saveAll failed"));
}
/* $LE = new LedgerEntry(); */
/* $LE->create(); */
/* $ret = $LE->save($data, */
/* array( */
/* 'validate' => false, */
/* 'fieldList' => array(), */
/* 'callbacks' => true, */
/* )); */
/* $leid = $LE->id; */
/* pr(array('checkpoint' => "New Ledger Entry", */
/* compact('leid', 'ret'))); */
//pr($LE);
}
}

View File

@@ -92,6 +92,23 @@ class Account extends AppModel {
function invoiceAccountID() { return $this->nameToID('Invoice'); }
function receiptAccountID() { return $this->nameToID('Receipt'); }
/**************************************************************************
**************************************************************************
**************************************************************************
* function: currentLedgerID
* - Returns the current ledger ID of the account
*/
function currentLedgerID($id) {
$this->cacheQueries = true;
$item = $this->find('first', array
('contain' => 'CurrentLedger',
'conditions' => array('Account.id' => $id),
));
$this->cacheQueries = false;
return $item['CurrentLedger']['id'];
}
/**************************************************************************
**************************************************************************
@@ -131,6 +148,34 @@ class Account extends AppModel {
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: closeCurrentLedger
* - Closes the current account ledger, and opens a new one
* with the old balance carried forward.
*/
function closeCurrentLedger($id = null) {
$contain = array('CurrentLedger' => array('fields' => array('CurrentLedger.id')));
$this->cacheQueries = true;
$account = $this->find('all', array
('contain' => $contain,
'fields' => array(),
'conditions' =>
$id ? array(array('Account.id' => $id)) : array()
));
$this->cacheQueries = false;
//pr(compact('id', 'account'));
foreach ($account AS $acct) {
if (!$this->Ledger->closeLedger($acct['CurrentLedger']['id']))
return false;
}
return true;
}
/**************************************************************************
**************************************************************************
**************************************************************************
@@ -222,7 +267,7 @@ class Account extends AppModel {
('fields' => array(),
"LedgerEntry" => array
('class' => "{$ucfund}LedgerEntry",
'fields' => array('id', 'amount'),
'fields' => array('id', 'customer_id', 'lease_id', 'amount'),
"ReconciliationLedgerEntry" => array
('class' => "{$ucfund}ReconciliationLedgerEntry",
'fields' => array

View File

@@ -44,6 +44,72 @@ class Ledger extends AppModel {
);
/**************************************************************************
**************************************************************************
**************************************************************************
* function: closeLedger
* - Closes the current ledger, and returns a fresh one
*/
function closeLedger($id) {
$this->recursive = -1;
$stamp = date('Y-m-d G:i:s');
$this->id = $id;
$this->read();
$this->data['Ledger']['close_stamp'] = $stamp;
$this->data['Ledger']['closed'] = 1;
$this->save($this->data, false);
$stats = $this->stats($id);
$this->read();
$this->data['Ledger']['id'] = null;
$this->data['Ledger']['closed'] = 0;
$this->data['Ledger']['open_stamp'] = $stamp;
$this->data['Ledger']['close_stamp'] = null;
$this->data['Ledger']['comment'] = null;
++$this->data['Ledger']['sequence'];
$this->id = null;
$this->save($this->data, false);
//pr($this->data);
if ($stats['balance'] == 0)
return $this->id;
$this->read();
$ftype = $this->Account->fundamentalType($this->data['Ledger']['account_id']);
$otype = $this->Account->fundamentalOpposite($ftype);
// Create a transaction for balance transfer
$transaction = new Transaction();
$transaction->create();
if (!$transaction->save(array(),
array('validate' => false,
))) {
return null;
}
// Create an entry to carry the balance forward
$carry_entry_data = array
($ftype.'_ledger_id' => $this->id,
$otype.'_ledger_id' => $id,
'transaction_id' => $transaction->id,
'amount' => $stats['balance'],
'comment' => "Ledger Balance Forward",
);
$carry_entry = new LedgerEntry();
$carry_entry->create();
if (!$carry_entry->save($carry_entry_data,
array('validate' => false,
))) {
return null;
}
return $this->id;
}
/**************************************************************************
**************************************************************************
**************************************************************************

View File

@@ -8,6 +8,16 @@ class LedgerEntry extends AppModel {
'amount' => array('money')
);
var $hasMany = array(
'DebitReconciliation' => array(
'className' => 'Reconciliation',
'foreignKey' => 'debit_ledger_entry_id',
),
'CreditReconciliation' => array(
'className' => 'Reconciliation',
'foreignKey' => 'credit_ledger_entry_id',
),
);
var $belongsTo = array(
'MonetarySource',
'Transaction',

15
models/reconciliation.php Normal file
View File

@@ -0,0 +1,15 @@
<?php
class Reconciliation extends AppModel {
var $belongsTo = array(
'DebitLedgerEntry' => array(
'className' => 'LedgerEntry',
//'foreignKey' => 'credit_ledger_entry_id',
),
'CreditLedgerEntry' => array(
'className' => 'LedgerEntry',
//'foreignKey' => 'credit_ledger_entry_id',
),
);
}

View File

@@ -7,7 +7,6 @@ class Transaction extends AppModel {
/* ); */
var $belongsTo = array(
'Customer',
);
var $hasMany = array(
@@ -17,10 +16,15 @@ class Transaction extends AppModel {
function beforeSave() {
if(!empty($this->data['Transaction']['stamp'])) {
if(isset($this->data['Transaction']['stamp']) &&
$this->data['Transaction']['stamp'] !== 'CURRENT_TIMESTAMP') {
$this->data['Transaction']['stamp'] =
$this->dateFormatBeforeSave($this->data['Transaction']['stamp']);
}
else {
$this->data['Transaction']['stamp'] = null;
}
return true;
}

View File

@@ -65,7 +65,7 @@ echo $this->element('ledgers',
*/
echo $this->element('ledger_entries',
array('caption' => "Current Ledger: (#{$account['CurrentLedger']['sequence']})",
array('caption' => "Current Ledger: (#{$account['Account']['id']}-{$account['CurrentLedger']['sequence']})",
'ledger_id' => $account['CurrentLedger']['id'],
'account_type' => $account['Account']['type'],
));

View File

@@ -148,6 +148,17 @@ $grid_setup['onSelectRow'] = array
$('#payments').html('');
$('#payment-id').val(0);
addPaymentSource(false);
datepickerNow();
}
function datepickerNow() {
now = new Date();
$("#datepicker").val($.datepicker.formatDate('mm/dd/yy', now)
+ ' '
+ (now.getHours() < 10 ? '0' : '')
+ now.getHours() + ':'
+ (now.getMinutes() < 10 ? '0' : '')
+ now.getMinutes());
}
function addPaymentSource(flash) {
@@ -158,16 +169,6 @@ $grid_setup['onSelectRow'] = array
'<DIV ID="payment-type-div-%{id}">' +
<?php
/* REVISIT <AP> 20090616:
* MUST GET THIS FROM THE DATABASE!!
* HARDCODED VALUES BAD... VERY BAD...
*/
$monetary_type_ids = array('Cash' => 2,
'Check' => 3,
'Money Order' => 4,
'ACH' => 5,
'Credit Card' => 7,
);
$types = array();
foreach(array('Cash', 'Check', 'Money Order', /*'ACH', 'Credit Card'*/) AS $name)
@@ -175,11 +176,10 @@ $grid_setup['onSelectRow'] = array
foreach ($types AS $type => $name) {
$div = '<DIV>';
$div .= '<INPUT TYPE="hidden" NAME="data[LedgerEntry][%{id}][bogus]" VALUE="1">';
$div .= '<INPUT TYPE="radio" NAME="data[LedgerEntry][%{id}][MonetarySource][monetary_type_id]"';
$div .= '<INPUT TYPE="radio" NAME="data[LedgerEntry][%{id}][monetary_type_name]"';
$div .= ' ONCLICK="switchPaymentType(%{id}, \\\''.$type.'\\\')"';
$div .= ' CLASS="payment-type-%{id}" ID="payment-type-'.$type.'-%{id}"';
$div .= ' VALUE="'.$monetary_type_ids[$name].'" ' . ($name == 'Cash' ? 'CHECKED ' : '') . '/>';
$div .= ' VALUE="'.$name.'" ' . ($name == 'Cash' ? 'CHECKED ' : '') . '/>';
$div .= ' <LABEL FOR="payment-type-'.$type.'-%{id}">'.$name.'</LABEL>';
$div .= '</DIV>';
echo "'$div' +\n";
@@ -228,7 +228,7 @@ function switchPaymentType(paymentid, type) {
'<DIV CLASS="input text required">' +
' <LABEL FOR="payment-check-number-'+paymentid+'">Check Number</LABEL>' +
// REVISIT <AP>: 20090617: Use comment field for now.
' <INPUT TYPE="text" SIZE="6" NAME="data[LedgerEntry]['+paymentid+'][MonetarySource][comment]"' +
' <INPUT TYPE="text" SIZE="6" NAME="data[LedgerEntry]['+paymentid+'][MonetarySource][data1]"' +
' ID="payment-check-number-'+paymentid+'" />' +
'</DIV>';
break;
@@ -238,7 +238,7 @@ function switchPaymentType(paymentid, type) {
'<DIV CLASS="input text required">' +
' <LABEL FOR="payment-moneyorder-number-'+paymentid+'">Money Order Number</LABEL>' +
// REVISIT <AP>: 20090617: Use comment field for now.
' <INPUT TYPE="text" SIZE="6" NAME="data[LedgerEntry]['+paymentid+'][MonetarySource][comment]"' +
' <INPUT TYPE="text" SIZE="6" NAME="data[LedgerEntry]['+paymentid+'][MonetarySource][data1]"' +
' ID="payment-moneyorder-number-'+paymentid+'" />' +
'</DIV>';
break;
@@ -248,14 +248,14 @@ function switchPaymentType(paymentid, type) {
'<DIV CLASS="input text required">' +
' <LABEL FOR="payment-ach-routing-'+paymentid+'">Routing Number</LABEL>' +
// REVISIT <AP>: 20090617: Use comment field for now.
' <INPUT TYPE="text" SIZE="9" NAME="data[LedgerEntry]['+paymentid+'][MonetarySource][comment]"' +
' <INPUT TYPE="text" SIZE="9" NAME="data[LedgerEntry]['+paymentid+'][MonetarySource][data1]"' +
' ID="payment-ach-routing-'+paymentid+'" />' +
'</DIV>' +
'<DIV CLASS="input text required">' +
' <LABEL FOR="payment-ach-account-'+paymentid+'">Account Number</LABEL>' +
// REVISIT <AP>: 20090617: Use comment field for now.
' <INPUT TYPE="text" SIZE="17" NAME="data[LedgerEntry]['+paymentid+'][MonetarySource][comment]"' +
' <INPUT TYPE="text" SIZE="17" NAME="data[LedgerEntry]['+paymentid+'][MonetarySource][data2]"' +
' ID="payment-ach-account-'+paymentid+'" />' +
'</DIV>';
break;
@@ -265,21 +265,21 @@ function switchPaymentType(paymentid, type) {
'<DIV CLASS="input text required">' +
' <LABEL FOR="payment-creditcard-account-'+paymentid+'">Account Number</LABEL>' +
// REVISIT <AP>: 20090617: Use comment field for now.
' <INPUT TYPE="text" SIZE="16" NAME="data[LedgerEntry]['+paymentid+'][MonetarySource][comment]' +
' <INPUT TYPE="text" SIZE="16" NAME="data[LedgerEntry]['+paymentid+'][MonetarySource][data1]' +
' ID="payment-creditcard-account-'+paymentid+'" />' +
'</DIV>' +
'<DIV CLASS="input text required">' +
' <LABEL FOR="payment-creditcard-expiration-'+paymentid+'">Expiration Date</LABEL>' +
// REVISIT <AP>: 20090617: Use comment field for now.
' <INPUT TYPE="text" SIZE="10" NAME="data[LedgerEntry]['+paymentid+'][MonetarySource][comment]' +
' <INPUT TYPE="text" SIZE="10" NAME="data[LedgerEntry]['+paymentid+'][MonetarySource][data2]' +
' ID="payment-creditcard-expiration-'+paymentid+'" />' +
' </DIV>' +
'<DIV CLASS="input text required">' +
' <LABEL FOR="payment-creditcard-cvv2-'+paymentid+'">CVV2 Code</LABEL>' +
// REVISIT <AP>: 20090617: Use comment field for now.
' <INPUT TYPE="text" SIZE="10" NAME=data[LedgerEntry]['+paymentid+'][MonetarySource][comment]' +
' <INPUT TYPE="text" SIZE="10" NAME=data[LedgerEntry]['+paymentid+'][MonetarySource][data3]' +
' ID="payment-creditcard-cvv2-'+paymentid+'" />' +
'</DIV>';
break;
@@ -436,7 +436,8 @@ echo $form->create(null, array('id' => 'payment-form',
<?php
echo 'Date: <input id="datepicker" name="data[Transaction][stamp]" type="text" /><BR>' . "\n";
echo 'Date: <input id="datepicker" name="data[Transaction][stamp]" type="text" />';
echo ' <A HREF="#" ONCLICK="datepickerNow(); return false;">Now</A><BR>' . "\n";
echo 'Comment: <input id="comment" name="data[Transaction][comment]" type="text" SIZE=80 /><BR>' . "\n";
echo $form->end('Post Payment');
@@ -457,8 +458,12 @@ echo $form->end('Post Payment');
<script type="text/javascript">
$(document).ready(function(){
$("#datepicker").datepicker()
.datepicker('setDate', '+0');
$("#datepicker").datepicker({ constrainInput: true,
numberOfMonths: [1, 1],
showCurrentAtPos: 0,
dateFormat: 'mm/dd/yy' })
//.datepicker('setDate', '+0');
;
<?php if (isset($customer['id'])) { ?>
$("#customer-id").val(<?php echo $customer['id']; ?>);

View File

@@ -3,8 +3,8 @@
// Define the table columns
$cols = array();
$cols['ID'] = array('index' => 'Account.id', 'formatter' => 'id');
$cols['Name'] = array('index' => 'Account.name', 'formatter' => 'name', 'width' => '250');
$cols['Type'] = array('index' => 'Account.type', 'width' => '60');
$cols['Name'] = array('index' => 'Account.name', 'formatter' => 'longname');
$cols['Type'] = array('index' => 'Account.type', 'formatter' => 'name');
$cols['Entries'] = array('index' => 'entries', 'width' => '60', 'align' => 'right');
$cols['Debits'] = array('index' => 'debits', 'formatter' => 'currency');
$cols['Credits'] = array('index' => 'credits', 'formatter' => 'currency');

View File

@@ -114,12 +114,12 @@ foreach ($jqGridColumns AS &$col) {
elseif ($col['formatter'] === 'currency') {
// Switch currency over to our own custom formatting
$col['formatter'] = array('--special' => 'currencyFormatter');
$default['width'] = 80;
$default['width'] = 85;
$default['align'] = 'right';
}
elseif ($col['formatter'] === 'date') {
$default['formatoptions'] = array('newformat' => 'm/d/Y');
$default['width'] = 90;
$default['width'] = 95;
$default['align'] = 'center';
}
elseif ($col['formatter'] === 'name' || $col['formatter'] === 'longname') {

View File

@@ -12,6 +12,12 @@ if (isset($ledger_id) || isset($account_id) || isset($ar_account)) {
$single_amount = true;
}
if (isset($lease_id) || isset($customer_id)) {
$references = false;
} else {
$references = true;
}
if (isset($reconcile_id)) {
$applied_amount = true;
} else {
@@ -47,9 +53,13 @@ else {
$cols['Debit Account'] = array('index' => 'DebitAccount.name', 'formatter' => 'name');
$cols['Credit Account'] = array('index' => 'CreditAccount.name', 'formatter' => 'name');
}
$cols['Customer'] = array('index' => 'Customer.name', 'formatter' => 'longname');
$cols['Lease'] = array('index' => 'Lease.number', 'formatter' => 'id');
$cols['Unit'] = array('index' => 'Unit.name', 'formatter' => 'name');
if ($references) {
$cols['Customer'] = array('index' => 'Customer.name', 'formatter' => 'longname');
//$cols['Lease'] = array('index' => 'Lease.number', 'formatter' => 'id');
$cols['Unit'] = array('index' => 'Unit.name', 'formatter' => 'name');
}
$cols['Source'] = array('index' => 'MonetarySource.name', 'formatter' => 'name');
$cols['Comment'] = array('index' => 'LedgerEntry.comment', 'formatter' => 'comment', 'width'=>150);

View File

@@ -3,13 +3,14 @@
// Define the table columns
$cols = array();
$cols['ID'] = array('index' => 'id_sequence', 'formatter' => 'id');
$cols['Account'] = array('index' => 'Account.name', 'formatter' => 'name', 'width' => '250');
$cols['Account'] = array('index' => 'Account.name', 'formatter' => 'longname');
$cols['Open Date'] = array('index' => 'Ledger.open_stamp', 'formatter' => 'date');
$cols['Close Date'] = array('index' => 'Ledger.close_stamp', 'formatter' => 'date');
$cols['Comment'] = array('index' => 'Ledger.comment', 'formatter' => 'comment');
$cols['Entries'] = array('index' => 'entries', 'width' => '60', 'align' => 'right');
$cols['Debits'] = array('index' => 'debits', 'formatter' => 'currency');
$cols['Credits'] = array('index' => 'credits', 'formatter' => 'currency');
$cols['Balance'] = array('index' => 'balance', 'formatter' => 'currency');
$cols['Close Date'] = array('index' => 'Ledger.close_stamp', 'formatter' => 'date');
$cols['Comment'] = array('index' => 'Ledger.comment', 'formatter' => 'comment');
$jqGrid_options = array('jqGridColumns' => $cols,
'controller' => 'ledgers',

View File

@@ -121,7 +121,6 @@ if ($debit_ledger['Account']['trackable']) {
'grid_div_id' => 'debit_reconciliation_ledger_entries',
'account_ftype' => 'debit',
'reconcile_id' => $entry['id'],
//'ledger_entries' => $reconciled['debit']['entry'],
));
}
@@ -131,7 +130,6 @@ if ($credit_ledger['Account']['trackable']) {
'grid_div_id' => 'credit_reconciliation_ledger_entries',
'account_ftype' => 'credit',
'reconcile_id' => $entry['id'],
//'ledger_entries' => $reconciled['credit']['entry'],
));
}

View File

@@ -15,6 +15,10 @@ $source = $monetarySource['MonetarySource'];
$rows = array(array('ID', $source['id']),
array('Name', $source['name']),
array('Type', $type['name']),
array('Data 1', $source['data1']),
array('Data 2', $source['data2']),
array('Data 3', $source['data3']),
array('Data 4', $source['data4']),
array('Tillable', $type['tillable'] ? 'Yes' : 'No'),
array('Comment', $source['comment']));