Major change to invoice/receipt algorithms. The end result shouldn't be visible, but there were significant problems understanding how to reconcile entries and this cleaned things up significantly. There may be some bugs left, but quick tests show it to be working

git-svn-id: file:///svn-source/pmgr/branches/charge_credit_20090629@190 97e9348a-65ac-dc4b-aefc-98561f571b83
This commit is contained in:
abijah
2009-06-30 17:52:43 +00:00
parent 1c8cc70a28
commit 0b69e065ae

View File

@@ -696,10 +696,6 @@ foreach $row (@{query($sdbh, $query)}) {
$newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'id'} =
$newdb{'tables'}{'contacts'}{'autoid'};
$newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'account_id'} =
$newdb{'lookup'}{'account'}{'A/R'}{'account_id'};
$newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'ledger_id'} =
$newdb{'lookup'}{'account'}{'A/R'}{'ledger_id'};
addRow('customers',
{ 'name' => "$row->{'LastName'}, $row->{'FirstName'}",
@@ -818,19 +814,15 @@ foreach $row (@{query($sdbh, $query)}) {
$newdb{'lookup'}{'ledger'} = {};
$query = "SELECT L.*, A.TenantID FROM TenantLedger L LEFT JOIN `Access` A ON A.LedgerID = L.LedgerID WHERE L.UnitID <> 'POS\$' ORDER BY L.LedgerID";
$query = "SELECT L.*, A.TenantID FROM TenantLedger L LEFT JOIN `Access` A ON A.LedgerID = L.LedgerID WHERE L.UnitID <> 'POS\$' ORDER BY L.DateIn";
foreach $row (@{query($sdbh, $query)}) {
$newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}
= { 'customer_id' => $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'customer_id'} };
$newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'account_id'}
= $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'account_id'};
$newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'ledger_id'}
= $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'ledger_id'};
addRow('leases',
{ 'number' => $row->{'LedgerID'},
{ #'number' => $newdb{'tables'}{'leases'}{'autoid'}+1,
'number' => $row->{'LedgerID'},
'lease_type_id' => $newdb{'tables'}{'lease_types'}{'autoid'},
'unit_id' => $newdb{'lookup'}{'unit'}{$row->{'UnitID'}}{'id'},
'customer_id' => $newdb{'lookup'}{'tenant'}{$row->{'TenantID'}}{'customer_id'},
@@ -857,49 +849,78 @@ foreach $row (@{query($sdbh, $query)}) {
##
######################################################################
## Charges
## Invoices
$newdb{'lookup'}{'charge'} = {};
$query = "SELECT * FROM Charges ORDER BY ChargeID";
$query = "SELECT *, ChargeAmount+TaxAmount AS InvoiceAmount FROM Charges ORDER BY ChargeID";
foreach $row (@{query($sdbh, $query)}) {
my $credit_ledger_id;
my $ledger_entry_id;
addRow('transactions',
{ 'stamp' => datefmt($row->{'ChargeDate'}),
'through_date' => datefmt($row->{'EndDate'}) });
$newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}
= { 'tx' => $newdb{'tables'}{'transactions'}{'autoid'},
'ledger_id' => $newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'ledger_id'},
#'ledger_id' => $newdb{'lookup'}{'account'}{'Invoice'}{'ledger_id'},
'amount' => $row->{'ChargeAmount'},
'tax_amount' => $row->{'TaxAmount'},
'customer_id' => $newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'customer_id'},
= { 'invoice' =>
{ 'tx' => $newdb{'tables'}{'transactions'}{'autoid'},
'lease_id' => $newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'lease_id'},
};
'customer_id' => $newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'customer_id'},
'amount' => $row->{'InvoiceAmount'},
} };
$credit_ledger_id = $newdb{'lookup'}{'charge_type'}{$row->{'ChargeDescription'}}{'ledger_id'};
if ($use_ir) {
# Invoice must debit the A/R ledger...
$newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'invoice'}{'debit_ledger_id'}
= $newdb{'lookup'}{'account'}{'A/R'}{'ledger_id'};
# ...and credit the Invoice ledger.
$newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'invoice'}{'credit_ledger_id'}
= $newdb{'lookup'}{'account'}{'Invoice'}{'ledger_id'};
# Create the invoice entry
# debit: A/R credit: Invoice
addRow('ledger_entries',
{ 'monetary_source_id' => $newdb{'ids'}{'monetary_source'}{'internal'},
'transaction_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'tx'},
'debit_ledger_id' => $newdb{'lookup'}{'account'}{'Invoice'}{'ledger_id'},
'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'},
'comment' => "Charge: $row->{'ChargeID'}; Ledger: $row->{'LedgerID'}" });
$ledger_entry_id = $newdb{'tables'}{'ledger_entries'}{'autoid'};
$credit_ledger_id = $newdb{'lookup'}{'account'}{'Invoice'}{'ledger_id'};
'transaction_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'invoice'}{'tx'},
'debit_ledger_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'invoice'}{'debit_ledger_id'},
'credit_ledger_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'invoice'}{'credit_ledger_id'},
'customer_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'invoice'}{'customer_id'},
'lease_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'invoice'}{'lease_id'},
'amount' => $row->{'InvoiceAmount'},
'comment' => "Invoice: Charge: $row->{'ChargeID'}" });
$newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'invoice'}{'ledger_entry_id'}
= $newdb{'tables'}{'ledger_entries'}{'autoid'};
}
######################################################################
## Charges
$query = "SELECT * FROM Charges ORDER BY ChargeID";
foreach $row (@{query($sdbh, $query)}) {
$newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'tx'}
= $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'invoice'}{'tx'};
$newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'customer_id'}
= $newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'customer_id'};
$newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'lease_id'}
= $newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'lease_id'};
# Charge must credit the invoice ledger...
$newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'credit_ledger_id'}
= $newdb{'lookup'}{'charge_type'}{$row->{'ChargeDescription'}}{'ledger_id'};
# ...and debit the A/R ledger.
$newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'debit_ledger_id'}
= $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'invoice'}{'credit_ledger_id'};
# Add the charge entry
# debit: Invoice credit: Rent/LateCharge/Etc
addRow('ledger_entries',
{ '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_id'},
'credit_ledger_id' => $credit_ledger_id,
'debit_ledger_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'debit_ledger_id'},
'credit_ledger_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'credit_ledger_id'},
'customer_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'customer_id'},
'lease_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'lease_id'},
'amount' => $row->{'ChargeAmount'},
@@ -908,58 +929,47 @@ foreach $row (@{query($sdbh, $query)}) {
$newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'ledger_entry_id'}
= $newdb{'tables'}{'ledger_entries'}{'autoid'};
if ($use_ir) {
# Reconcile the invoice account. Since this is from the perspective
# of the invoice, the entry crediting the charge is the debit, and
# the entry debiting A/R is the credit.
# Reconcile the Invoice account. Our two entries look like:
# debit: Invoice credit: Rent/LateCharge/Etc
# debit: A/R credit: Invoice
# Since this is from the perspective of the Invoice account,
# the credit entry is the Invoice<->A/R, and the debit
# entry is the actual charge ledger entry.
addRow('reconciliations',
{ 'debit_ledger_entry_id' => $ledger_entry_id,
'credit_ledger_entry_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'ledger_entry_id'},
{ 'debit_ledger_entry_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'ledger_entry_id'},
'credit_ledger_entry_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'invoice'}{'ledger_entry_id'},
'amount' => $row->{'ChargeAmount'},
});
}
next unless $row->{'TaxAmount'};
$credit_ledger_id = $newdb{'lookup'}{'charge_type'}{'Tax'}{'ledger_id'};
if ($use_ir) {
# Add the tax charge entry
# debit: Invoice credit: Tax
addRow('ledger_entries',
{ 'monetary_source_id' => $newdb{'ids'}{'monetary_source'}{'internal'},
'transaction_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'tx'},
'debit_ledger_id' => $newdb{'lookup'}{'account'}{'Invoice'}{'ledger_id'},
'credit_ledger_id' => $credit_ledger_id,
'debit_ledger_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'debit_ledger_id'},
'credit_ledger_id' => $newdb{'lookup'}{'account'}{'Tax'}{'ledger_id'},
'customer_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'customer_id'},
'lease_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'lease_id'},
'amount' => $row->{'TaxAmount'},
'comment' => undef });
$ledger_entry_id = $newdb{'tables'}{'ledger_entries'}{'autoid'};
$credit_ledger_id = $newdb{'lookup'}{'account'}{'Invoice'}{'ledger_id'};
}
'comment' => "Tax for ChargeID:$row->{'ChargeID'}" });
addRow('ledger_entries',
{ '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_id'},
'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'},
'comment' => undef });
$newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'tax_entry'}
$newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'tax_ledger_entry_id'}
= $newdb{'tables'}{'ledger_entries'}{'autoid'};
if ($use_ir) {
# Reconcile the invoice account. Since this is from the perspective
# of the invoice, the entry crediting the charge is the debit, and
# the entry debiting A/R is the credit.
# Reconcile the Invoice account. Our two entries look like:
# debit: Invoice credit: Tax
# debit: A/R credit: Invoice
# Since this is from the perspective of the Invoice account,
# the credit entry is the Invoice<->A/R, and the debit
# entry is the actual tax ledger entry.
addRow('reconciliations',
{ 'debit_ledger_entry_id' => $ledger_entry_id,
'credit_ledger_entry_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'tax_entry'},
{ 'debit_ledger_entry_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'tax_ledger_entry_id'},
'credit_ledger_entry_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'invoice'}{'ledger_entry_id'},
'amount' => $row->{'TaxAmount'},
});
}
}
######################################################################
@@ -967,42 +977,168 @@ foreach $row (@{query($sdbh, $query)}) {
$newdb{'lookup'}{'receipt'} = {};
############################################################
############################################################
############################################################
# REVISIT <AP> 20090630
# Handling of receipts is all backwards. The way things
# _should_ look if someone provides Cash and Check to pay
# rent & tax for two units (50 on UnitA and 40 UnitB):
#
# RENT TAX INVOICE A/R RECEIPT CASH CHECK
# ------- ------- ------- ------- ------- ------- -------
# |50 | 50| | | | |
# | | 5 5| | | | |
# | | |55 55| | | |
# |40 | 40| | | | |
# | | 4 4| | | | |
# | | |44 44| | | |
# | | | | |79 | 79|
# | | | | |20 20| |
# | | | |99 99| | |
# | | | | | | |
#
# HOWEVER,
# Our current implementation MUST match LedgerEntry to
# LedgerEntry for reconcile purposes. Thus, although there
# is a way to reconcile that $50 was received, there is no
# way to flag the payment as being for UnitA, unless we
# either rely on the charge to determine the fact (a
# solution that has proven very messy), or we add it to
# the reconciliations table. The hope, for simplicity's
# sake, was to ensure there was a single ledger entry in
# A/R for each payment that could correspond to a lease/unit,
# so that no A/R ledger entry ever represented payment for
# more than one lease. However, to do so, our ledgers
# appear like this instead:
#
# RENT TAX INVOICE A/R RECEIPT CASH CHECK
# ------- ------- ------- ------- ------- ------- -------
# |50 | 50| | | | |
# | | 5 5| | | | |
# | | |55 55| | | |
# |40 | 40| | | | |
# | | 4 4| | | | |
# | | |44 44| | | |
# | | | | |79 | 79|
# | | | | |20 20| |
# | | | |50 50| | |
# | | | | 5 5| | |
# | | | |40 40| | |
# | | | | 4 4| | |
# | | | | | | |
#
# There is another possible solution, although it is
# very probably ledger overkill (even invoice/receipt
# already fall into the overkill category).
#
# RENT TAX INVOICE A/R MERGE RECEIPT CASH CHECK
# ------- ------- ------- ------- ------- ------- ------- -------
# |50 | 50| | | | | |
# | | 5 5| | | | | |
# | | |55 55| | | | |
# |40 | 40| | | | | |
# | | 4 4| | | | | |
# | | |44 44| | | | |
# | | | | | |79 | 79|
# | | | | | |20 20| |
# | | | | |50 50| | |
# | | | | | 5 5| | |
# | | | | |40 40| | |
# | | | | | 4 4| | |
# | | | |99 99| | | |
# | | | | | | | |
#
# I might opt for this last option, but ultimately, none
# of these are really correct. We need a better solution.
# Until then, I'll go with the easiest.
############################################################
############################################################
############################################################
# Sitelink splits one physical payment into multiple "payments" to match each charge.
# The solution here is kludgy, but for our cases at least, it brings those pseudo-payments
# back into a single one. This presumes there is only one PaymentType per receipt.
$query =
"SELECT R.ReceiptNum, C.LedgerID, R.ReceiptDate" .
" FROM Receipts R, Payments P, Charges C" .
"SELECT R.ReceiptNum, R.ReceiptDate, P.PaymentType, P.CheckNum, SUM(P.PaymentAmount) AS ReceiptAmount" .
" FROM Receipts R, Payments P" .
" WHERE P.ReceiptNum = R.ReceiptNum" .
" AND C.ChargeID = P.ChargeID" .
" GROUP BY R.ReceiptNum, C.LedgerID, R.ReceiptDate" .
" ORDER BY R.ReceiptNum";
" GROUP BY R.ReceiptNum, R.ReceiptDate, P.PaymentType, P.CheckNum" .
" ORDER BY R.ReceiptNum, P.PaymentType";
foreach $row (@{query($sdbh, $query)}) {
if ($newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}) {
die unless ($newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{'customer_id'}
== $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{'customer_id'});
push(@{$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{'ledgers'}},
$newdb{'lookup'}{'ledger'}{$row->{'LedgerID'}}{'ledger_id'});
#print Dumper $receipt_map{$row->{'ReceiptNum'}};
next;
}
# if ($newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'ledger_entry_id'}) {
# next;
# }
if (!$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}) {
addRow('transactions',
{ 'stamp' => datefmt($row->{'ReceiptDate'}),
'through_date' => undef });
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}
= {'tx' => $newdb{'tables'}{'transactions'}{'autoid'},
# NOTE: Use of 'lease_id' would be invalid, since the
# 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'} ] };
= {'tx' => $newdb{'tables'}{'transactions'}{'autoid'} };
}
if ($row->{'ReceiptDate'} =~ m%3/25/2009%) {
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'monetary_source_id'}
= $newdb{'ids'}{'monetary_source'}{'Closing'};
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'account_name'}
= 'Bank';
}
else {
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'monetary_source_id'}
= $newdb{'ids'}{'monetary_source'}{
$newdb{'lookup'}{'payment_type'}{$row->{'PaymentType'}}{'name'}
};
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'account_name'}
= $newdb{'lookup'}{'payment_type'}{$row->{'PaymentType'}}{'account_name'};
}
# Set up a monetary source for the receipt,
if (!$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'monetary_source_id'}) {
my $name = $newdb{'lookup'}{'payment_type'}{$row->{'PaymentType'}}{'name'};
if ($name eq 'Check') {
$name = 'Check #' . $row->{'CheckNum'};
}
addRow('monetary_sources',
{ 'monetary_type_id' => $newdb{'lookup'}{'payment_type'}{$row->{'PaymentType'}}{'monetary_type'}{'id'},
'name' => $name,
'comment' => "Receipt:$row->{'ReceiptNum'}; Payment:$row->{'PaymentType'}; Check:$row->{'CheckNum'}" });
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'monetary_source_id'}
= $newdb{'tables'}{'monetary_sources'}{'autoid'};
}
# Receipt must debit the "money" asset (bank, cash, check, etc)...
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'debit_ledger_id'}
= $newdb{'lookup'}{'account'}{
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'account_name'}
}{'ledger_id'};
# ...and credit the Receipt ledger
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'credit_ledger_id'}
= $newdb{'lookup'}{'account'}{'Receipt'}{'ledger_id'};
# NOTE THE ABOVE LARGE COMMENT BLOCK
# The choice of credit/debit ledgers does not mirror the
# choices for invoice. This _should_ be A/R to Receipt,
# but it is Money to Receipt instead.
# debit: Cash/Check/Etc credit: Receipt
addRow('ledger_entries',
{ 'monetary_source_id' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'monetary_source_id'},
'transaction_id' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{'tx'},
'debit_ledger_id' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'debit_ledger_id'},
'credit_ledger_id' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'credit_ledger_id'},
'amount' => $row->{'ReceiptAmount'},
'comment' => "Receipt: $row->{'ReceiptNum'}; " });
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'ledger_entry_id'}
= $newdb{'tables'}{'ledger_entries'}{'autoid'};
}
# sub idkeys { [ sort( {$a <=> $b} keys(%{$_[0]})) ] }
# $Data::Dumper::Sortkeys = \&idkeys;
######################################################################
## Payments
@@ -1014,114 +1150,65 @@ foreach $row (@{query($sdbh, $query)})
{
$newdb{'lookup'}{'payment'}{$row->{'PaymentID'}} = {};
if ($row->{'PaymentDate'} =~ m%3/25/2009%) {
$newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'monetary_source_id'}
= $newdb{'ids'}{'monetary_source'}{'Closing'};
$newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'account_name'}
= 'Bank';
}
else {
$newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'monetary_source_id'}
= $newdb{'ids'}{'monetary_source'}{
$newdb{'lookup'}{'payment_type'}{$row->{'PaymentType'}}{'name'}
};
$newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'account_name'}
= $newdb{'lookup'}{'payment_type'}{$row->{'PaymentType'}}{'account_name'};
}
# NOTE THE ABOVE LARGE COMMENT BLOCK
# The choice of credit/debit ledgers does not mirror the
# choices for charges. This _should_ be Money to Receipt,
# but it is A/R to Receipt instead.
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',
{ 'monetary_type_id' => $newdb{'lookup'}{'payment_type'}{$row->{'PaymentType'}}{'monetary_type'}{'id'},
'name' => $name,
'comment' => "Payment: $row->{'PaymentID'}; Type: $row->{'PaymentType'}; Check: $row->{'CheckNum'}; $row->{'Memo'}" });
$newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'monetary_source_id'}
= $newdb{'tables'}{'monetary_sources'}{'autoid'};
}
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'monetary_source_id'}
= $newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'monetary_source_id'};
}
$newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'credit_ledger_id'}
= $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'ledger_id'};
$newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'debit_ledger_id'}
= $newdb{'lookup'}{'account'}{
$newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'account_name'}
}{'ledger_id'};
if ($use_ir) {
addRow('ledger_entries',
{ #'monetary_source_id' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'monetary_source_id'},
'transaction_id' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{'tx'},
'debit_ledger_id' => $newdb{'lookup'}{'account'}{'Receipt'}{'ledger_id'},
'credit_ledger_id' => $newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'credit_ledger_id'},
'customer_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'customer_id'},
'lease_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'lease_id'},
'amount' => $row->{'PaymentAmount'},
'comment' => "Receipt: $row->{'ReceiptNum'}; " });
# Ensure Receipt has the right customer
$newdb{'tables'}{'ledger_entries'}{'rows'}[
$newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'ledger_entry_id'}
= $newdb{'tables'}{'ledger_entries'}{'autoid'};
$newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'credit_ledger_id'}
= $newdb{'lookup'}{'account'}{'Receipt'}{'ledger_id'};
}
]{'customer_id'} = $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'customer_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'}{'payment'}{$row->{'PaymentID'}}{'ledger_entry_id'}) {
# Payment must debit the associated receipt ledger (which should be Receipt)...
$newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'debit_ledger_id'}
= $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'credit_ledger_id'};
# ...and credit the A/R ledger.
$newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'credit_ledger_id'}
= $newdb{'lookup'}{'account'}{'A/R'}{'ledger_id'};
# Add the payment entry
# debit: Receipt credit: A/R
addRow('ledger_entries',
{ 'monetary_source_id' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'monetary_source_id'},
{ 'monetary_source_id' => $newdb{'ids'}{'monetary_source'}{'internal'},
'transaction_id' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{'tx'},
'debit_ledger_id' => $newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'debit_ledger_id'},
'credit_ledger_id' => $newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'credit_ledger_id'},
'customer_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'customer_id'},
#'lease_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'lease_id'},
'amount' => 0,
'lease_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'lease_id'},
'amount' => $row->{'PaymentAmount'},
'comment' => "Receipt: $row->{'ReceiptNum'}; Charge: $row->{'ChargeID'}; Payment: $row->{'PaymentID'}" });
$newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'ledger_entry_id'}
= $newdb{'tables'}{'ledger_entries'}{'autoid'};
}
$newdb{'tables'}{'ledger_entries'}{'rows'}[
$newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'ledger_entry_id'}
]{'amount'} += $row->{'PaymentAmount'};
$newdb{'tables'}{'ledger_entries'}{'rows'}[
$newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'ledger_entry_id'}
]{'comment'} .= 'P:'.$row->{'PaymentID'} . '-&gt;C:' . $row->{'ChargeID'} . '; ';
if ($use_ir) {
# Reconcile the invoice account. Since this is from the perspective
# of the invoice, the entry crediting the charge is the debit, and
# the entry debiting A/R is the credit.
# Reconcile the Receipt account. Our two entries look like:
# debit: Cash/Check/Etc credit: Receipt
# debit: Receipt credit: A/R
# Since this is from the perspective of the Receipt account,
# the debit entry is the Receipt<->A/R, and the credit
# entry is the actual receipt ledger entry.
addRow('reconciliations',
{ 'debit_ledger_entry_id' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'ledger_entry_id'},
'credit_ledger_entry_id' => $newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'ledger_entry_id'},
{ 'debit_ledger_entry_id' => $newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'ledger_entry_id'},
'credit_ledger_entry_id' => $newdb{'lookup'}{'receipt'}{$row->{'ReceiptNum'}}{$row->{'PaymentType'}}{'ledger_entry_id'},
'amount' => $row->{'PaymentAmount'},
});
}
# 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'}}{'invoice'}{'amount'};
#print STDERR Dumper($newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}); exit;
$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
# Reconcile the A/R account. Our two entries look like:
# debit: Receipt credit: A/R
# debit: A/R credit: Invoice
# Since this is from the perspective of the A/R account,
# the debit entry is the Invoice<->A/R, and the credit
# entry is the Receipt<->A/R.
addRow('reconciliations',
{ 'debit_ledger_entry_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'ledger_entry_id'},
{ 'debit_ledger_entry_id' => $newdb{'lookup'}{'charge'}{$row->{'ChargeID'}}{'invoice'}{'ledger_entry_id'},
'credit_ledger_entry_id' => $newdb{'lookup'}{'payment'}{$row->{'PaymentID'}}{'ledger_entry_id'},
'amount' => $reconcile_amount,
});