Compare commits

..

5 Commits

Author SHA1 Message Date
abijah
c9ade62536 Very, very messy and broken. It does work somewhat, but I can see just what a mess it's going to be to carry it out, so I'm abandoning.
git-svn-id: file:///svn-source/pmgr/branches/reconcile_entry_to_receipt_20090629@187 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-06-30 00:59:09 +00:00
abijah
4f0b5ffc28 Branch to work on another possible solution to this mess
git-svn-id: file:///svn-source/pmgr/branches/reconcile_entry_to_receipt_20090629@186 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-06-30 00:57:11 +00:00
abijah
ce4fa4131a More changes. I just can't seem to come up with a solution that works that I like. The problem now, without invoice/receipt, is that one check cannot cleanly pay for two units.
git-svn-id: file:///svn-source/pmgr/branches/single_AR_20090622@182 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-06-24 00:33:39 +00:00
abijah
80f8bd36d5 Nowhere near done yet, but checking in a snapshot of semi-working code. There is some simultaneous support for both with and without use of the Invoice/Receipt account. I want to do away with them completely, but will need to change how sitelink payments are mapped (right now, they split a payment into multiple parts to match the charge).
git-svn-id: file:///svn-source/pmgr/branches/single_AR_20090622@181 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-06-23 19:04:41 +00:00
abijah
7aa1100cac Moving to the standard accounting method of a single Account Receiveable.
git-svn-id: file:///svn-source/pmgr/branches/single_AR_20090622@180 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-06-22 23:46:03 +00:00
23 changed files with 1034 additions and 623 deletions

View File

@@ -866,15 +866,18 @@ LOCK TABLES `pmgr_accounts` WRITE;
INSERT INTO `pmgr_accounts` (`type`, `name`, `trackable`) INSERT INTO `pmgr_accounts` (`type`, `name`, `trackable`)
VALUES VALUES
('ASSET', 'A/R', 1), ('ASSET', 'A/R', 1),
('ASSET', 'Invoice', 1),
('ASSET', 'Receipt', 1),
('LIABILITY', 'A/P', 1), ('LIABILITY', 'A/P', 1),
('LIABILITY', 'Tax', 0), ('LIABILITY', 'Tax', 0),
('LIABILITY', 'Customer Credit', 1), ('LIABILITY', 'Customer Credit', 1),
('ASSET', 'Bank', 0), ('ASSET', 'Bank', 0),
('ASSET', 'Payment', 0), ('ASSET', 'Till', 0),
('LIABILITY', 'Security Deposit', 1), ('LIABILITY', 'Security Deposit', 1),
('INCOME', 'Rent', 0), ('INCOME', 'Rent', 0),
('INCOME', 'Late Charge', 0), ('INCOME', 'Late Charge', 0),
('EXPENSE', 'Concession', 0); ('EXPENSE', 'Concession', 0),
('EXPENSE', 'Bad Debt', 0);
UNLOCK TABLES; UNLOCK TABLES;
@@ -965,6 +968,8 @@ CREATE TABLE `pmgr_ledger_entries` (
`name` VARCHAR(80) DEFAULT NULL, `name` VARCHAR(80) DEFAULT NULL,
`monetary_source_id` INT(10) UNSIGNED DEFAULT NULL, -- NULL if internal transfer `monetary_source_id` INT(10) UNSIGNED DEFAULT NULL, -- NULL if internal transfer
`transaction_id` INT(10) UNSIGNED NOT NULL, `transaction_id` INT(10) UNSIGNED NOT NULL,
`customer_id` INT(10) UNSIGNED DEFAULT NULL,
`lease_id` INT(10) UNSIGNED DEFAULT NULL,
`amount` FLOAT(12,2) NOT NULL, `amount` FLOAT(12,2) NOT NULL,
`debit_ledger_id` INT(10) UNSIGNED NOT NULL, `debit_ledger_id` INT(10) UNSIGNED NOT NULL,
@@ -984,9 +989,15 @@ DROP TABLE IF EXISTS `pmgr_reconciliations`;
CREATE TABLE `pmgr_reconciliations` ( CREATE TABLE `pmgr_reconciliations` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`debit_ledger_entry_id` INT(10) UNSIGNED NOT NULL, `type` ENUM('DEBIT',
`credit_ledger_entry_id` INT(10) UNSIGNED NOT NULL, 'CREDIT')
`terminal_ledger_entry_id` INT(10) UNSIGNED DEFAULT NULL, NOT NULL,
-- Match up the ledger entry to the transaction that
-- reconciles it. For example, this could be a charge
-- matching up with a receipt.
`ledger_entry_id` INT(10) UNSIGNED NOT NULL,
`transaction_id` INT(10) UNSIGNED NOT NULL,
`amount` FLOAT(12,2) NOT NULL, `amount` FLOAT(12,2) NOT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)

View File

@@ -92,6 +92,32 @@ sub addRow {
} }
######################################################################
######################################################################
## updateRow
sub updateRow {
my ($table, $id, $cols) = @_;
die unless $table;
die unless $id;
die unless ref($cols) eq 'HASH';
die "Table `$table` is unknown!"
unless defined $newdb{'tables'}{$table};
die "Table `$table` : ID `$id` does not exist!"
unless $newdb{'tables'}{$table}{'rows'}[$id];
# For debug purposes
my $line = (caller())[2];
$cols->{'--UPDATE-LINE--'} = [] unless $cols->{'--UPDATE-LINE--'};
push(@{$cols->{'--UPDATE-LINE--'}}, "updateRow called from line: $line");
#$newdb{'tables'}{$table}{'rows'}[$id] = $cols;
return $id;
}
###################################################################### ######################################################################
###################################################################### ######################################################################
## query ## query
@@ -145,7 +171,13 @@ sub executeSchema {
sub buildTables { sub buildTables {
foreach my $table (values %{$newdb{'tables'}}) { foreach my $table (values %{$newdb{'tables'}}) {
printf(STDERR "%-30s : %d rows\n", $table->{'name'}, int(@{$table->{'rows'}})); my $count = 0;
foreach (@{$table->{'rows'}}) {
next unless defined $_;
++$count;
}
printf(STDERR "%-30s : %d rows\n", $table->{'name'}, $count);
foreach (@{$table->{'rows'}}) { foreach (@{$table->{'rows'}}) {
next unless defined $_; next unless defined $_;
@@ -437,9 +469,9 @@ foreach $row (@$result) {
'comment' => undef }); 'comment' => undef });
$newdb{'lookup'}{'account'}{$row->{'name'}} $newdb{'lookup'}{'account'}{$row->{'name'}}
= {'account' => $row->{'id'}, = {'account_id' => $row->{'id'},
'tillable' => $row->{'tillable'}, 'tillable' => $row->{'tillable'},
'ledger' => $newdb{'tables'}{'ledgers'}{'autoid'} }; 'ledger_id' => $newdb{'tables'}{'ledgers'}{'autoid'} };
if ((!defined $newdb{'tables'}{'accounts'}{'autoid'}) || if ((!defined $newdb{'tables'}{'accounts'}{'autoid'}) ||
$row->{'id'} > $newdb{'tables'}{'accounts'}{'autoid'}) { $row->{'id'} > $newdb{'tables'}{'accounts'}{'autoid'}) {
@@ -449,7 +481,7 @@ foreach $row (@$result) {
# For compatibility, while deciding on account names # For compatibility, while deciding on account names
$newdb{'lookup'}{'account'}{'Cash'} $newdb{'lookup'}{'account'}{'Cash'}
= $newdb{'lookup'}{'account'}{'Payment'}; = $newdb{'lookup'}{'account'}{'Till'};
$newdb{'lookup'}{'charge_type'} = {}; $newdb{'lookup'}{'charge_type'} = {};
$newdb{'lookup'}{'charge_type'}{'Rent'} = $newdb{'lookup'}{'charge_type'}{'Rent'} =
@@ -474,15 +506,15 @@ foreach $row (@$result) {
$newdb{'lookup'}{'payment_type'} = {}; $newdb{'lookup'}{'payment_type'} = {};
$newdb{'lookup'}{'payment_type'}{1} $newdb{'lookup'}{'payment_type'}{1}
= { 'name' => 'Cash', 'account' => 'Cash', 'monetary_type' => $newdb{'lookup'}{'monetary_type'}{'Cash'} }; = { 'name' => 'Cash', 'account_name' => 'Cash', 'monetary_type' => $newdb{'lookup'}{'monetary_type'}{'Cash'} };
$newdb{'lookup'}{'payment_type'}{2} $newdb{'lookup'}{'payment_type'}{2}
= { 'name' => 'Check', 'account' => 'Cash', 'monetary_type' => $newdb{'lookup'}{'monetary_type'}{'Check'} }; = { 'name' => 'Check', 'account_name' => 'Cash', 'monetary_type' => $newdb{'lookup'}{'monetary_type'}{'Check'} };
$newdb{'lookup'}{'payment_type'}{3} $newdb{'lookup'}{'payment_type'}{3}
= { 'name' => 'Money Order', 'account' => 'Cash', 'monetary_type' => $newdb{'lookup'}{'monetary_type'}{'Money Order'} }; = { 'name' => 'Money Order', 'account_name' => 'Cash', 'monetary_type' => $newdb{'lookup'}{'monetary_type'}{'Money Order'} };
$newdb{'lookup'}{'payment_type'}{4} $newdb{'lookup'}{'payment_type'}{4}
= { 'name' => 'ACH', 'account' => 'Bank', 'monetary_type' => $newdb{'lookup'}{'monetary_type'}{'ACH'} }; = { 'name' => 'ACH', 'account_name' => 'Bank', 'monetary_type' => $newdb{'lookup'}{'monetary_type'}{'ACH'} };
$newdb{'lookup'}{'payment_type'}{12} $newdb{'lookup'}{'payment_type'}{12}
= { 'name' => 'Concession', 'account' => 'Concession', 'monetary_type' => $newdb{'lookup'}{'monetary_type'}{'Other Non-Tillable'} }; = { 'name' => 'Concession', 'account_name' => 'Concession', 'monetary_type' => $newdb{'lookup'}{'monetary_type'}{'Other Non-Tillable'} };
$newdb{'ids'}{'monetary_source'} = {}; $newdb{'ids'}{'monetary_source'} = {};
@@ -490,14 +522,14 @@ $newdb{'ids'}{'monetary_source'}{'internal'} = undef;
addRow('monetary_sources', addRow('monetary_sources',
{ 'monetary_type_id' => $newdb{'lookup'}{'monetary_type'}{'Cash'}{'id'}, { 'monetary_type_id' => $newdb{'lookup'}{'monetary_type'}{'Cash'}{'id'},
'name' => 'Cash Source', 'name' => 'Cash',
'comment' => 'Monetary source used for any cash transaction' }); 'comment' => 'Monetary source used for any cash transaction' });
$newdb{'ids'}{'monetary_source'}{'Cash'} = $newdb{'ids'}{'monetary_source'}{'Cash'} =
$newdb{'tables'}{'monetary_sources'}{'autoid'}; $newdb{'tables'}{'monetary_sources'}{'autoid'};
addRow('monetary_sources', addRow('monetary_sources',
{ 'monetary_type_id' => $newdb{'lookup'}{'monetary_type'}{'Other Non-Tillable'}{'id'}, { 'monetary_type_id' => $newdb{'lookup'}{'monetary_type'}{'Other Non-Tillable'}{'id'},
'name' => 'Closing Monies Credited', 'name' => 'Closing',
'comment' => 'Credited at the closing table' }); 'comment' => 'Credited at the closing table' });
$newdb{'ids'}{'monetary_source'}{'Closing'} = $newdb{'ids'}{'monetary_source'}{'Closing'} =
$newdb{'tables'}{'monetary_sources'}{'autoid'}; $newdb{'tables'}{'monetary_sources'}{'autoid'};
@@ -660,35 +692,21 @@ foreach $row (@{query($sdbh, $query)}) {
$newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'id'} = $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'id'} =
$newdb{'tables'}{'contacts'}{'autoid'}; $newdb{'tables'}{'contacts'}{'autoid'};
$newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'account_id'} =
# Every customer gets their own account $newdb{'lookup'}{'account'}{'A/R'}{'account_id'};
addRow('accounts', $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'ledger_id'} =
{ 'type' => 'ASSET', $newdb{'lookup'}{'account'}{'A/R'}{'ledger_id'};
'trackable' => 1,
'name' => ('Customer #' . ($newdb{'tables'}{'customers'}{'autoid'}+1) .
' ('.$newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'name'} . ')'),
'comment' => undef });
#'comment' => 'For direct customer transaction, NOT lease charges!' });
addRow('ledgers',
{ 'account_id' => $newdb{'tables'}{'accounts'}{'autoid'},
'open_stamp' => '2009-01-01',
'comment' => undef });
$newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'account'} =
$newdb{'tables'}{'accounts'}{'autoid'};
$newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'ledger'} =
$newdb{'tables'}{'ledgers'}{'autoid'};
addRow('customers', addRow('customers',
{ 'name' => "$row->{'LastName'}, $row->{'FirstName'}", { 'name' => "$row->{'LastName'}, $row->{'FirstName'}",
'primary_contact_id' => $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'id'}, 'primary_contact_id' => $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'id'},
'account_id' => $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'account'} }); 'account_id' => $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'account_id'} });
$newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'cust'} = $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'customer_id'} =
$newdb{'tables'}{'customers'}{'autoid'}; $newdb{'tables'}{'customers'}{'autoid'};
addRow('contacts_customers', addRow('contacts_customers',
{ 'customer_id' => $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'cust'}, { 'customer_id' => $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'customer_id'},
'contact_id' => $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'id'}, 'contact_id' => $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'id'},
'type' => 'TENANT' }, 'type' => 'TENANT' },
1); 1);
@@ -754,7 +772,7 @@ foreach $row (@{query($sdbh, $query)}) {
$newdb{'tables'}{'contacts'}{'autoid'}; $newdb{'tables'}{'contacts'}{'autoid'};
addRow('contacts_customers', addRow('contacts_customers',
{ 'customer_id' => $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'cust'}, { 'customer_id' => $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'customer_id'},
'contact_id' => $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'alt'}, 'contact_id' => $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'alt'},
'type' => 'ALTERNATE' }, 'type' => 'ALTERNATE' },
1); 1);
@@ -800,52 +818,26 @@ $query = "SELECT L.*, A.TenantID FROM TenantLedger L LEFT JOIN `Access` A ON A.L
foreach $row (@{query($sdbh, $query)}) { foreach $row (@{query($sdbh, $query)}) {
$newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}} $newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}
= { 'cust' => $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'cust'} }; = { 'customer_id' => $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'customer_id'} };
if (1) { $newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'account_id'}
# Every lease gets its own account = $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'account_id'};
addRow('accounts', $newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'ledger_id'}
{ 'type' => 'ASSET', = $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'ledger_id'};
'trackable' => 1,
'name' => ('Lease #' . $row->{'LedgerID'}
. ' ('.$newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'name'} . ')'),
'comment' => undef });
#'comment' => 'For lease related transaction, NOT personal charges!' });
addRow('ledgers',
{ 'account_id' => $newdb{'tables'}{'accounts'}{'autoid'},
'open_stamp' => datefmt($row->{'DateIn'}),
'comment' => undef });
$newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'account'}
= $newdb{'tables'}{'accounts'}{'autoid'};
$newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'ledger'}
= $newdb{'tables'}{'ledgers'}{'autoid'};
}
else {
$newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'account'}
= $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'account'};
$newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'ledger'}
= $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'ledger'};
}
$newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'cust_account'}
= $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'account'};
$newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'cust_ledger'}
= $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'ledger'};
addRow('leases', addRow('leases',
{ 'number' => $row->{'LedgerID'}, { 'number' => $row->{'LedgerID'},
'lease_type_id' => $newdb{'tables'}{'lease_types'}{'autoid'}, 'lease_type_id' => $newdb{'tables'}{'lease_types'}{'autoid'},
'unit_id' => $newdb{'lookup'}{'unit'}{$row->{'UnitID'}}{'id'}, 'unit_id' => $newdb{'lookup'}{'unit'}{$row->{'UnitID'}}{'id'},
'customer_id' => $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'cust'}, 'customer_id' => $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'customer_id'},
'account_id' => $newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'account'}, 'account_id' => $newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'account_id'},
'lease_date' => datefmt($row->{'DateIn'}), 'lease_date' => datefmt($row->{'DateIn'}),
'movein_date' => datefmt($row->{'DateIn'}), 'movein_date' => datefmt($row->{'DateIn'}),
'moveout_date' => datefmt($row->{'DateOut'}), 'moveout_date' => datefmt($row->{'DateOut'}),
'close_date' => datefmt($row->{'DateClosed'}), 'close_date' => datefmt($row->{'DateClosed'}),
'amount' => $row->{'Rent'} }); 'amount' => $row->{'Rent'} });
$newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'lease'} = $newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'lease_id'} =
$newdb{'tables'}{'leases'}{'autoid'}; $newdb{'tables'}{'leases'}{'autoid'};
} }
@@ -868,6 +860,8 @@ $newdb{'lookup'}{'charge'} = {};
$query = "SELECT * FROM Charges ORDER BY ChargeID"; $query = "SELECT * FROM Charges ORDER BY ChargeID";
foreach $row (@{query($sdbh, $query)}) { foreach $row (@{query($sdbh, $query)}) {
my $credit_ledger_id;
my $ledger_entry_id;
addRow('transactions', addRow('transactions',
{ 'stamp' => datefmt($row->{'ChargeDate'}), { 'stamp' => datefmt($row->{'ChargeDate'}),
@@ -875,56 +869,45 @@ foreach $row (@{query($sdbh, $query)}) {
$newdb{'lookup'}{'charge'}{$row->{'ChargeID'}} $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}
= { 'tx' => $newdb{'tables'}{'transactions'}{'autoid'}, = { 'tx' => $newdb{'tables'}{'transactions'}{'autoid'},
'ledger' => $newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'ledger'}, 'ledger_id' => $newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'ledger_id'},
#'ledger_id' => $newdb{'lookup'}{'account'}{'Invoice'}{'ledger_id'},
'amount' => $row->{'ChargeAmount'}, 'amount' => $row->{'ChargeAmount'},
'tax_amount' => $row->{'TaxAmount'}, 'tax_amount' => $row->{'TaxAmount'},
'customer_id' => $newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'customer_id'},
'lease_id' => $newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'lease_id'},
}; };
addRow('ledger_entries', $credit_ledger_id = $newdb{'lookup'}{'charge_type'}{$row->{'ChargeDescription'}}{'ledger_id'};
{ 'monetary_source_id' => $newdb{'ids'}{'monetary_source'}{'internal'},
'transaction_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'tx'},
'debit_ledger_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'ledger'},
'credit_ledger_id' => $newdb{'lookup'}{'charge_type'}{$row->{'ChargeDescription'}}{'ledger'},
'amount' => $row->{'ChargeAmount'},
'comment' => "Charge: $row->{'ChargeID'}; Ledger: $row->{'LedgerID'}" });
my $debit_entry_id = $newdb{'tables'}{'ledger_entries'}{'autoid'},
addRow('ledger_entries', addRow('ledger_entries',
{ 'monetary_source_id' => $newdb{'ids'}{'monetary_source'}{'internal'}, { 'monetary_source_id' => $newdb{'ids'}{'monetary_source'}{'internal'},
'transaction_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'tx'}, 'transaction_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'tx'},
'debit_ledger_id' => $newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'cust_ledger'}, 'debit_ledger_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'ledger_id'},
'credit_ledger_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'ledger'}, 'credit_ledger_id' => $credit_ledger_id,
'customer_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'customer_id'},
'lease_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'lease_id'},
'amount' => $row->{'ChargeAmount'}, 'amount' => $row->{'ChargeAmount'},
'comment' => "Charge: $row->{'ChargeID'}; Ledger: $row->{'LedgerID'}" }); 'comment' => "Charge: $row->{'ChargeID'}; Ledger: $row->{'LedgerID'}" });
$newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'terminal'} $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'ledger_entry_id'}
= $debit_entry_id; = $newdb{'tables'}{'ledger_entries'}{'autoid'};
$newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'entry'}
= $newdb{'tables'}{'ledger_entries'}{'autoid'},
$newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'ledger'}
= $newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'cust_ledger'};
addRow('reconciliations',
{ 'debit_ledger_entry_id' => $debit_entry_id,
'credit_ledger_entry_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'entry'},
'terminal_ledger_entry_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'terminal'},
'amount' => $row->{'ChargeAmount'},
});
next unless $row->{'TaxAmount'}; next unless $row->{'TaxAmount'};
$credit_ledger_id = $newdb{'lookup'}{'charge_type'}{'Tax'}{'ledger_id'};
addRow('ledger_entries', addRow('ledger_entries',
{ 'monetary_source_id' => $newdb{'ids'}{'monetary_source'}{'internal'}, { 'monetary_source_id' => $newdb{'ids'}{'monetary_source'}{'internal'},
'transaction_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'tx'}, 'transaction_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'tx'},
'debit_ledger_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'ledger'}, 'debit_ledger_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'ledger_id'},
'credit_ledger_id' => $newdb{'lookup'}{'charge_type'}{'Tax'}{'ledger'}, 'credit_ledger_id' => $credit_ledger_id,
'customer_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'customer_id'},
'lease_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'lease_id'},
'amount' => $row->{'TaxAmount'}, 'amount' => $row->{'TaxAmount'},
'comment' => undef }); 'comment' => undef });
$newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'tax_entry'} $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'tax_entry'}
= $newdb{'tables'}{'ledger_entries'}{'autoid'}, = $newdb{'tables'}{'ledger_entries'}{'autoid'};
} }
@@ -944,10 +927,10 @@ $query =
foreach $row (@{query($sdbh, $query)}) { foreach $row (@{query($sdbh, $query)}) {
if ($newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}) { if ($newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}) {
die unless ($newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{'cust'} die unless ($newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{'customer_id'}
== $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{'cust'}); == $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{'customer_id'});
push(@{$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{'ledgers'}}, push(@{$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{'ledgers'}},
$newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'ledger'}); $newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'ledger_id'});
#print Dumper $receipt_map{$row->{'ReceiptNum'}}; #print Dumper $receipt_map{$row->{'ReceiptNum'}};
next; next;
} }
@@ -958,8 +941,12 @@ foreach $row (@{query($sdbh, $query)}) {
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}} $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}
= {'tx' => $newdb{'tables'}{'transactions'}{'autoid'}, = {'tx' => $newdb{'tables'}{'transactions'}{'autoid'},
'cust' => $newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'cust'}, # NOTE: Use of 'lease_id' would be invalid, since the
'ledgers' => [ $newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'ledger'} ] }; # receipt could be for multiple leases. 'customer_id'
# could be OK, but better to avoid this issue all
# together by excluding them both from this lookup.
'ledgers' => [ $newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'ledger_id'} ] };
} }
@@ -975,48 +962,88 @@ $newdb{'lookup'}{'payment'} = {};
$query = "SELECT * FROM Payments ORDER BY PaymentID"; $query = "SELECT * FROM Payments ORDER BY PaymentID";
foreach $row (@{query($sdbh, $query)}) foreach $row (@{query($sdbh, $query)})
{ {
my $monetary_source_id; $newdb{'lookup'}{'payment'}{$row->{'PaymentID'}} = {};
if ($row->{'PaymentDate'} =~ m%3/25/2009%) { if ($row->{'PaymentDate'} =~ m%3/25/2009%) {
$monetary_source_id = $newdb{'ids'}{'monetary_source'}{'closing'}; $newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'monetary_source_id'}
= $newdb{'ids'}{'monetary_source'}{'Closing'};
$newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'account_name'}
= 'Bank';
} }
else { else {
$monetary_source_id = $newdb{'ids'}{'monetary_source'}{ $newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'monetary_source_id'}
= $newdb{'ids'}{'monetary_source'}{
$newdb{'lookup'}{'payment_type'}{$row->{'PaymentType'}}{'name'} $newdb{'lookup'}{'payment_type'}{$row->{'PaymentType'}}{'name'}
}; };
$newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'account_name'}
= $newdb{'lookup'}{'payment_type'}{$row->{'PaymentType'}}{'account_name'};
} }
if (!defined $monetary_source_id) { if (!$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'monetary_source_id'}) {
if (!defined $newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'monetary_source_id'}) {
my $name;
$name = $newdb{'lookup'}{'payment_type'}{$row->{'PaymentType'}}{'name'};
if ($name eq 'Check') {
$name = 'Check #' . $row->{'CheckNum'};
}
addRow('monetary_sources', addRow('monetary_sources',
{ 'monetary_type_id' => $newdb{'lookup'}{'payment_type'}{$row->{'PaymentType'}}{'monetary_type'}{'id'}, { 'monetary_type_id' => $newdb{'lookup'}{'payment_type'}{$row->{'PaymentType'}}{'monetary_type'}{'id'},
'name' => $row->{'RecdFrom'}, 'name' => $name,
'comment' => "Payment: $row->{'PaymentID'}; Type: $row->{'PaymentType'}; Check: $row->{'CheckNum'}; $row->{'Memo'}" }); 'comment' => "Payment: $row->{'PaymentID'}; Type: $row->{'PaymentType'}; Check: $row->{'CheckNum'}; $row->{'Memo'}" });
$monetary_source_id = $newdb{'tables'}{'monetary_sources'}{'autoid'}; $newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'monetary_source_id'}
= $newdb{'tables'}{'monetary_sources'}{'autoid'};
} }
my $payment_acct = $newdb{'lookup'}{'payment_type'}{$row->{'PaymentType'}}{'account'}; $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'monetary_source_id'}
= $newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'monetary_source_id'};
}
$newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'debit_ledger_id'}
= $newdb{'lookup'}{'account'}{$newdb{'lookup'}{'payment'}{
$row->{'PaymentID'}}{'account_name'}
}{'ledger_id'};
# Sitelink splits one physical payment into multiple "payments" to match each charge
# This is kludgy, but for our cases at least, brings those pseudo-payments back into
# a single one. It presumes that there is only one PaymentType per receipt.
if (!$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'ledger_entry_id'}) {
addRow('ledger_entries', addRow('ledger_entries',
{ 'monetary_source_id' => $monetary_source_id, { 'monetary_source_id' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'monetary_source_id'},
'transaction_id' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{'tx'}, 'transaction_id' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{'tx'},
'debit_ledger_id' => $newdb{'lookup'}{'account'}{$payment_acct}{'ledger'}, 'debit_ledger_id' => $newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'debit_ledger_id'},
'credit_ledger_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'ledger'}, 'credit_ledger_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'ledger_id'},
'amount' => $row->{'PaymentAmount'}, 'customer_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'customer_id'},
'comment' => "Receipt: $row->{'ReceiptNum'}; Payment: $row->{'PaymentID'}; Charge: $row->{'ChargeID'}" }); #'lease_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'lease_id'},
'amount' => 0,
'comment' => "Receipt: $row->{'ReceiptNum'}; " });
$newdb{'lookup'}{'payment'}{$row->{'PaymentID'}} $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'ledger_entry_id'}
= { 'entry' => $newdb{'tables'}{'ledger_entries'}{'autoid'} }; = $newdb{'tables'}{'ledger_entries'}{'autoid'};
}
# Reconcile Payment to the Charge. Since tracking is due to $newdb{'tables'}{'ledger_entries'}{'rows'}[
# the A/R account (Lease Account in this case), credit/debit $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'ledger_entry_id'}
# is from the perspective of that account. Namely, the charge ]{'amount'} += $row->{'PaymentAmount'};
# was the debit to the A/R, and the payment was the credit.
$newdb{'tables'}{'ledger_entries'}{'rows'}[
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'ledger_entry_id'}
]{'comment'} .= 'P:'.$row->{'PaymentID'} . '->C:' . $row->{'ChargeID'} . '; ';
# OK, now that the receipt is reconciled, update
# payment to reference the true ledger_entry_id
$newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'ledger_entry_id'}
= $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'ledger_entry_id'};
# Figure out how much of the charge can be reconciled
my $reconcile_amount = $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'amount'}; my $reconcile_amount = $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'amount'};
$reconcile_amount = $row->{'PaymentAmount'} if $row->{'PaymentAmount'} <= $reconcile_amount; $reconcile_amount = $row->{'PaymentAmount'} if $row->{'PaymentAmount'} <= $reconcile_amount;
# Reconcile the A/R account. Since this is from the perspective
# of the A/R, charge is the debit, and payment is the credit
addRow('reconciliations', addRow('reconciliations',
{ 'debit_ledger_entry_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'entry'}, { 'type' => 'DEBIT',
'credit_ledger_entry_id' => $newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'entry'}, 'ledger_entry_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'ledger_entry_id'},
'terminal_ledger_entry_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'terminal'}, 'transaction_id' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{'tx'},
'amount' => $reconcile_amount, 'amount' => $reconcile_amount,
}); });
@@ -1033,11 +1060,12 @@ foreach $row (@{query($sdbh, $query)})
## Fake Data for Testing ## Fake Data for Testing
my %fake = my %fake =
('custid' => 2, ('customer_id' => 4,
'ledger_id' => 4,
'invoice' => [ { 'id' => 1000, 'invoice' => [ { 'id' => 1000,
'date' => '2009-05-05', 'date' => '2009-05-05',
'entry' => [ { 'id' => 2100, 'entry' => [ { 'id' => 2100,
'account' => 'Security Deposit', 'account_name' => 'Security Deposit',
'amount' => 10, 'amount' => 10,
'tax' => 0 }, 'tax' => 0 },
], ],
@@ -1046,7 +1074,7 @@ my %fake =
'date' => '2009-05-01', 'date' => '2009-05-01',
'thru' => '2009-05-31', 'thru' => '2009-05-31',
'entry' => [ { 'id' => 2110, 'entry' => [ { 'id' => 2110,
'account' => 'Rent', 'account_name' => 'Rent',
'amount' => 100, 'amount' => 100,
'tax' => 5 }, 'tax' => 5 },
], ],
@@ -1054,7 +1082,7 @@ my %fake =
{ 'id' => 1002, { 'id' => 1002,
'date' => '2009-05-11', 'date' => '2009-05-11',
'entry' => [ { 'id' => 2120, 'entry' => [ { 'id' => 2120,
'account' => 'Late Charge', 'account_name' => 'Late Charge',
'amount' => 25, 'amount' => 25,
'tax' => 0 }, 'tax' => 0 },
], ],
@@ -1115,17 +1143,17 @@ my %fake =
); );
sub fakeTesting {
$newdb{'ids'}{'ledger'}{'Cash-Old'} = $newdb{'ids'}{'ledger'}{'Cash-Old'} =
$newdb{'lookup'}{'account'}{'Cash'}{'ledger'}; $newdb{'lookup'}{'account'}{'Cash'}{'ledger_id'};
addRow('ledgers', addRow('ledgers',
{ 'account_id' => $newdb{'lookup'}{'account'}{'Cash'}{'account'}, { 'account_id' => $newdb{'lookup'}{'account'}{'Cash'}{'account_id'},
'open_stamp' => 'NOW()', 'open_stamp' => 'NOW()',
'sequence' => 2, 'sequence' => 2,
'comment' => 'Opened new ledger for testing' }); 'comment' => 'Opened new ledger for testing' });
$newdb{'lookup'}{'account'}{'Cash'}{'ledger'} = $newdb{'lookup'}{'account'}{'Cash'}{'ledger_id'} =
$newdb{'tables'}{'ledgers'}{'autoid'}; $newdb{'tables'}{'ledgers'}{'autoid'};
my $balance = 0; my $balance = 0;
@@ -1143,7 +1171,7 @@ addRow('transactions',
addRow('ledger_entries', addRow('ledger_entries',
{ 'monetary_source_id' => $newdb{'ids'}{'monetary_source'}{'internal'}, { 'monetary_source_id' => $newdb{'ids'}{'monetary_source'}{'internal'},
'transaction_id' => $newdb{'tables'}{'transactions'}{'autoid'}, 'transaction_id' => $newdb{'tables'}{'transactions'}{'autoid'},
'debit_ledger_id' => $newdb{'lookup'}{'account'}{'Cash'}{'ledger'}, 'debit_ledger_id' => $newdb{'lookup'}{'account'}{'Cash'}{'ledger_id'},
'credit_ledger_id' => $newdb{'ids'}{'ledger'}{'Cash-Old'}, 'credit_ledger_id' => $newdb{'ids'}{'ledger'}{'Cash-Old'},
'amount' => $balance, 'amount' => $balance,
'name' => "Close Out ($newdb{'ids'}{'ledger'}{'Cash-Old'} -> $newdb{'tables'}{'transactions'}{'autoid'})", 'name' => "Close Out ($newdb{'ids'}{'ledger'}{'Cash-Old'} -> $newdb{'tables'}{'transactions'}{'autoid'})",
@@ -1165,8 +1193,10 @@ foreach my $ir ('invoice', 'receipt') {
1); 1);
foreach my $e (@{$tx->{'entry'}}) { foreach my $e (@{$tx->{'entry'}}) {
my $crdr = ($ir eq 'invoice') ? 'Invoice' : 'Receipt';
my $dr = ($ir eq 'invoice') ? 'A/R' : 'Cash'; my $dr = ($ir eq 'invoice') ? 'A/R' : 'Cash';
my $cr = ($ir eq 'invoice') ? $e->{'account'} : 'A/R'; $crdr = $dr;
my $cr = ($ir eq 'invoice') ? $e->{'account_name'} : 'A/R';
my $monetary_source_id; my $monetary_source_id;
if (defined $e->{'type'}) { if (defined $e->{'type'}) {
@@ -1184,17 +1214,31 @@ foreach my $ir ('invoice', 'receipt') {
{ 'id' => $e->{'id'}, { 'id' => $e->{'id'},
'monetary_source_id' => $monetary_source_id, 'monetary_source_id' => $monetary_source_id,
'transaction_id' => $tx->{'id'}, 'transaction_id' => $tx->{'id'},
'debit_ledger_id' => $newdb{'lookup'}{'account'}{$dr}{'ledger'}, 'debit_ledger_id' => $newdb{'lookup'}{'account'}{$crdr}{'ledger_id'},
'credit_ledger_id' => $newdb{'lookup'}{'account'}{$cr}{'ledger'}, 'credit_ledger_id' => $newdb{'lookup'}{'account'}{$cr}{'ledger_id'},
'customer_id' => $fake{'customer_id'},
'lease_id' => $fake{'lease_id'},
'amount' => $e->{'amount'}, 'amount' => $e->{'amount'},
'comment' => "Fake $ir entry" }, 'comment' => "Fake $ir entry" },
1); 1);
# addRow('ledger_entries',
# { 'id' => $e->{'id'},
# 'monetary_source_id' => $monetary_source_id,
# 'transaction_id' => $tx->{'id'},
# 'debit_ledger_id' => $newdb{'lookup'}{'account'}{$dr}{'ledger_id'},
# 'credit_ledger_id' => $newdb{'lookup'}{'account'}{$crdr}{'ledger_id'},
# 'customer_id' => $fake{'customer_id'},
# 'lease_id' => $fake{'lease_id'},
# 'amount' => $e->{'amount'},
# 'comment' => "Fake $ir entry" },
# 1);
foreach my $t (@{$e->{'track'}}) { foreach my $t (@{$e->{'track'}}) {
addRow('reconciliations', addRow('reconciliations',
{ 'debit_ledger_entry_id' => $t->{'debit'}, { 'type' => 'DEBIT',
'credit_ledger_entry_id' => $e->{'id'}, 'ledger_entry_id' => $t->{'debit'},
'terminal_ledger_entry_id' => $t->{'debit'}, 'transaction_id' => $tx->{'id'},
'amount' => $t->{'amount'} 'amount' => $t->{'amount'}
}); });
} }
@@ -1205,14 +1249,31 @@ foreach my $ir ('invoice', 'receipt') {
{ 'id' => $e->{'id'}+1, { 'id' => $e->{'id'}+1,
'monetary_source_id' => $monetary_source_id, 'monetary_source_id' => $monetary_source_id,
'transaction_id' => $tx->{'id'}, 'transaction_id' => $tx->{'id'},
'debit_ledger_id' => $newdb{'lookup'}{'account'}{$dr}{'ledger'}, 'debit_ledger_id' => $newdb{'lookup'}{'account'}{$crdr}{'ledger_id'},
'credit_ledger_id' => $newdb{'lookup'}{'account'}{'Tax'}{'ledger'}, 'credit_ledger_id' => $newdb{'lookup'}{'account'}{'Tax'}{'ledger_id'},
'amount' => $e->{'tax'}, 'customer_id' => $fake{'customer_id'},
'lease_id' => $fake{'lease_id'},
'amount' => $e->{'amount'},
'comment' => "Fake Tax" }, 'comment' => "Fake Tax" },
1); 1);
# addRow('ledger_entries',
# { 'id' => $e->{'id'}+1,
# 'monetary_source_id' => $monetary_source_id,
# 'transaction_id' => $tx->{'id'},
# 'debit_ledger_id' => $newdb{'lookup'}{'account'}{$dr}{'ledger_id'},
# 'credit_ledger_id' => $newdb{'lookup'}{'account'}{$crdr}{'ledger_id'},
# 'customer_id' => $fake{'customer_id'},
# 'lease_id' => $fake{'lease_id'},
# 'amount' => $e->{'tax'},
# 'comment' => "Fake Tax" },
# 1);
} }
} }
} }
}
#fakeTesting();
$Data::Dumper::Sortkeys = 1; $Data::Dumper::Sortkeys = 1;
print Dumper \%newdb; print Dumper \%newdb;

View File

@@ -305,7 +305,13 @@ class AppController extends Controller {
$id = 'id'; $id = 'id';
extract(array_intersect_key($fields, array_flip($special))); extract(array_intersect_key($fields, array_flip($special)));
foreach ($records AS &$record) { foreach ($records AS &$record) {
if (!isset($record[$table]))
continue;
foreach (array_diff_key($fields, array_flip($special)) AS $field) { foreach (array_diff_key($fields, array_flip($special)) AS $field) {
if (!isset($record[$table][$id]) || !isset($record[$table][$field]))
continue;
// DEBUG PURPOSES ONLY! // DEBUG PURPOSES ONLY!
//$params['linkrecord'][] = compact('table', 'field', 'id', 'controller', 'record'); //$params['linkrecord'][] = compact('table', 'field', 'id', 'controller', 'record');
$record[$table][$field] = $record[$table][$field] =
@@ -338,29 +344,39 @@ class AppController extends Controller {
} }
function jqGridDataOutputRecords(&$params, &$model, &$records) { function jqGridDataOutputRecords(&$params, &$model, &$records) {
$model_alias = $model->alias; $id_field = 'jqGrid_id';
$id = 'jqGrid_id';
foreach ($records AS $record) { foreach ($records AS $record) {
echo " <row id='{$record[$id]}'>\n"; $this->jqGridDataOutputRecord($params, $model, $record,
foreach ($params['fields'] AS $field) { $record[$id_field], $params['fields']);
}
}
function jqGridDataOutputRecord(&$params, &$model, &$record, $id, $fields) {
echo " <row id='$id'>\n";
foreach ($fields AS $field) {
$this->jqGridDataOutputRecordField($params, $model, $record, $field);
}
echo " </row>\n";
}
function jqGridDataOutputRecordField(&$params, &$model, &$record, $field) {
if (preg_match("/\./", $field)) { if (preg_match("/\./", $field)) {
list($tbl, $col) = explode(".", $field); list($tbl, $col) = explode(".", $field);
$data = $record[$tbl][$col]; $data = $record[$tbl][$col];
} }
else { else {
$data = $record[$model_alias][$field]; $data = $record[$model->alias][$field];
}
$this->jqGridDataOutputRecordCell($params, $model, $record, $field, $data);
} }
function jqGridDataOutputRecordCell(&$params, &$model, &$record, $field, $data) {
// be sure to put text data in CDATA // be sure to put text data in CDATA
if (preg_match("/^\d*$/", $data)) if (preg_match("/^\d*$/", $data))
echo " <cell>$data</cell>\n"; echo " <cell>$data</cell>\n";
else else
echo " <cell><![CDATA[$data]]></cell>\n"; echo " <cell><![CDATA[$data]]></cell>\n";
} }
echo " </row>\n";
}
}
function jqGridDataFinalize(&$params) { function jqGridDataFinalize(&$params) {
if ($params['debug']) { if ($params['debug']) {

View File

@@ -71,6 +71,7 @@ class LeasesController extends AppController {
function jqGridRecordLinks(&$params, &$model, &$records, $links) { function jqGridRecordLinks(&$params, &$model, &$records, $links) {
$links['Lease'] = array('number'); $links['Lease'] = array('number');
$links['Unit'] = array('name'); $links['Unit'] = array('name');
$links['Customer'] = array('name');
return parent::jqGridRecordLinks($params, $model, $records, $links); return parent::jqGridRecordLinks($params, $model, $records, $links);
} }
@@ -107,7 +108,6 @@ class LeasesController extends AppController {
array(// Models array(// Models
'LeaseType', 'LeaseType',
'Unit', 'Unit',
'Account' => array('CurrentLedger'),
'Customer', 'Customer',
), ),
'conditions' => array(array('Lease.id' => $id)), 'conditions' => array(array('Lease.id' => $id)),
@@ -115,23 +115,15 @@ class LeasesController extends AppController {
) )
); );
// Summarize each ledger
$this->Lease->statsMerge($lease,
$this->Lease->stats($lease['Lease']['id']));
// Obtain the overall lease balance // Obtain the overall lease balance
$this->Lease->statsMerge($lease['Lease'], $this->Lease->statsMerge($lease['Lease'],
array('stats' => $this->Lease->stats($id))); array('stats' => $this->Lease->stats($id)));
$outstanding_balance = $lease['Lease']['stats']['Account']['Ledger']['balance']; $outstanding_balance = $lease['Lease']['stats']['balance'];
// Determine the lease security deposit // Determine the lease security deposit
$deposits = $this->Lease->findSecurityDeposits($lease['Lease']['id']); $deposits = $this->Lease->findSecurityDeposits($lease['Lease']['id']);
$outstanding_deposit = $deposits['summary']['balance']; $outstanding_deposit = $deposits['summary']['balance'];
// Move the Leder stats into our alias 'CurrentLedger'
$lease['Account']['CurrentLedger'] += $lease['Account']['Ledger'];
unset($lease['Account']['Ledger']);
// Prepare to render // Prepare to render
$title = 'Lease: #' . $lease['Lease']['id']; $title = 'Lease: #' . $lease['Lease']['id'];
$this->set(compact('lease', 'title', $this->set(compact('lease', 'title',

View File

@@ -25,7 +25,15 @@ class LedgerEntriesController extends AppController {
* to jqGrid. * to jqGrid.
*/ */
function jqGridDataTables(&$params, &$model) { function jqGridDataSetup(&$params) {
parent::jqGridDataSetup($params);
if (isset($params['custom']['ar_account'])) {
$params['custom']['account_id'] =
$this->LedgerEntry->DebitLedger->Account->accountReceivableAccountID();
}
}
function jqGridDataCountTables(&$params, &$model) {
$link = $link =
array(// Models array(// Models
'Transaction' => 'Transaction' =>
@@ -36,6 +44,16 @@ class LedgerEntriesController extends AppController {
array('fields' => array('id', 'name'), array('fields' => array('id', 'name'),
), ),
'Customer' =>
array('fields' => array('id', 'name'),
),
'Lease' =>
array('fields' => array('id', 'number'),
'Unit' =>
array('fields' => array('id', 'name'),
),
),
); );
if (isset($params['custom']['account_ftype'])) { if (isset($params['custom']['account_ftype'])) {
@@ -77,26 +95,86 @@ class LedgerEntriesController extends AppController {
); );
} }
if (isset($params['custom']['account_id']) || isset($params['custom']['lease_id'])) {
if (isset($params['custom']['account_id']))
$account_id = $params['custom']['account_id'];
else
$account_id =
$this->LedgerEntry->DebitLedger->Account->accountReceivableAccountID();
$link['Ledger'] =
array('fields' => array('id', 'sequence'),
'conditions' => ("Ledger.id = IF(DebitLedger.account_id = $account_id," .
" LedgerEntry.credit_ledger_id," .
" LedgerEntry.debit_ledger_id)"),
'Account' => array(
'fields' => array('id', 'name'),
),
);
}
if (isset($params['custom']['lease_id'])) {
$account_id = $params['custom']['lease_id'];
$link['Transaction']['ReconciledLedgerEntry'] =
array('fields' => array('id', 'Reconciliation.amount', 'Reconciliation.type'),
);
}
if (isset($params['custom']['reconcile_id'])) { if (isset($params['custom']['reconcile_id'])) {
$ftype = $params['custom']['account_ftype']; $ftype = $params['custom']['account_ftype'];
$ftype = $this->LedgerEntry->DebitLedger->Account->fundamentalOpposite($ftype); $ftype = $this->LedgerEntry->DebitLedger->Account->fundamentalOpposite($ftype);
$ftype = ucfirst($ftype); $link['ReconcilingTransaction'] =
$link[$ftype.'ReconciliationLedgerEntry'] = array('fields' => array('Reconciliation.amount'),
array('fields' => array('Reconciliation.amount')); 'conditions' => array('Reconciliation.type' => $ftype),
);
} }
return array('link' => $link); return array('link' => $link);
} }
function jqGridDataTables(&$params, &$model) {
return $this->jqGridDataCountTables($params, $model);
}
function jqGridDataFields(&$params, &$model) { function jqGridDataFields(&$params, &$model) {
if (isset($params['custom']['lease_id'])) {
$account_id =
$this->LedgerEntry->DebitLedger->Account->accountReceivableAccountID();
$fields = array('id', 'name', 'comment', 'amount');
$fields[] = ("IF(DebitLedger.account_id = $account_id," .
" SUM(IF(ReconciledLedgerEntry.amount IS NULL," .
" LedgerEntry.amount," .
" ReconciledLedgerEntry.amount))," .
" NULL) AS debit");
$fields[] = ("IF(CreditLedger.account_id = $account_id," .
" SUM(IF(ReconciledLedgerEntry.amount IS NULL," .
" LedgerEntry.amount," .
" ReconciledLedgerEntry.amount))," .
" NULL) AS credit");
$Account = new Account();
$account_ftype = ucfirst($Account->fundamentalType($account_id));
$fields[] = ("(IF({$account_ftype}Ledger.account_id = $account_id, 1, -1)" .
" * SUM(IF(ReconciledLedgerEntry.amount IS NULL," .
" LedgerEntry.amount," .
" ReconciledLedgerEntry.amount)))" .
" AS balance");
return $fields;
}
$ledger_id = (isset($params['custom']['ledger_id']) $ledger_id = (isset($params['custom']['ledger_id'])
? $params['custom']['ledger_id'] ? $params['custom']['ledger_id']
: null); : null);
$account_id = (isset($params['custom']['account_id'])
? $params['custom']['account_id']
: null);
$account_type = (isset($params['custom']['account_type']) $account_type = (isset($params['custom']['account_type'])
? $params['custom']['account_type'] ? $params['custom']['account_type']
: null); : null);
return $model->ledgerContextFields2($ledger_id, $account_type); return $model->ledgerContextFields2($ledger_id, $account_id, $account_type);
} }
function jqGridDataConditions(&$params, &$model) { function jqGridDataConditions(&$params, &$model) {
@@ -109,13 +187,44 @@ class LedgerEntriesController extends AppController {
$conditions = parent::jqGridDataConditions($params, $model); $conditions = parent::jqGridDataConditions($params, $model);
if ($params['action'] === 'ledger') { if ($params['action'] === 'ledger' && isset($ledger_id)) {
$conditions[] = $model->ledgerContextConditions($ledger_id, $account_type); $conditions[] = $model->ledgerContextConditions($ledger_id, $account_type);
} }
if (isset($params['custom']['reconcile_id'])) { if (isset($params['custom']['reconcile_id'])) {
$ftype = $params['custom']['account_ftype']; $ftype = $params['custom']['account_ftype'];
//$ftype = $this->LedgerEntry->DebitLedger->Account->fundamentalOpposite($ftype); //$ftype = $this->LedgerEntry->DebitLedger->Account->fundamentalOpposite($ftype);
$conditions[] = array('Reconciliation.'.$ftype.'_ledger_entry_id' => $params['custom']['reconcile_id']); //$link['ReconcilingTransaction']['conditions'][] = array('Reconciliation.type' => $ftype);
$conditions[] = array('Reconciliation.ledger_entry_id' => $params['custom']['reconcile_id']);
}
if (isset($params['custom']['account_id'])) {
$conditions[] =
array('OR' =>
array(array('CreditAccount.id' => $params['custom']['account_id']),
array('DebitAccount.id' => $params['custom']['account_id'])));
/* $conditions[] = */
/* array('Account.id' => $params['custom']['account_id']); */
}
if (isset($params['custom']['customer_id'])) {
$conditions[] =
array('Customer.id' => $params['custom']['customer_id']);
}
if (isset($params['custom']['lease_id'])) {
$conditions[] =
array('OR' => array
(array('Lease.id' => $params['custom']['lease_id']),
array('ReconciledLedgerEntry.lease_id' => $params['custom']['lease_id']),
));
}
if (isset($params['custom']['transaction_id'])) {
$conditions[] =
array('Transaction.id' => $params['custom']['transaction_id']);
} }
return $conditions; return $conditions;
@@ -124,14 +233,13 @@ class LedgerEntriesController extends AppController {
function jqGridRecordLinks(&$params, &$model, &$records, $links) { function jqGridRecordLinks(&$params, &$model, &$records, $links) {
$links['Transaction'] = array('id'); $links['Transaction'] = array('id');
$links['LedgerEntry'] = array('id'); $links['LedgerEntry'] = array('id');
if (isset($params['custom']['account_ftype']) || isset($params['custom']['ledger_id'])) {
$links['Account'] = array('controller' => 'accounts', 'name'); $links['Account'] = array('controller' => 'accounts', 'name');
}
else {
$links['DebitAccount'] = array('controller' => 'accounts', 'name'); $links['DebitAccount'] = array('controller' => 'accounts', 'name');
$links['CreditAccount'] = array('controller' => 'accounts', 'name'); $links['CreditAccount'] = array('controller' => 'accounts', 'name');
}
$links['MonetarySource'] = array('name'); $links['MonetarySource'] = array('name');
$links['Customer'] = array('name');
$links['Lease'] = array('number');
$links['Unit'] = array('name');
return parent::jqGridRecordLinks($params, $model, $records, $links); return parent::jqGridRecordLinks($params, $model, $records, $links);
} }
@@ -145,8 +253,39 @@ class LedgerEntriesController extends AppController {
function jqGridDataOrder(&$params, &$model, $index, $direction) { function jqGridDataOrder(&$params, &$model, $index, $direction) {
/* if ($index === 'balance') */ /* if ($index === 'balance') */
/* return ($index .' '. $direction); */ /* return ($index .' '. $direction); */
$order = parent::jqGridDataOrder($params, $model, $index, $direction);
return parent::jqGridDataOrder($params, $model, $index, $direction); if ($index === 'Transaction.stamp') {
$order[] = 'LedgerEntry.id ' . $direction;
}
return $order;
}
function jqGridRecordsPostProcess(&$params, &$model, &$records) {
parent::jqGridRecordsPostProcess($params, $model, $records);
$subtotal = 0;
foreach ($records AS &$record) {
$amount = (isset($record['LedgerEntry']['balance'])
? $record['LedgerEntry']['balance']
: $record['LedgerEntry']['amount']);
$record['LedgerEntry']['subtotal'] = ($subtotal += $amount);
continue;
// Experiment to minimize columns by putting the monetary source
// as the Account, when available
if ($record['MonetarySource']['name'])
$record['Account']['name'] = $record['MonetarySource']['name'];
}
}
function jqGridDataOutputRecordCell(&$params, &$model, &$record, $field, $data) {
/* if ($field === 'CreditAccount.name') { */
/* $data .= '-OK'; */
/* } */
parent::jqGridDataOutputRecordCell($params, $model, $record, $field, $data);
} }
@@ -167,6 +306,7 @@ class LedgerEntriesController extends AppController {
$entry = $this->LedgerEntry->find $entry = $this->LedgerEntry->find
('first', ('first',
array('contain' => array('MonetarySource.id', array('contain' => array('MonetarySource.id',
'MonetarySource.name',
'MonetarySource.MonetaryType.id', 'MonetarySource.MonetaryType.id',
'Transaction.id', 'Transaction.id',
'Transaction.stamp', 'Transaction.stamp',
@@ -176,6 +316,9 @@ class LedgerEntriesController extends AppController {
'CreditLedger.id', 'CreditLedger.id',
'CreditLedger.sequence', 'CreditLedger.sequence',
'CreditLedger.account_id', 'CreditLedger.account_id',
'Customer.id',
'Customer.name',
'Lease.id',
), ),
'fields' => array('LedgerEntry.id', 'fields' => array('LedgerEntry.id',
@@ -184,6 +327,7 @@ class LedgerEntriesController extends AppController {
'conditions' => array('LedgerEntry.id' => $id), 'conditions' => array('LedgerEntry.id' => $id),
)); ));
//pr($entry);
// Because 'DebitLedger' and 'CreditLedger' both relate to 'Account', // Because 'DebitLedger' and 'CreditLedger' both relate to 'Account',
// CakePHP will not include them in the LedgerEntry->find (or so it // CakePHP will not include them in the LedgerEntry->find (or so it
@@ -213,8 +357,8 @@ class LedgerEntriesController extends AppController {
$stats['credit_amount_remaining'] = $entry['LedgerEntry']['amount'] - $stats['credit_amount_reconciled']; $stats['credit_amount_remaining'] = $entry['LedgerEntry']['amount'] - $stats['credit_amount_reconciled'];
//pr($stats); //pr($stats);
$reconciled = $this->LedgerEntry->findReconciledLedgerEntries($id); $reconciled = $this->LedgerEntry->findReconcilingTransactions($id);
//pr($reconciled); //pr(compact('reconciled'));
// Prepare to render. // Prepare to render.
$title = "Ledger Entry #{$entry['LedgerEntry']['id']}"; $title = "Ledger Entry #{$entry['LedgerEntry']['id']}";

View File

@@ -41,6 +41,43 @@ class TransactionsController extends AppController {
* to jqGrid. * to jqGrid.
*/ */
function jqGridDataSetup(&$params) {
parent::jqGridDataSetup($params);
}
function jqGridDataTables(&$params, &$model) {
$link = array();
if (isset($params['custom']['reconcile_ledger_entry_id'])) {
$ftype = $params['custom']['reconcile_type'];
//$ftype = $this->Transaction->LedgerEntry->DebitLedger->Account->fundamentalOpposite($ftype);
$link['ReconciledLedgerEntry'] =
array('fields' => array('Reconciliation.amount'),
'conditions' => array('Reconciliation.type' => $ftype)
);
}
return array('link' => $link);
}
function jqGridDataFields(&$params, &$model) {
return parent::jqGridDataFields($params, $model);
}
function jqGridDataConditions(&$params, &$model) {
$conditions = parent::jqGridDataConditions($params, $model);
if (isset($params['custom']['reconcile_ledger_entry_id'])) {
/* $ftype = $params['custom']['reconcile_type']; */
/* $ftype = $this->LedgerEntry->DebitLedger->Account->fundamentalOpposite($ftype); */
/* $conditions[] = array('Reconciliation.type' => $ftype); */
$conditions[] = array('Reconciliation.ledger_entry_id'
=> $params['custom']['reconcile_ledger_entry_id']);
}
return $conditions;
}
function jqGridRecordLinks(&$params, &$model, &$records, $links) { function jqGridRecordLinks(&$params, &$model, &$records, $links) {
$links['Transaction'] = array('id'); $links['Transaction'] = array('id');
return parent::jqGridRecordLinks($params, $model, $records, $links); return parent::jqGridRecordLinks($params, $model, $records, $links);

View File

@@ -121,7 +121,7 @@ class UnitsController extends AppController {
// Get the balance on each lease. // Get the balance on each lease.
foreach ($unit['Lease'] AS &$lease) { foreach ($unit['Lease'] AS &$lease) {
$stats = $this->Unit->Lease->stats($lease['id']); $stats = $this->Unit->Lease->stats($lease['id']);
$lease['balance'] = $stats['Account']['Ledger']['balance']; $lease['balance'] = $stats['balance'];
} }
$outstanding_balance = 0; $outstanding_balance = 0;
@@ -130,7 +130,7 @@ class UnitsController extends AppController {
// Figure out the outstanding balance of the current lease. // Figure out the outstanding balance of the current lease.
$stats = $this->Unit->stats($id); $stats = $this->Unit->stats($id);
$outstanding_balance = $outstanding_balance =
$stats['CurrentLease']['Account']['Ledger']['balance']; $stats['CurrentLease']['balance'];
// Figure out the total security deposit for the current lease. // Figure out the total security deposit for the current lease.
$deposits = $this->Unit->Lease->findSecurityDeposits($unit['CurrentLease']['id']); $deposits = $this->Unit->Lease->findSecurityDeposits($unit['CurrentLease']['id']);

View File

@@ -82,37 +82,26 @@ class Account extends AppModel {
/************************************************************************** /**************************************************************************
************************************************************************** **************************************************************************
************************************************************************** **************************************************************************
* function: securityDepositAccountID * function: accountNameToID
* - Returns the ID of the Security Deposit Account * - Returns the ID of the named account
*/ */
function securityDepositAccountID() { function accountNameToID($name) {
$this->cacheQueries = true; $this->cacheQueries = true;
$account = $this->find('first', array $account = $this->find('first', array
('recursive' => -1, ('recursive' => -1,
'conditions' => array 'conditions' => compact('name'),
(array('name' => 'Security Deposit')),
)); ));
$this->cacheQueries = false; $this->cacheQueries = false;
return $account['Account']['id']; return $account['Account']['id'];
} }
function securityDepositAccountID() { return $this->accountNameToID('Security Deposit'); }
/************************************************************************** function rentAccountID() { return $this->accountNameToID('Rent'); }
************************************************************************** function accountReceivableAccountID() { return $this->accountNameToID('A/R'); }
************************************************************************** function invoiceAccountID() { return $this->accountReceivableAccountID(); }
* function:rentAccountID function receiptAccountID() { return $this->accountReceivableAccountID(); }
* - Returns the ID of the Rent Account //function invoiceAccountID() { return $this->accountNameToID('Invoice'); }
*/ //function receiptAccountID() { return $this->accountNameToID('Receipt'); }
function rentAccountID() {
$this->cacheQueries = true;
$account = $this->find('first', array
('recursive' => -1,
'conditions' => array
(array('name' => 'Rent')),
));
$this->cacheQueries = false;
return $account['Account']['id'];
}
/************************************************************************** /**************************************************************************
@@ -122,22 +111,19 @@ class Account extends AppModel {
* - Returns an array of ledger ids from the given account * - Returns an array of ledger ids from the given account
*/ */
function ledgers($id, $all = false) { function ledgers($id, $all = false) {
$cachekey = $all ? 'all' : 'current';
if (isset($this->cache[$id]['ledgers'][$cachekey])) {
return $this->cache[$id]['ledgers'][$cachekey];
}
if ($all) { if ($all) {
$contain = array('Ledger' => array('fields' => array('Ledger.id'))); $contain = array('Ledger' => array('fields' => array('Ledger.id')));
} else { } else {
$contain = array('CurrentLedger' => array('fields' => array('CurrentLedger.id'))); $contain = array('CurrentLedger' => array('fields' => array('CurrentLedger.id')));
} }
$this->cacheQueries = true;
$account = $this->find('first', array $account = $this->find('first', array
('contain' => $contain, ('contain' => $contain,
'fields' => array(), 'fields' => array(),
'conditions' => array(array('Account.id' => $id)), 'conditions' => array(array('Account.id' => $id)),
)); ));
$this->cacheQueries = false;
if ($all) { if ($all) {
$ledger_ids = array(); $ledger_ids = array();
@@ -148,14 +134,11 @@ class Account extends AppModel {
$ledger_ids = array($account['CurrentLedger']['id']); $ledger_ids = array($account['CurrentLedger']['id']);
} }
// Save the ledgers in our cache for future reference
$this->cache[$id]['ledgers'][$cachekey] = $ledger_ids;
/* pr(array('function' => 'Account::ledgers', */ /* pr(array('function' => 'Account::ledgers', */
/* 'args' => compact('id', 'all'), */ /* 'args' => compact('id', 'all'), */
/* 'return' => $this->cache[$id]['ledgers'][$cachekey])); */ /* 'return' => $ledger_ids)); */
return $this->cache[$id]['ledgers'][$cachekey]; return $ledger_ids;
} }
@@ -234,25 +217,29 @@ class Account extends AppModel {
* (such as charges not paid). * (such as charges not paid).
*/ */
function findUnreconciledLedgerEntries($id = null, $fundamental_type = null) { function findUnreconciledLedgerEntries($id = null, $fundamental_type = null, $cond = null) {
if (!isset($cond))
$cond = array();
$cond[] = array('Account.id' => $id);
foreach (($fundamental_type foreach (($fundamental_type
? array($fundamental_type) ? array($fundamental_type)
: array('debit', 'credit')) AS $fund) { : array('debit', 'credit')) AS $fund) {
$ucfund = ucfirst($fund); $ucfund = ucfirst($fund);
$unreconciled[$fund]['entry'] = $this->find $unreconciled[$fund]['LedgerEntry'] = $this->find
('all', array ('all', array
('link' => array ('link' => array
('Ledger' => array ('Ledger' => array
('fields' => array(), ('fields' => array(),
"LedgerEntry" => array 'LedgerEntry' => array
('class' => "{$ucfund}LedgerEntry", ('class' => "{$ucfund}LedgerEntry",
'fields' => array('id', 'amount'), 'fields' => array('id', 'amount'),
"ReconciliationLedgerEntry" => array 'ReconcilingTransaction' => array
('class' => "{$ucfund}ReconciliationLedgerEntry", ('fields' => array
'fields' => array
("COALESCE(SUM(Reconciliation.amount),0) AS 'reconciled'", ("COALESCE(SUM(Reconciliation.amount),0) AS 'reconciled'",
"LedgerEntry.amount - COALESCE(SUM(Reconciliation.amount),0) AS 'balance'", "LedgerEntry.amount - COALESCE(SUM(Reconciliation.amount),0) AS 'balance'",
), ),
'conditions' => array('Reconciliation.type' => $fund),
), ),
), ),
), ),
@@ -260,11 +247,11 @@ class Account extends AppModel {
'group' => ("LedgerEntry.id" . 'group' => ("LedgerEntry.id" .
" HAVING LedgerEntry.amount" . " HAVING LedgerEntry.amount" .
" <> COALESCE(SUM(Reconciliation.amount),0)"), " <> COALESCE(SUM(Reconciliation.amount),0)"),
'conditions' => array('Account.id' => $id), 'conditions' => $cond,
'fields' => array(), 'fields' => array(),
)); ));
$balance = 0; $balance = 0;
foreach ($unreconciled[$fund]['entry'] AS &$entry) { foreach ($unreconciled[$fund]['LedgerEntry'] AS &$entry) {
$entry = array_merge(array_diff_key($entry["LedgerEntry"], array(0=>true)), $entry = array_merge(array_diff_key($entry["LedgerEntry"], array(0=>true)),
$entry[0]); $entry[0]);
$balance += $entry['balance']; $balance += $entry['balance'];
@@ -290,24 +277,24 @@ class Account extends AppModel {
* whatever algorithm is simplest. * whatever algorithm is simplest.
*/ */
function reconcileNewLedgerEntry($id, $fundamental_type, $amount) { function reconcileNewLedgerEntry($id, $fundamental_type, $amount, $cond = null) {
$ofund = $this->fundamentalOpposite($fundamental_type); $ofund = $this->fundamentalOpposite($fundamental_type);
$unreconciled = array($ofund => array('entry'=>array(), 'balance'=>0)); $unreconciled = array($ofund => array('LedgerEntry'=>array(), 'balance'=>0));
$applied = 0; $applied = 0;
// if there is no money in the entry, it can reconcile nothing // if there is no money in the entry, it can reconcile nothing
// don't bother wasting time sifting ledger entries. // don't bother wasting time sifting ledger entries.
if ($amount > 0) { if ($amount > 0) {
$unreconciled = $this->findUnreconciledLedgerEntries($id, $ofund); $unreconciled = $this->findUnreconciledLedgerEntries($id, $ofund, $cond);
foreach ($unreconciled[$ofund]['entry'] AS $i => &$entry) { foreach ($unreconciled[$ofund]['LedgerEntry'] AS $i => &$entry) {
// Determine if amount is sufficient to cover the entry // Determine if amount is sufficient to cover the entry
if ($amount > $entry['balance']) if ($amount > $entry['balance'])
$apply = $entry['balance']; $apply = $entry['balance'];
elseif ($amount > 0) elseif ($amount > 0)
$apply = $amount; $apply = $amount;
else { else {
unset($unreconciled[$ofund]['entry'][$i]); unset($unreconciled[$ofund]['LedgerEntry'][$i]);
continue; continue;
} }

View File

@@ -85,6 +85,28 @@ class LinkableBehavior extends ModelBehavior {
protected $_defaults = array('type' => 'LEFT'); protected $_defaults = array('type' => 'LEFT');
function pr($lev, $mixed) {
if ($lev >= 5)
return;
pr($mixed);
return;
$trace = debug_backtrace(false);
//array_shift($trace);
$calls = array();
foreach ($trace AS $call) {
$call = array_intersect_key($call,
array('file'=>1,
'line'=>1,
//'class'=>1,
'function'=>1,
));
$calls[] = implode("; ", $call);
}
pr(array('debug' => $mixed, 'stack' => $calls));
}
/* /*
* This is a function for made recursive str_replaces in an array * This is a function for made recursive str_replaces in an array
* NOTE: The palacement of this function is terrible, but I don't * NOTE: The palacement of this function is terrible, but I don't
@@ -108,7 +130,10 @@ class LinkableBehavior extends ModelBehavior {
} }
public function beforeFind(&$Model, $query) { public function beforeFind(&$Model, $query) {
/* pr("Linkable::beforeFind() begin"); pr($query); */ $this->pr(10,
array('function' => 'Linkable::beforeFind',
'args' => array('Model->alias' => '$Model->alias') + compact('query'),
));
if (isset($query[$this->_key])) { if (isset($query[$this->_key])) {
$optionsDefaults = $this->_defaults + array('reference' => $optionsDefaults = $this->_defaults + array('reference' =>
array('class' => $Model->alias, array('class' => $Model->alias,
@@ -132,7 +157,10 @@ class LinkableBehavior extends ModelBehavior {
unset($iterator['defaults']); unset($iterator['defaults']);
} }
$iterations = Set::normalize($iterator); $iterations = Set::normalize($iterator);
/* pr(array('checkpoint' => 'Iterations', compact('iterations'))); */ $this->pr(25,
array('checkpoint' => 'Iterations',
compact('iterations'),
));
foreach ($iterations as $alias => $options) { foreach ($iterations as $alias => $options) {
if (is_null($options)) { if (is_null($options)) {
$options = array(); $options = array();
@@ -145,7 +173,15 @@ class LinkableBehavior extends ModelBehavior {
if (empty($options['class'])) if (empty($options['class']))
$options['class'] = $alias; $options['class'] = $alias;
/* pr(array('checkpoint' => 'Begin Model Work', compact('alias', 'options'))); */ if (!isset($options['conditions']))
$options['conditions'] = array();
elseif (!is_array($options['conditions']))
$options['conditions'] = array($options['conditions']);
$this->pr(20,
array('checkpoint' => 'Begin Model Work',
compact('alias', 'options'),
));
$modelClass = $options['class']; $modelClass = $options['class'];
$modelAlias = $options['alias']; $modelAlias = $options['alias'];
@@ -154,11 +190,13 @@ class LinkableBehavior extends ModelBehavior {
$_Model =& ClassRegistry::init($modelClass); // the incoming model to be linked in query $_Model =& ClassRegistry::init($modelClass); // the incoming model to be linked in query
$Reference =& ClassRegistry::init($referenceClass); // the already in query model that links to $_Model $Reference =& ClassRegistry::init($referenceClass); // the already in query model that links to $_Model
/* pr(array('checkpoint' => 'Aliases Established', */ $this->pr(12,
/* 'Model' => ($modelAlias .' : '. $modelClass . */ array('checkpoint' => 'Aliases Established',
/* ' ('. $_Model->alias .' : '. $_Model->name .')'), */ 'Model' => ($modelAlias .' : '. $modelClass .
/* 'Reference' => ($referenceAlias .' : '. $referenceClass . */ ' ('. $_Model->alias .' : '. $_Model->name .')'),
/* ' ('. $Reference->alias .' : '. $Reference->name .')'))); */ 'Reference' => ($referenceAlias .' : '. $referenceClass .
' ('. $Reference->alias .' : '. $Reference->name .')'),
));
$db =& $_Model->getDataSource(); $db =& $_Model->getDataSource();
@@ -169,20 +207,20 @@ class LinkableBehavior extends ModelBehavior {
// a relationship if one doesn't otherwise already exists. // a relationship if one doesn't otherwise already exists.
if (($associations = $Reference->getAssociated()) && if (($associations = $Reference->getAssociated()) &&
isset($associations[$_Model->alias])) { isset($associations[$_Model->alias])) {
/* pr("Reference defines association to _Model"); */ $this->pr(12, array('checkpoint' => "Reference defines association to _Model"));
$associatedThroughReference = 1; $associatedThroughReference = 1;
$type = $associations[$_Model->alias]; $type = $associations[$_Model->alias];
$association = $Reference->{$type}[$_Model->alias]; $association = $Reference->{$type}[$_Model->alias];
} }
elseif (($associations = $_Model->getAssociated()) && elseif (($associations = $_Model->getAssociated()) &&
isset($associations[$Reference->alias])) { isset($associations[$Reference->alias])) {
/* pr("_Model defines association to Reference"); */ $this->pr(12, array('checkpoint' => "_Model defines association to Reference"));
$type = $associations[$Reference->alias]; $type = $associations[$Reference->alias];
$association = $_Model->{$type}[$Reference->alias]; $association = $_Model->{$type}[$Reference->alias];
} }
else { else {
// No relationship... make our best effort to create one. // No relationship... make our best effort to create one.
/* pr("No assocation between _Model and Reference"); */ $this->pr(12, array('checkpoint' => "No assocation between _Model and Reference"));
$type = 'belongsTo'; $type = 'belongsTo';
$_Model->bind($Reference->alias); $_Model->bind($Reference->alias);
// Grab the association now, since we'll unbind in a moment. // Grab the association now, since we'll unbind in a moment.
@@ -212,12 +250,13 @@ class LinkableBehavior extends ModelBehavior {
$associationAlias, $associationAlias,
$association['conditions']); $association['conditions']);
/* pr(array('checkpoint' => 'Models Established - Check Associations', */ $this->pr(15,
/* 'primaryModel' => $primaryAlias .' : '. $primaryModel->name, */ array('checkpoint' => 'Models Established - Check Associations',
/* 'foreignModel' => $foreignAlias .' : '. $foreignModel->name, */ 'primaryModel' => $primaryAlias .' : '. $primaryModel->name,
/* compact('type', 'association'))); */ 'foreignModel' => $foreignAlias .' : '. $foreignModel->name,
compact('type', 'association'),
));
if (empty($options['conditions'])) {
if ($type === 'hasAndBelongsToMany') { if ($type === 'hasAndBelongsToMany') {
if (isset($association['with'])) if (isset($association['with']))
$linkClass = $association['with']; $linkClass = $association['with'];
@@ -231,6 +270,11 @@ class LinkableBehavior extends ModelBehavior {
else else
$linkAlias = $Link->alias; $linkAlias = $Link->alias;
$this->pr(17,
array('checkpoint' => 'Linking HABTM',
compact('linkClass', 'linkAlias'),
));
// Get the foreign key fields (for the link table) directly from // Get the foreign key fields (for the link table) directly from
// the defined model associations, if they exists. This is the // the defined model associations, if they exists. This is the
// users direct specification, and therefore definitive if present. // users direct specification, and therefore definitive if present.
@@ -279,6 +323,11 @@ class LinkableBehavior extends ModelBehavior {
$foreignKey = $primaryModel->escapeField($association['foreignKey'], $primaryAlias); $foreignKey = $primaryModel->escapeField($association['foreignKey'], $primaryAlias);
$primaryKey = $foreignModel->escapeField($foreignModel->primaryKey, $foreignAlias); $primaryKey = $foreignModel->escapeField($foreignModel->primaryKey, $foreignAlias);
$this->pr(17,
array('checkpoint' => 'Linking due to foreignKey',
compact('foreignKey', 'primaryKey'),
));
// Only differentiating to help show the logical flow. // Only differentiating to help show the logical flow.
// Either way works and this test can be tossed out // Either way works and this test can be tossed out
if (($type === 'hasMany' || $type === 'hasOne') ^ $associatedThroughReference) if (($type === 'hasMany' || $type === 'hasOne') ^ $associatedThroughReference)
@@ -287,10 +336,20 @@ class LinkableBehavior extends ModelBehavior {
$options['conditions'][] = "{$foreignKey} = {$primaryKey}"; $options['conditions'][] = "{$foreignKey} = {$primaryKey}";
} }
else { else {
$this->pr(17,
array('checkpoint' => 'Linking with no logic (expecting user defined)',
));
// No Foreign Key... nothing we can do. // No Foreign Key... nothing we can do.
$options['conditions'] = array();
} }
$this->pr(19,
array('checkpoint' => 'Conditions',
array('options[conditions]' => $options['conditions'],
'association[conditions]' => $association['conditions'],
),
));
// The user may have specified conditions directly in the model // The user may have specified conditions directly in the model
// for this join. Make sure to adhere to those conditions. // for this join. Make sure to adhere to those conditions.
if (isset($association['conditions']) && is_array($association['conditions'])) if (isset($association['conditions']) && is_array($association['conditions']))
@@ -298,7 +357,12 @@ class LinkableBehavior extends ModelBehavior {
elseif (!empty($association['conditions'])) elseif (!empty($association['conditions']))
$options['conditions'][] = $association['conditions']; $options['conditions'][] = $association['conditions'];
} $this->pr(19,
array('checkpoint' => 'Conditions2',
array('options[conditions]' => $options['conditions'],
),
));
if (empty($options['table'])) { if (empty($options['table'])) {
$options['table'] = $db->fullTableName($_Model, true); $options['table'] = $db->fullTableName($_Model, true);
} }
@@ -312,8 +376,6 @@ class LinkableBehavior extends ModelBehavior {
(empty($association['fields']) (empty($association['fields'])
? array() : $db->fields($_Model, $modelAlias, $association['fields']))); ? array() : $db->fields($_Model, $modelAlias, $association['fields'])));
/* pr(array('checkpoint' => 'Model Work Complete', compact('options', 'modelClass', 'modelAlias'))); */
$options[$this->_key] = am($options[$this->_key], array_diff_key($options, $optionsKeys)); $options[$this->_key] = am($options[$this->_key], array_diff_key($options, $optionsKeys));
$options = array_intersect_key($options, $optionsKeys); $options = array_intersect_key($options, $optionsKeys);
if (!empty($options[$this->_key])) { if (!empty($options[$this->_key])) {
@@ -325,13 +387,20 @@ class LinkableBehavior extends ModelBehavior {
'alias' => $modelAlias)))); 'alias' => $modelAlias))));
} }
$query['joins'][] = array_intersect_key($options, array('type' => true, 'alias' => true, 'table' => true, 'joins' => true, 'conditions' => true)); $query['joins'][] = array_intersect_key($options, array('type' => true, 'alias' => true, 'table' => true, 'joins' => true, 'conditions' => true));
$this->pr(19,
array('checkpoint' => 'Model Join Complete',
compact('options', 'modelClass', 'modelAlias', 'query'),
));
} }
++$cont; ++$cont;
$notDone = isset($iterators[$cont]); $notDone = isset($iterators[$cont]);
} while ($notDone); } while ($notDone);
} }
/* pr(array('checkpoint' => 'Linkable::beforeFind() end', */ $this->pr(20,
/* compact('query'))); */ array('function' => 'Linkable::beforeFind',
'return' => compact('query'),
));
return $query; return $query;
} }
} }

View File

@@ -8,7 +8,6 @@ class Customer extends AppModel {
); );
var $belongsTo = array( var $belongsTo = array(
'Account',
'PrimaryContact' => array( 'PrimaryContact' => array(
'className' => 'Contact', 'className' => 'Contact',
), ),
@@ -20,11 +19,19 @@ class Customer extends AppModel {
'conditions' => 'CurrentLease.close_date IS NULL', 'conditions' => 'CurrentLease.close_date IS NULL',
), ),
'Lease', 'Lease',
'Transaction', 'LedgerEntry',
// Cheat to get Account set as part of this class
'Account',
); );
var $hasAndBelongsToMany = array( var $hasAndBelongsToMany = array(
'Contact', 'Contact',
'Transaction' => array(
'joinTable' => 'ledger_entries',
'foreignKey' => 'customer_id',
'associationForeignKey' => 'transaction_id',
),
); );
@@ -80,16 +87,9 @@ class Customer extends AppModel {
/* )); */ /* )); */
$entries = $this->Account->findLedgerEntriesRelatedToAccount $entries = $this->Account->findLedgerEntriesRelatedToAccount
($this->accountId($id), ($this->Account->invoiceAccountID(),
$this->Account->securityDepositAccountID(), $this->Account->securityDepositAccountID(),
true, null, $link); true, array('LedgerEntry.customer_id' => $id), $link);
foreach ($this->leaseIds($id) AS $lease_id) {
$ledger_entries = $this->Lease->findSecurityDeposits($lease_id, $link);
$this->statsMerge($entries['summary'], $ledger_entries['summary']);
$entries['Entries'] = array_merge($entries['Entries'],
$ledger_entries['Entries']);
}
/* pr(array('function' => 'Customer::findSecurityDeposits', */ /* pr(array('function' => 'Customer::findSecurityDeposits', */
/* 'args' => compact('id', 'link'), */ /* 'args' => compact('id', 'link'), */
@@ -110,22 +110,10 @@ class Customer extends AppModel {
*/ */
function findUnreconciledLedgerEntries($id = null, $fundamental_type = null) { function findUnreconciledLedgerEntries($id = null, $fundamental_type = null) {
$unreconciled = $this->Account->findUnreconciledLedgerEntries $unreconciled = $this->Account->findUnreconciledLedgerEntries
($this->accountId($id), $fundamental_type); ($this->Account->accountReceivableAccountID(),
$fundamental_type,
foreach ($this->leaseIds($id) AS $lease_id) { array('LedgerEntry.customer_id' => $id));
$unrec = $this->Lease->findUnreconciledLedgerEntries($lease_id,
$fundamental_type);
foreach (array_keys($unreconciled) AS $type) {
$left = &$unreconciled[$type];
$right = &$unrec[$type];
$left['entry'] = array_merge($left['entry'], $right['entry']);
$left['balance'] += $right['balance'];
}
}
return $unreconciled; return $unreconciled;
} }
@@ -146,25 +134,11 @@ class Customer extends AppModel {
*/ */
function reconcileNewLedgerEntry($id, $fundamental_type, $amount) { function reconcileNewLedgerEntry($id, $fundamental_type, $amount) {
$reconciled = $this->Account->reconcileNewLedgerEntry $reconciled = $this->Account->reconcileNewLedgerEntry
($this->accountId($id), $fundamental_type, $amount); ($this->Account->accountReceivableAccountID(),
foreach ($this->leaseIds($id) AS $lease_id) {
foreach (array_keys($reconciled) AS $type) {
$rec = $this->Lease->reconcileNewLedgerEntry($lease_id,
$fundamental_type, $fundamental_type,
$reconciled[$type]['unapplied']); $amount,
array('LedgerEntry.customer_id' => $id));
$left = &$reconciled[$type];
$right = &$rec[$type];
$left['entry'] = array_merge($left['entry'], $right['entry']);
$left['balance'] += $right['balance'];
$left['applied'] += $right['applied'];
$left['unapplied'] = $right['unapplied'];
}
}
return $reconciled; return $reconciled;
} }
@@ -189,7 +163,6 @@ class Customer extends AppModel {
'ContactEmail', 'ContactEmail',
'ContactAddress', 'ContactAddress',
), ),
'Account',
'Lease' => 'Lease' =>
array('Unit' => array('Unit' =>
array('order' => array('sort_order'), array('order' => array('sort_order'),
@@ -201,22 +174,12 @@ class Customer extends AppModel {
'conditions' => array('Customer.id' => $id), 'conditions' => array('Customer.id' => $id),
)); ));
// Add the lease balance to each lease. // Figure out the outstanding balance for this customer
foreach ($customer['Lease'] AS &$lease) {
$stats = $this->Lease->stats($lease['id']);
$lease['balance'] = $stats['Account']['Ledger']['balance'];
}
// Figure out the outstanding balance of the current lease.
$customer['stats'] = $this->stats($id); $customer['stats'] = $this->stats($id);
// Figure out the total security deposit for the current lease. // Figure out the total security deposit for the current lease.
$customer['deposits'] = $this->findSecurityDeposits($id); $customer['deposits'] = $this->findSecurityDeposits($id);
// Add statistics into the customer account.
$customer['Account'] = array_merge($customer['Account'],
$customer['stats']['Account']['Ledger']);
return $customer; return $customer;
} }
@@ -232,29 +195,11 @@ class Customer extends AppModel {
if (!$id) if (!$id)
return null; return null;
// Get the basic information necessary $stats = $this->Account->stats($this->Account->accountReceivableAccountID(), true,
$customer = $this->find('first', array('LedgerEntry.customer_id' => $id));
array('contain' =>
array('Account' => array
('fields' => array('Account.id')),
'Lease' => array
('fields' => array('Lease.id'))
),
'conditions' => array
(array('Customer.id' => $id))));
// Get stats from the customer account, and each lease
$stats['Account'] = $this->Account->stats($customer['Account']['id']);
foreach ($customer['Lease'] AS $lease) {
$this->statsMerge($stats['Lease'], $this->Lease->stats($lease['id']));
}
// Merge the stats from both the customer specific account, as
// well as the leases. This will provide current customer standing.
$this->statsMerge($stats, $stats['Account']['Ledger']);
$this->statsMerge($stats, $stats['Lease']['Account']['Ledger']);
// Pull to the top level and return
$stats = $stats['Ledger'];
return $stats; return $stats;
} }

View File

@@ -25,11 +25,18 @@ class Lease extends AppModel {
var $belongsTo = array( var $belongsTo = array(
'LeaseType', 'LeaseType',
'Unit', 'Unit',
'Account',
'Customer', 'Customer',
'LateSchedule', 'LateSchedule',
); );
var $hasMany = array(
'LedgerEntry',
// Cheat to get Account set as part of this class
'Account',
);
/************************************************************************** /**************************************************************************
************************************************************************** **************************************************************************
************************************************************************** **************************************************************************
@@ -37,15 +44,7 @@ class Lease extends AppModel {
* - Returns the accountId of the given lease * - Returns the accountId of the given lease
*/ */
function accountId($id) { function accountId($id) {
$this->cacheQueries = true; return $this->Account->invoiceAccountID();
$lease = $this->find('first', array
('recursive' => -1,
'fields' => array('account_id'),
'conditions' => array(array('id' => $id)),
));
$this->cacheQueries = false;
return $lease['Lease']['account_id'];
} }
@@ -61,6 +60,10 @@ class Lease extends AppModel {
/* 'args' => compact('id', 'all', 'cond', 'link'), */ /* 'args' => compact('id', 'all', 'cond', 'link'), */
/* )); */ /* )); */
if (!isset($cond))
$cond = array();
$cond[] = array('LedgerEntry.lease_id' => $id);
$entries = $this->Account->findLedgerEntries($this->accountId($id), $entries = $this->Account->findLedgerEntries($this->accountId($id),
$all, $cond, $link); $all, $cond, $link);
@@ -87,7 +90,7 @@ class Lease extends AppModel {
$entries = $this->Account->findLedgerEntriesRelatedToAccount $entries = $this->Account->findLedgerEntriesRelatedToAccount
($this->accountId($id), ($this->accountId($id),
$this->Account->securityDepositAccountID(), $this->Account->securityDepositAccountID(),
true, null, $link); true, array('LedgerEntry.lease_id' => $id), $link);
/* pr(array('function' => 'Lease::findSecurityDeposits', */ /* pr(array('function' => 'Lease::findSecurityDeposits', */
/* 'args' => compact('id', 'link'), */ /* 'args' => compact('id', 'link'), */
@@ -108,7 +111,7 @@ class Lease extends AppModel {
function findUnreconciledLedgerEntries($id = null, $fundamental_type = null) { function findUnreconciledLedgerEntries($id = null, $fundamental_type = null) {
return $this->Account->findUnreconciledLedgerEntries return $this->Account->findUnreconciledLedgerEntries
($this->accountId($id), $fundamental_type); ($this->accountId($id), $fundamental_type, array('LedgerEntry.lease_id' => $id));
} }
@@ -128,7 +131,7 @@ class Lease extends AppModel {
function reconcileNewLedgerEntry($id, $fundamental_type, $amount) { function reconcileNewLedgerEntry($id, $fundamental_type, $amount) {
return $this->Account->reconcileNewLedgerEntry return $this->Account->reconcileNewLedgerEntry
($this->accountId($id), $fundamental_type, $amount); ($this->accountId($id), $fundamental_type, $amount, array('LedgerEntry.lease_id' => $id));
} }
@@ -143,18 +146,15 @@ class Lease extends AppModel {
if (!$id) if (!$id)
return null; return null;
// Find the associated account. $stats = $this->Account->stats($this->Account->accountReceivableAccountID(), true,
$lease = $this->find('first', array('OR' => array
array('recursive' => -1, (array('LedgerEntry.lease_id' => $id),
'conditions' => array(array('Lease.id' => $id)))); array('ReconciledLedgerEntry.lease_id' => $id),
),
// Pull the stats from the account. ));
$stats['Account'] = $this->Account->stats($lease['Lease']['account_id']);
// Place a summary of the stats (one lease account in this case)
// at the top level for easy summarized access.
$this->statsMerge($stats, $stats['Account']['Ledger']);
// Pull to the top level and return
$stats = $stats['Ledger'];
return $stats; return $stats;
} }

View File

@@ -115,6 +115,9 @@ class Ledger extends AppModel {
* - Returns summary data from the requested ledger. * - Returns summary data from the requested ledger.
*/ */
function stats($id, $cond = null) { function stats($id, $cond = null) {
if (!isset($cond))
$cond = array();
$cond[] = array('Ledger.id' => $id);
$stats = $this->find $stats = $this->find
('first', array ('first', array
@@ -138,8 +141,7 @@ class Ledger extends AppModel {
) * IF(LedgerEntry.amount, LedgerEntry.amount, 0) ) * IF(LedgerEntry.amount, LedgerEntry.amount, 0)
) AS balance", ) AS balance",
"COUNT(LedgerEntry.id) AS entries"), "COUNT(LedgerEntry.id) AS entries"),
'conditions' => array(isset($cond) ? $cond : array(), 'conditions' => $cond,
array('Ledger.id' => $id)),
'group' => 'Ledger.id', 'group' => 'Ledger.id',
)); ));

View File

@@ -11,6 +11,8 @@ class LedgerEntry extends AppModel {
var $belongsTo = array( var $belongsTo = array(
'MonetarySource', 'MonetarySource',
'Transaction', 'Transaction',
'Customer',
'Lease',
'DebitLedger' => array( 'DebitLedger' => array(
'className' => 'Ledger', 'className' => 'Ledger',
@@ -23,17 +25,11 @@ class LedgerEntry extends AppModel {
); );
var $hasAndBelongsToMany = array( var $hasAndBelongsToMany = array(
'DebitReconciliationLedgerEntry' => array( 'ReconcilingTransaction' => array(
'className' => 'LedgerEntry', 'className' => 'Transaction',
'joinTable' => 'reconciliations', 'joinTable' => 'reconciliations',
'foreignKey' => 'credit_ledger_entry_id', 'foreignKey' => 'transaction_id',
'associationForeignKey' => 'debit_ledger_entry_id', 'associationForeignKey' => 'ledger_entry_id',
),
'CreditReconciliationLedgerEntry' => array(
'className' => 'LedgerEntry',
'joinTable' => 'reconciliations',
'foreignKey' => 'debit_ledger_entry_id',
'associationForeignKey' => 'credit_ledger_entry_id',
), ),
); );
@@ -84,7 +80,7 @@ class LedgerEntry extends AppModel {
return $fields; return $fields;
} }
function ledgerContextFields2($ledger_id = null, $account_type = null) { function ledgerContextFields2($ledger_id = null, $account_id = null, $account_type = null) {
$fields = array('id', 'name', 'comment', 'amount'); $fields = array('id', 'name', 'comment', 'amount');
if (isset($ledger_id)) { if (isset($ledger_id)) {
@@ -93,20 +89,29 @@ class LedgerEntry extends AppModel {
$fields[] = ("IF(LedgerEntry.credit_ledger_id = $ledger_id," . $fields[] = ("IF(LedgerEntry.credit_ledger_id = $ledger_id," .
" SUM(LedgerEntry.amount), NULL) AS credit"); " SUM(LedgerEntry.amount), NULL) AS credit");
if (isset($account_type)) { if (isset($account_id) || isset($account_type)) {
if (in_array($account_type, array('ASSET', 'EXPENSE'))) $Account = new Account();
$ledger_type = 'debit'; $account_ftype = $Account->fundamentalType($account_id ? $account_id : $account_type);
else $fields[] = ("(IF(LedgerEntry.{$account_ftype}_ledger_id = $ledger_id," .
$ledger_type = 'credit';
$fields[] = ("(IF(LedgerEntry.{$ledger_type}_ledger_id = $ledger_id," .
" 1, -1) * SUM(LedgerEntry.amount)) AS balance"); " 1, -1) * SUM(LedgerEntry.amount)) AS balance");
} }
} }
elseif (isset($account_id)) {
$fields[] = ("IF(DebitLedger.account_id = $account_id," .
" SUM(LedgerEntry.amount), NULL) AS debit");
$fields[] = ("IF(CreditLedger.account_id = $account_id," .
" SUM(LedgerEntry.amount), NULL) AS credit");
$Account = new Account();
$account_ftype = ucfirst($Account->fundamentalType($account_id));
$fields[] = ("(IF({$account_ftype}Ledger.account_id = $account_id," .
" 1, -1) * SUM(LedgerEntry.amount)) AS balance");
}
return $fields; return $fields;
} }
function ledgerContextConditions($ledger_id, $account_type) { function ledgerContextConditions($ledger_id, $account_type) {
if (isset($ledger_id)) { if (isset($ledger_id)) {
return array return array
@@ -156,36 +161,36 @@ class LedgerEntry extends AppModel {
/************************************************************************** /**************************************************************************
************************************************************************** **************************************************************************
************************************************************************** **************************************************************************
* function: findReconciledLedgerEntries * function: findReconcilingTransactions
* - Returns ledger entries that are reconciled to the given entry. * - Returns transactions that reconcile the given entry
* (such as payments towards a charge). * (such as receipts that reconcile a charge).
*/ */
function findReconciledLedgerEntries($id = null, $fundamental_type = null) { function findReconcilingTransactions($id = null, $fundamental_type = null) {
foreach (($fundamental_type foreach (($fundamental_type
? array($fundamental_type) ? array($fundamental_type)
: array('debit', 'credit')) AS $fund) { : array('debit', 'credit')) AS $fund) {
$ucfund = ucfirst($fund); $reconciled[$fund]['LedgerEntry'] = $this->find
$reconciled[$fund]['entry'] = $this->find
('all', array ('all', array
('link' => array ('link' => array
("ReconciliationLedgerEntry" => array ('ReconcilingTransaction' => array
('class' => "{$ucfund}ReconciliationLedgerEntry", ('fields' => array
'fields' => array
('id', ('id',
"COALESCE(SUM(Reconciliation.amount),0) AS 'reconciled'", "COALESCE(SUM(Reconciliation.amount),0) AS 'reconciled'",
"LedgerEntry.amount - COALESCE(SUM(Reconciliation.amount),0) AS 'balance'", //"ReconcilingTransaction.amount - COALESCE(SUM(Reconciliation.amount),0) AS 'balance'",
"COALESCE(7) AS 'balance'",
),
'conditions' => array('Reconciliation.type' => $fund),
), ),
), ),
), 'group' => ('ReconcilingTransaction.id'),
'group' => ("ReconciliationLedgerEntry.id"),
'conditions' => array('LedgerEntry.id' => $id), 'conditions' => array('LedgerEntry.id' => $id),
'fields' => array(), 'fields' => array(),
)); ));
//pr($reconciled); //pr($reconciled);
$balance = 0; $balance = 0;
foreach ($reconciled[$fund]['entry'] AS &$entry) { foreach ($reconciled[$fund]['LedgerEntry'] AS &$entry) {
$entry = array_merge($entry["ReconciliationLedgerEntry"], $entry[0]); $entry = array_merge($entry["ReconcilingTransaction"], $entry[0]);
$balance += $entry['balance']; $balance += $entry['balance'];
} }
$reconciled[$fund]['balance'] = $balance; $reconciled[$fund]['balance'] = $balance;
@@ -201,27 +206,31 @@ class LedgerEntry extends AppModel {
* function: stats * function: stats
* - Returns summary data from the requested ledger entry * - Returns summary data from the requested ledger entry
*/ */
function stats($id) { function stats($id, $cond = null) {
if (!isset($cond))
$cond = array();
$cond[] = array('LedgerEntry.id' => $id);
$query = array $query = array
( (
'link' => array('ReconcilingTransaction'),
'fields' => array("SUM(Reconciliation.amount) AS 'reconciled'"), 'fields' => array("SUM(Reconciliation.amount) AS 'reconciled'"),
'conditions' => array(isset($cond) ? $cond : array(),
array('LedgerEntry.id' => $id)),
'group' => 'LedgerEntry.id', 'group' => 'LedgerEntry.id',
); );
// Get the applied amounts on the debit side // Get the applied amounts on the debit side
$query['link'] = $qcond = $cond;
array('DebitReconciliationLedgerEntry' => array('alias' => 'DRLE', 'DRLETransaction' => array('class' => 'Transaction'))); $qcond[] = array('Reconciliation.type' => 'DEBIT');
$query['conditions'] = $qcond;
$tmpstats = $this->find('first', $query); $tmpstats = $this->find('first', $query);
$stats['debit_amount_reconciled'] = $tmpstats[0]['reconciled']; $stats['debit_amount_reconciled'] = $tmpstats[0]['reconciled'];
// Get the applied amounts on the credit side // Get the applied amounts on the credit side
$query['link'] = $qcond = $cond;
array('CreditReconciliationLedgerEntry' => array('alias' => 'CRLE', 'CRLETransaction' => array('class' => 'Transaction'))); $qcond[] = array('Reconciliation.type' => 'CREDIT');
$query['conditions'] = $qcond;
$tmpstats = $this->find('first', $query); $tmpstats = $this->find('first', $query);
$stats['credit_amount_reconciled'] = $tmpstats[0]['reconciled']; $stats['credit_amount_reconciled'] = $tmpstats[0]['reconciled'];

View File

@@ -14,6 +14,14 @@ class Transaction extends AppModel {
'LedgerEntry', 'LedgerEntry',
); );
var $hasAndBelongsToMany = array(
'ReconciledLedgerEntry' => array(
'className' => 'LedgerEntry',
'joinTable' => 'reconciliations',
'foreignKey' => 'ledger_entry_id',
'associationForeignKey' => 'transaction_id',
),
);
function beforeSave() { function beforeSave() {
@@ -24,5 +32,40 @@ class Transaction extends AppModel {
return true; return true;
} }
/**************************************************************************
**************************************************************************
**************************************************************************
* function: findReconciledLedgerEntries
* - Returns ledger entries that are reconciled by the given
* transaction (such as charges reconciled by a receipt)
*/
function findReconciledLedgerEntries($id = null) {
$reconciled['LedgerEntry'] = $this->find
('all', array
('link' => array
('ReconciledLedgerEntry' => array
('fields' => array
('id',
"COALESCE(SUM(Reconciliation.amount),0) AS 'reconciled'",
"ReconciledLedgerEntry.amount - COALESCE(SUM(Reconciliation.amount),0) AS 'balance'",
),
),
),
'group' => ('ReconciledLedgerEntry.id'),
'conditions' => array('Transaction.id' => $id),
'fields' => array(),
));
//pr($reconciled);
$balance = 0;
foreach ($reconciled['LedgerEntry'] AS &$entry) {
$entry = array_merge($entry["ReconciledLedgerEntry"], $entry[0]);
$balance += $entry['balance'];
}
$reconciled['balance'] = $balance;
return $reconciled;
}
} }
?> ?>

View File

@@ -63,12 +63,14 @@ echo $this->element('leases',
/********************************************************************** /**********************************************************************
* Account * Customer Account History
*/ */
echo $this->element('accounts', echo $this->element('ledger_entries',
array('caption' => 'Account', array('caption' => 'Account',
'accounts' => array($customer['Account']))); 'customer_id' => $customer['Customer']['id'],
'ar_account' => true,
));
/* End "detail supporting" div */ /* End "detail supporting" div */

View File

@@ -119,7 +119,7 @@ foreach ($jqGridColumns AS &$col) {
} }
elseif ($col['formatter'] === 'date') { elseif ($col['formatter'] === 'date') {
$default['formatoptions'] = array('newformat' => 'm/d/Y'); $default['formatoptions'] = array('newformat' => 'm/d/Y');
$default['width'] = 90; $default['width'] = 100;
$default['align'] = 'center'; $default['align'] = 'center';
} }
elseif ($col['formatter'] === 'name' || $col['formatter'] === 'longname') { elseif ($col['formatter'] === 'name' || $col['formatter'] === 'longname') {
@@ -143,8 +143,12 @@ foreach ($jqGridColumns AS &$col) {
} }
// Set the default sort column // Set the default sort column
if (isset($sort_column)) {
$sortname = $jqGridColumns[$sort_column];
} else {
reset($jqGridColumns); reset($jqGridColumns);
$sortname = current($jqGridColumns); $sortname = current($jqGridColumns);
}
$sortname = $sortname['index']; $sortname = $sortname['index'];
// Configure the grid setup, giving priority to user defined parameters // Configure the grid setup, giving priority to user defined parameters
@@ -185,10 +189,14 @@ $jqGrid_setup = array_merge
jQuery(document).ready(function(){ jQuery(document).ready(function(){
currencyFormatter = function(el, cellval, opts) { currencyFormatter = function(el, cellval, opts) {
if (!cellval)
return;
$(el).html(fmtCurrency(cellval)); $(el).html(fmtCurrency(cellval));
} }
idFormatter = function(el, cellval, opts) { idFormatter = function(el, cellval, opts) {
if (!cellval)
return;
$(el).html('#'+cellval); $(el).html('#'+cellval);
} }

View File

@@ -1,5 +1,37 @@
<?php /* -*- mode:PHP -*- */ <?php /* -*- mode:PHP -*- */
if (isset($account_ftype) || isset($ledger_id) || isset($lease_id) || isset($account_id) || isset($ar_account)) {
$single_account = true;
} else {
$single_account = false;
}
if (isset($ledger_id) || isset($lease_id) || isset($account_id) || isset($ar_account)) {
$single_amount = false;
} else {
$single_amount = true;
}
if (isset($lease_id) || isset($customer_id)) {
$references = false;
}
else {
$references = true;
}
if (isset($reconcile_id)) {
$applied_amount = true;
} else {
$applied_amount = false;
}
if (isset($account_ftype)) {
$subtotal_amount = false;
} else {
$subtotal_amount = true;
}
// Define the table columns // Define the table columns
$cols = array(); $cols = array();
if (0) { if (0) {
@@ -8,33 +40,49 @@ if (isset($notxgroup))
else else
$cols['Transaction'] = array('index' => 'Transaction.id', 'formatter' => 'id'); $cols['Transaction'] = array('index' => 'Transaction.id', 'formatter' => 'id');
} else { } else {
$notxgroup = true; $notxgroup = false;
$cols['Transaction'] = array('index' => 'Transaction.id', 'formatter' => 'id'); $cols['Transaction'] = array('index' => 'Transaction.id', 'formatter' => 'id');
$cols['Entry'] = array('index' => 'LedgerEntry.id', 'formatter' => 'id'); $cols['Entry'] = array('index' => 'LedgerEntry.id', 'formatter' => 'id');
} }
$cols['Date'] = array('index' => 'Transaction.stamp', 'formatter' => 'date'); $cols['Date'] = array('index' => 'Transaction.stamp', 'formatter' => 'date');
if (isset($account_ftype) || isset($ledger_id)) {
$cols['Account'] = array('index' => 'Account.name', 'formatter' => 'longname'); if ($single_account) {
$cols['Account'] = array('index' => 'Account.name', 'formatter' => 'name');
} }
else { else {
$cols['Debit Account'] = array('index' => 'DebitAccount.name', 'formatter' => 'longname'); $cols['Debit Account'] = array('index' => 'DebitAccount.name', 'formatter' => 'name');
$cols['Credit Account'] = array('index' => 'CreditAccount.name', 'formatter' => 'longname'); $cols['Credit Account'] = array('index' => 'CreditAccount.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['Source'] = array('index' => 'MonetarySource.name', 'formatter' => 'name');
$cols['Comment'] = array('index' => 'LedgerEntry.comment', 'formatter' => 'comment', 'width'=>150); $cols['Comment'] = array('index' => 'LedgerEntry.comment', 'formatter' => 'comment', 'width'=>150);
if (isset($ledger_id)) {
if ($single_amount) {
$cols['Amount'] = array('index' => 'LedgerEntry.amount', 'formatter' => 'currency');
}
else {
$cols['Debit'] = array('index' => 'debit', 'formatter' => 'currency'); $cols['Debit'] = array('index' => 'debit', 'formatter' => 'currency');
$cols['Credit'] = array('index' => 'credit', 'formatter' => 'currency'); $cols['Credit'] = array('index' => 'credit', 'formatter' => 'currency');
} }
else {
$cols['Amount'] = array('index' => 'LedgerEntry.amount', 'formatter' => 'currency'); if ($applied_amount) {
}
if (isset($reconcile_id)) {
$cols['Applied'] = array('index' => "Reconciliation.amount", 'formatter' => 'currency'); $cols['Applied'] = array('index' => "Reconciliation.amount", 'formatter' => 'currency');
} }
$custom_post_data = compact('ledger_id', 'account_type', 'account_ftype', 'notxgroup'); if ($subtotal_amount) {
$cols['Sub-Total'] = array('index' => 'subtotal', 'formatter' => 'currency', 'sortable' => false);
}
$custom_post_data = compact('ledger_id', 'account_id', 'ar_account',
'account_type', 'account_ftype',
'customer_id', 'lease_id', 'transaction_id', 'notxgroup');
$jqGrid_options = array('jqGridColumns' => $cols, $jqGrid_options = array('jqGridColumns' => $cols,
'controller' => 'ledger_entries', 'controller' => 'ledger_entries',
@@ -42,11 +90,6 @@ $jqGrid_options = array('jqGridColumns' => $cols,
$jqGrid_options += compact('grid_div_id', 'grid_id', 'caption', 'grid_setup', 'limit'); $jqGrid_options += compact('grid_div_id', 'grid_id', 'caption', 'grid_setup', 'limit');
if (isset($ledger_id)) {
$jqGrid_options += array('action' => 'ledger',
'limit' => 50);
}
if (isset($ledger_entries)) { if (isset($ledger_entries)) {
$jqGrid_options += array('custom_ids' => $jqGrid_options += array('custom_ids' =>
array_map(create_function('$data', array_map(create_function('$data',
@@ -54,6 +97,10 @@ if (isset($ledger_entries)) {
$ledger_entries), $ledger_entries),
'limit' => 10); 'limit' => 10);
} }
else {
$jqGrid_options += array('action' => 'ledger',
'limit' => 50);
}
if (isset($reconcile_id)) { if (isset($reconcile_id)) {
$custom_post_data += compact('reconcile_id'); $custom_post_data += compact('reconcile_id');
@@ -61,5 +108,6 @@ if (isset($reconcile_id)) {
} }
$jqGrid_options += compact('custom_post_data'); $jqGrid_options += compact('custom_post_data');
$jqGrid_options['sort_column'] = 'Date';
echo $this->element('jqGrid', $jqGrid_options); echo $this->element('jqGrid', $jqGrid_options);

View File

@@ -1,17 +1,38 @@
<?php /* -*- mode:PHP -*- */ <?php /* -*- mode:PHP -*- */
if (isset($reconcile_ledger_entry_id)) {
$applied_amount = true;
} else {
$applied_amount = false;
}
$subtotal_amount = false;
// Define the table columns // Define the table columns
$cols = array(); $cols = array();
$cols['ID'] = array('index' => 'Transaction.id', 'formatter' => 'id'); $cols['ID'] = array('index' => 'Transaction.id', 'formatter' => 'id');
//$cols['Customer'] = array('index' => 'Customer.name', 'formatter' => 'longname'); //$cols['Customer'] = array('index' => 'Customer.name', 'formatter' => 'longname');
$cols['Timesamp'] = array('index' => 'Transaction.stamp', 'formatter' => 'date'); $cols['Timestamp'] = array('index' => 'Transaction.stamp', 'formatter' => 'date');
$cols['Through'] = array('index' => 'Transaction.through_date', 'formatter' => 'date'); $cols['Through'] = array('index' => 'Transaction.through_date', 'formatter' => 'date');
$cols['Due'] = array('index' => 'Transaction.due_date', 'formatter' => 'date'); $cols['Due'] = array('index' => 'Transaction.due_date', 'formatter' => 'date');
$cols['Comment'] = array('index' => 'Transaction.comment', 'formatter' => 'comment'); $cols['Comment'] = array('index' => 'Transaction.comment', 'formatter' => 'comment');
if ($applied_amount) {
$cols['Applied'] = array('index' => "Reconciliation.amount", 'formatter' => 'currency');
}
if ($subtotal_amount) {
$cols['Sub-Total'] = array('index' => 'subtotal', 'formatter' => 'currency', 'sortable' => false);
}
$jqGrid_options = array('jqGridColumns' => $cols, $jqGrid_options = array('jqGridColumns' => $cols,
'controller' => 'transactions', 'controller' => 'transactions',
'caption' => isset($caption) ? $caption : null); );
$jqGrid_options += compact('grid_div_id', 'grid_id', 'caption', 'grid_setup', 'limit');
$custom_post_data = compact('reconcile_type', 'reconcile_ledger_entry_id');
if (isset($transactions)) { if (isset($transactions)) {
$jqGrid_options += array('custom_ids' => $jqGrid_options += array('custom_ids' =>
@@ -20,8 +41,14 @@ if (isset($transactions)) {
$transactions), $transactions),
'limit' => 5); 'limit' => 5);
} }
elseif (isset($reconcile_ledger_entry_id)) {
$jqGrid_options += array('limit' => 5);
}
else { else {
$jqGrid_options += array('search_fields' => array('Due', 'Comment')); $jqGrid_options += array('search_fields' => array('Due', 'Comment'));
} }
$jqGrid_options += compact('custom_post_data');
$jqGrid_options['sort_column'] = 'Timestamp';
echo $this->element('jqGrid', $jqGrid_options); echo $this->element('jqGrid', $jqGrid_options);

View File

@@ -11,7 +11,6 @@ echo '<div class="lease view">' . "\n";
$lease_type = $lease['LeaseType']; $lease_type = $lease['LeaseType'];
$customer = $lease['Customer']; $customer = $lease['Customer'];
$account = $lease['Account'];
$unit = $lease['Unit']; $unit = $lease['Unit'];
if (isset($lease['Lease'])) if (isset($lease['Lease']))
@@ -20,7 +19,7 @@ if (isset($lease['Lease']))
$rows = array(array('ID', $lease['id']), $rows = array(array('ID', $lease['id']),
array('Number', $lease['number']), array('Number', $lease['number']),
array('Lease Type', $lease_type['name']), array('Lease Type', $lease_type['name']),
array('Unit', $html->link($unit['id'], array('Unit', $html->link($unit['name'],
array('controller' => 'units', array('controller' => 'units',
'action' => 'view', 'action' => 'view',
$unit['id']))), $unit['id']))),
@@ -36,10 +35,6 @@ $rows = array(array('ID', $lease['id']),
array('Notice Given', FormatHelper::date($lease['notice_given_date'], true)), array('Notice Given', FormatHelper::date($lease['notice_given_date'], true)),
array('Notice Received', FormatHelper::date($lease['notice_received_date'], true)), array('Notice Received', FormatHelper::date($lease['notice_received_date'], true)),
array('Closed', FormatHelper::date($lease['close_date'], true)), array('Closed', FormatHelper::date($lease['close_date'], true)),
array('Account', $html->link($account['name'],
array('controller' => 'accounts',
'action' => 'view',
$account['id']))),
array('Deposit', FormatHelper::currency($lease['deposit'])), array('Deposit', FormatHelper::currency($lease['deposit'])),
array('Rent', FormatHelper::currency($lease['amount'])), array('Rent', FormatHelper::currency($lease['amount'])),
array('Comment', $lease['comment'])); array('Comment', $lease['comment']));
@@ -53,7 +48,7 @@ echo $this->element('table',
/********************************************************************** /**********************************************************************
* Account Info Box * Lease Info Box
*/ */
echo '<div class="infobox">' . "\n"; echo '<div class="infobox">' . "\n";
@@ -80,15 +75,16 @@ echo '<div CLASS="detail supporting">' . "\n";
/********************************************************************** /**********************************************************************
* Current Ledger * Lease Account History
*/ */
echo $this->element('ledger_entries', echo $this->element('ledger_entries',
array('caption' => "Current Ledger: (#{$account['id']}-{$account['CurrentLedger']['sequence']})", array('caption' => 'Account',
'ledger_id' => $account['CurrentLedger']['id'], 'lease_id' => $lease['id'],
'account_type' => $account['type'], //'ar_account' => true,
)); ));
/* End "detail supporting" div */ /* End "detail supporting" div */
echo '</div>' . "\n"; echo '</div>' . "\n";

View File

@@ -13,6 +13,8 @@ $transaction = $entry['Transaction'];
$debit_ledger = $entry['DebitLedger']; $debit_ledger = $entry['DebitLedger'];
$credit_ledger = $entry['CreditLedger']; $credit_ledger = $entry['CreditLedger'];
$source = $entry['MonetarySource']; $source = $entry['MonetarySource'];
$customer = $entry['Customer'];
$lease = $entry['Lease'];
$entry = $entry['LedgerEntry']; $entry = $entry['LedgerEntry'];
$rows = array(array('ID', $entry['id']), $rows = array(array('ID', $entry['id']),
@@ -21,8 +23,20 @@ $rows = array(array('ID', $entry['id']),
'action' => 'view', 'action' => 'view',
$transaction['id']))), $transaction['id']))),
array('Timestamp', FormatHelper::datetime($transaction['stamp'])), array('Timestamp', FormatHelper::datetime($transaction['stamp'])),
array('Monetary Source', (isset($source['id']) array('Customer', (isset($customer['name'])
? $html->link('#'.$source['id'], ? $html->link($customer['name'],
array('controller' => 'customers',
'action' => 'view',
$customer['id']))
: null)),
array('Lease', (isset($lease['id'])
? $html->link('#'.$lease['id'],
array('controller' => 'leases',
'action' => 'view',
$lease['id']))
: null)),
array('Monetary Source', (isset($source['name'])
? $html->link($source['name'],
array('controller' => 'monetary_sources', array('controller' => 'monetary_sources',
'action' => 'view', 'action' => 'view',
$source['id'])) $source['id']))
@@ -97,26 +111,23 @@ echo '<div CLASS="detail supporting">' . "\n";
* Reconciliation Ledger Entries * Reconciliation Ledger Entries
*/ */
echo $this->element('ledger_entries', if ($debit_ledger['Account']['trackable']) {
array('caption' => "Debit Applications", echo $this->element('transactions',
array('caption' => "Payments Received",
'grid_div_id' => 'debit_reconciliation_ledger_entries', 'grid_div_id' => 'debit_reconciliation_ledger_entries',
//'ledger_id' => $debit_ledger['id'], 'reconcile_type' => 'debit',
//'account_type' => $debit_ledger['Account']['type'], 'reconcile_ledger_entry_id' => $entry['id'],
'account_ftype' => 'debit',
'reconcile_id' => $entry['id'],
'ledger_entries' => $reconciled['debit']['entry'],
)); ));
}
echo $this->element('ledger_entries', if ($credit_ledger['Account']['trackable']) {
array('caption' => "Credit Applications", echo $this->element('transactions',
array('caption' => "Charges Paid",
'grid_div_id' => 'credit_reconciliation_ledger_entries', 'grid_div_id' => 'credit_reconciliation_ledger_entries',
//'ledger_id' => $credit_ledger['id'], 'reconcile_type' => 'credit',
//'account_type' => $credit_ledger['Account']['type'], 'reconcile_ledger_entry_id' => $entry['id'],
//'account_ftype' => 'debit', // Looking for debits to match this credit
'account_ftype' => 'credit',
'reconcile_id' => $entry['id'],
'ledger_entries' => $reconciled['credit']['entry'],
)); ));
}
/* End "detail supporting" div */ /* End "detail supporting" div */

View File

@@ -54,7 +54,8 @@ echo '<div CLASS="detail supporting">' . "\n";
echo $this->element('ledger_entries', echo $this->element('ledger_entries',
array('caption' => 'Entries in Transaction', array('caption' => 'Entries in Transaction',
'ledger_entries' => $transaction['LedgerEntry'], //'ledger_entries' => $transaction['LedgerEntry'],
'transaction_id' => $transaction['Transaction']['id'],
'notxgroup' => true, 'notxgroup' => true,
)); ));

View File

@@ -57,16 +57,16 @@ echo $this->element('leases',
/********************************************************************** /**********************************************************************
* Ledger History * Current Tenant Lease Account History
*/ */
/* foreach($unit['Lease'] AS $lease) { */
/* pr($lease); */ echo $this->element('ledger_entries',
/* $caption = 'Lease #'.$lease['number'].' (Tenant: '.$lease['Customer']['name'].')'; */ array('caption' => ('Current Lease Account (' .
/* echo $this->element('lease', */ $unit['CurrentLease']['Customer']['name']
/* array('caption' => $caption, */ . ')'),
/* 'entries' => $lease['Customer']['Transaction'], */ 'ar_account' => true,
/* 'ledger' => array('mix'=>1))); */ 'lease_id' => $unit['CurrentLease']['id'],
/* } */ ));
/* End "detail supporting" div */ /* End "detail supporting" div */

View File

@@ -68,6 +68,8 @@ table.detail { width : 60%;
float : left; } float : left; }
table.detail td.field { width : 10em; } table.detail td.field { width : 10em; }
table.item.detail td.value { white-space : normal; }
div.detail.supporting { clear : both; div.detail.supporting { clear : both;
padding-top: 1.5em; } padding-top: 1.5em; }