Compare commits

...

36 Commits

Author SHA1 Message Date
abijah
1da567ccdd Resetting the db, with reference to the old data
git-svn-id: file:///svn-source/pmgr/tags/v0.2.0@940 97e9348a-65ac-dc4b-aefc-98561f571b83
2010-03-02 03:28:51 +00:00
abijah
e175428212 Creating the 0.2.0 release
git-svn-id: file:///svn-source/pmgr/tags/v0.2.0@939 97e9348a-65ac-dc4b-aefc-98561f571b83
2010-03-02 03:26:44 +00:00
abijah
ccd1af6154 Merge in the v0.2.0 work
git-svn-id: file:///svn-source/pmgr/trunk@938 97e9348a-65ac-dc4b-aefc-98561f571b83
2010-03-02 03:25:52 +00:00
abijah
ce633d816a Added bookkeeping notes, apparently on 1/14/10
git-svn-id: file:///svn-source/pmgr/trunk@937 97e9348a-65ac-dc4b-aefc-98561f571b83
2010-03-02 03:16:34 +00:00
abijah
83bfb8d32d As the database has grown, the statement entry page query has finally ground to a halt. The query was kludged as simple as possible, and it now operates much quicker. A cleaner solution would be nice...
git-svn-id: file:///svn-source/pmgr/branches/v0.2.0_work@936 97e9348a-65ac-dc4b-aefc-98561f571b83
2010-03-02 03:10:54 +00:00
abijah
28817cea38 Removed buttons from the print media
git-svn-id: file:///svn-source/pmgr/branches/v0.2.0_work@914 97e9348a-65ac-dc4b-aefc-98561f571b83
2010-01-15 01:27:44 +00:00
abijah
3dca204ac6 Added the Deposit row to all tenders, not just those that have been deposited. This helps avoid confusion when looking at a non-deposited tender, since one may be trying to figure out whether or not it has been deposited and yet not remember if this is the appropriate screen.
git-svn-id: file:///svn-source/pmgr/branches/v0.2.0_work@900 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-12-09 18:02:00 +00:00
abijah
2fb2e6f5aa Update todo to reflect newly implemented features.
git-svn-id: file:///svn-source/pmgr/branches/v0.2.0_work@875 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-10-09 23:53:39 +00:00
abijah
44def81c81 Merge in from v0.1.0
git-svn-id: file:///svn-source/pmgr/branches/v0.2.0_work@874 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-10-09 23:51:45 +00:00
abijah
03da3afb98 More things to do based on how it's been going at VSS
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@873 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-10-09 23:46:18 +00:00
abijah
3b885e2686 Fixed the problem of client side lease selection breaking the automated rent invoicing tools.
git-svn-id: file:///svn-source/pmgr/branches/v0.2.0_work@872 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-10-09 23:17:46 +00:00
abijah
e162d35d56 Added a more automated mechanism for adding multiple rent charges to an invoice. Also included is a proration tool. This needs more work though, since it relies on server side data from the lease. Selecting a new lease on the client side will cause this change to fail, and so we'll need to add a column for charged-through. Finally, error messages for invoice and receipt were improved slightly to better explain the error.
git-svn-id: file:///svn-source/pmgr/branches/v0.2.0_work@871 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-10-09 22:48:37 +00:00
abijah
3b3ed7a264 Branch to add minor enhancements to v0.1.0
git-svn-id: file:///svn-source/pmgr/branches/v0.2.0_work@870 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-10-09 19:58:50 +00:00
cron
3b5aa78a47 property_manager database backup as of 2009_10_09_0113
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@869 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-10-09 08:13:46 +00:00
cron
721faa129b property_manager database backup as of 2009_10_08_0117
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@868 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-10-08 08:18:30 +00:00
cron
78806de606 property_manager database backup as of 2009_10_06_0124
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@867 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-10-06 08:24:25 +00:00
cron
d4ea5eea1f property_manager database backup as of 2009_10_03_0123
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@866 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-10-03 08:24:03 +00:00
cron
9213c1c21d property_manager database backup as of 2009_10_02_0905
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@865 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-10-02 16:06:14 +00:00
abijah
9674812e78 Merge in from the v0.1.0 tag, which is a bit of a botch. The intention was to make the change to trunk, then re-label as v0.1.1. However, due to a mixup, this was put directly as the v0.1.0 tag. It isn't good, but the change is small enough we'll live with it this time.
git-svn-id: file:///svn-source/pmgr/trunk@864 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-10-02 15:54:00 +00:00
abijah
8bda7c2cb0 Added the updateLeaseCount call to the customer update function. Most of the time it will not be necessary, but the purpose of update() is to ensure the customer info is current, so we're obligated to call it.
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@863 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-10-02 15:40:54 +00:00
cron
375d63485c property_manager database backup as of 2009_10_02_0116
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@862 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-10-02 08:16:34 +00:00
cron
26045a3db7 property_manager database backup as of 2009_10_01_0103
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@861 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-10-01 08:03:28 +00:00
cron
04ac012754 property_manager database backup as of 2009_09_29_0120
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@860 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-29 08:20:23 +00:00
cron
e6f662f0a1 property_manager database backup as of 2009_09_26_0113
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@859 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-26 08:13:58 +00:00
cron
04b3c06cda property_manager database backup as of 2009_09_25_0129
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@858 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-25 08:30:15 +00:00
cron
24da6d75b5 property_manager database backup as of 2009_09_24_0120
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@857 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-24 08:20:57 +00:00
cron
542ae17afd property_manager database backup as of 2009_09_23_0114
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@856 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-23 08:14:54 +00:00
cron
97fffaa610 property_manager database backup as of 2009_09_20_0118
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@855 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-20 08:18:46 +00:00
cron
3eb5139b62 property_manager database backup as of 2009_09_19_0125
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@854 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-19 08:26:07 +00:00
cron
5245393a04 property_manager database backup as of 2009_09_18_0104
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@853 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-18 08:04:33 +00:00
cron
e59df1dffb property_manager database backup as of 2009_09_16_0122
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@852 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-16 08:23:11 +00:00
cron
61da97974b property_manager database backup as of 2009_09_15_0112
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@851 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-15 08:12:24 +00:00
cron
6482cfd4cc property_manager database backup as of 2009_09_14_1953
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@850 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-15 02:53:36 +00:00
abijah
c3e51a7a6b Tagging first official release: v0.1.0
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@849 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-15 02:47:55 +00:00
abijah
de069ef186 Updated the todo items
git-svn-id: file:///svn-source/pmgr/trunk@848 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-15 02:42:32 +00:00
abijah
5047abba6a Merge in from pre_0.1 branch
git-svn-id: file:///svn-source/pmgr/trunk@847 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-15 02:38:28 +00:00
12 changed files with 378 additions and 6837 deletions

51
bookkeeping.notes Normal file
View File

@@ -0,0 +1,51 @@
Book Keeping Challenges / Issues
- Chart of Accounts is not sufficient
- One payment can go towards more than one charge
- One charge can be paid for by more than one payment
- Need to know: how much money does customer owe?
- Need to know: how much money has customer been charged for "Rent"?
- Need to know: how much money has customer paid towards "Rent" (nothing else)?
- Reverse a charge
To make charge reversal work, I'm presently issuing a credit note
(transaction) that has 3 ledger entries:
Debit charged account - Credit A/R
Debit A/R - Credit "Credit" account
Debit "Credit" account - Credit A/R
And 3 statement entries:
Reversal on charged account
Negative Disbursement on "Credit" account
Positive Disbursement on "Credit" account
Obviously, the two "Credit" account ledger entries cancel each other
out. However, the monies need to be reversed in the A/R account, and a
previous transaction will have already performed an A/R credit and so
the two A/R credits will create an imbalance in A/R unless we move
those funds to our "Credit" account. The "Credit" account statement
entries are needed to undo any previous disbursement to the charge
being reversed, and then to re-disburse those funds to a different
charge (or possibly just a Surplus entry if no other charges exist.)
Question
- What should be recorded with this charge reversal?
Charge of $5 for "Parking"
Charge of $6 for "Rent"
Payment of $6
Reverse the $5 "Parking" charge
- What should be recorded with this charge reversal?
Charge of $5 for "Parking"
Charge of $6 for "Rent"
Charge of $7 for "Pets"
Payment of $13
Reverse the $5 "Parking" charge
- What should be recorded with this charge reversal?
Charge of $5 for "Parking"
Charge of $6 for "Rent"
Charge of $7 for "Pets"
Payment of $18
Reverse the $5 "Parking" charge

File diff suppressed because it is too large Load Diff

View File

@@ -45,7 +45,7 @@ Operations to be functional
X - Receive and record Money Orders
X - Receive and record Cash
X - Receive and record ACH Deposits
? - Reverse rent charges (early moveout on prepaid occupancy)
X - Reverse rent charges (early moveout on prepaid occupancy)
X - Handle NSF checks
X - Assess NSF Fees
X - Determine Lease Paid-Through status

View File

@@ -47,7 +47,17 @@ class StatementEntriesController extends AppController {
if (!empty($params['post']['custom']['statement_entry_id'])) {
$link['ChargeEntry'] = array();
$link['DisbursementEntry'] = array();
// This query actually represents a union...
// Unpaid Charge/Surplus: ChargeID - NULL; DisbursementID - NULL
// Paid Charge/Refund: ChargeID - NULL; DisbursementID - !NULL
// Disbursement/Reversal: ChargeID - !NULL; DisbursementID - NULL
// <EMPTY SET>: ChargeID - !NULL; DisbursementID - !NULL
//
// The query is really slow unless we add the `id` condition to the join.
// A cleaner query would be nice, but we must work within the Cake framework.
$link['DisbursementEntry'] = array('conditions' =>
'`DisbursementEntry`.`id` = '
. $params['post']['custom']['statement_entry_id']);
}
return array('link' => $link);

View File

@@ -247,10 +247,10 @@ class Customer extends AppModel {
return;
}
// REVISIT <AP>: 20090812
// updateLeaseCount is handled directly when needed.
// Should we simplify by just doing it anyway?
//$this->updateLeaseCount($id);
// updateLeaseCount is typically handled directly when needed.
// However, this function is used to _ensure_ customer info is
// current, so we're obligated to call it anyway.
$this->updateLeaseCount($id);
$current_leases =
$this->find('all',

View File

@@ -48,26 +48,34 @@ function verifyRequest(formData, jqForm, options) {
if (formData[i]['name'] == "data[Customer][id]" &&
!(formData[i]['value'] > 0)) {
//$("#debug").append('<P>Missing Customer ID');
alert("Must select a customer first");
alert("Please select a customer first.");
return false;
}
if (formData[i]['name'] == "data[Transaction][stamp]" &&
formData[i]['value'] == '') {
//$("#debug").append('<P>Bad Stamp');
alert("Must enter a valid date stamp");
if (formData[i]['value'] != '')
alert(formData[i]['value'] + " is not valid date stamp. Please correct it.");
else
alert("Please enter a valid date stamp first.");
return false;
}
// Terrible way to accomplish this...
for (var j = 0; j < 20; ++j) {
if (formData[i]['name'] == "data[Entry]["+j+"][amount]" &&
!(formData[i]['value'] > 0)) {
if (formData[i]['name'] == "data[Entry]["+j+"][amount]") {
var val = formData[i]['value'].replace(/\$/,'');
//$("#debug").append('<P>Bad Amount');
alert("Must enter a valid amount");
if (!(val > 0)) {
if (formData[i]['value'] == '')
alert("Please enter an amount first.");
else
alert('"'+formData[i]['value']+'"' + " is not valid amount. Please correct it.");
return false;
}
}
}
}

View File

@@ -11,6 +11,7 @@ $cols['Signed'] = array('index' => 'Lease.lease_date', 'formatter' => 'dat
$cols['Move-In'] = array('index' => 'Lease.movein_date', 'formatter' => 'date');
$cols['Move-Out'] = array('index' => 'Lease.moveout_date', 'formatter' => 'date');
$cols['Closed'] = array('index' => 'Lease.close_date', 'formatter' => 'date');
$cols['Charge-Thru'] = array('index' => 'Lease.charge_through_date', 'formatter' => 'date');
$cols['Paid-Thru'] = array('index' => 'Lease.paid_through_date', 'formatter' => 'date');
$cols['Status'] = array('index' => 'status', 'formatter' => 'longenum');
$cols['Balance'] = array('index' => 'balance', 'formatter' => 'currency');
@@ -18,7 +19,7 @@ $cols['Comment'] = array('index' => 'Lease.comment', 'formatter' => 'com
if (!empty($this->params['action'])) {
if ($this->params['action'] === 'closed')
$grid->invalidFields(array('Paid-Thru', 'Status'));
$grid->invalidFields(array('Charge-Thru', 'Paid-Thru', 'Status'));
elseif ($this->params['action'] === 'active')
$grid->invalidFields(array('Closed'));
elseif ($this->params['action'] === 'delinquent')
@@ -32,4 +33,4 @@ $grid
->defaultFields(array('Lease'))
->searchFields(array('Customer', 'Unit'))
->render($this, isset($config) ? $config : null,
array_diff(array_keys($cols), array('Signed', 'Status', 'Comment')));
array_diff(array_keys($cols), array('Signed', 'Charge-Thru', 'Status', 'Comment')));

View File

@@ -10,6 +10,7 @@ $customer = $lease['Customer'];
if (isset($lease['Lease']))
$lease = $lease['Lease'];
//pr(compact('unit', 'customer', 'lease', 'movein'));
/**********************************************************************
**********************************************************************
@@ -25,6 +26,8 @@ Configure::write('debug', '0');
<script type="text/javascript"><!--
var lease_charge_through;
// prepare the form when the DOM is ready
$(document).ready(function() {
var options = {
@@ -62,19 +65,27 @@ function verifyRequest(formData, jqForm, options) {
if (formData[i]['name'] == "data[Transaction][stamp]" &&
formData[i]['value'] == '') {
//$("#debug").append('<P>Bad Stamp');
alert("Must enter a valid date stamp");
if (formData[i]['value'] != '')
alert(formData[i]['value'] + " is not valid date stamp. Please correct it.");
else
alert("Please enter a valid date stamp first.");
return false;
}
// Terrible way to accomplish this...
/* for (var j = 0; j < 20; ++j) { */
/* if (formData[i]['name'] == "data[Entry]["+j+"][amount]" && */
/* !(formData[i]['value'] > 0)) { */
/* //$("#debug").append('<P>Bad Amount'); */
/* alert("Must enter a valid amount"); */
/* return false; */
/* } */
/* } */
for (var j = 0; j < 20; ++j) {
if (formData[i]['name'] == "data[Entry]["+j+"][amount]") {
var val = formData[i]['value'].replace(/\$/,'');
//$("#debug").append('<P>Bad Amount');
if (!(val > 0)) {
if (formData[i]['value'] == '')
alert("Please enter an amount for Charge #"+j+", or remove the Charge completely.");
else
alert('"'+formData[i]['value']+'"' + " is not a valid amount for Charge #"+j+". Please correct it.");
return false;
}
}
}
}
//$("#debug").append('OK');
@@ -142,6 +153,7 @@ function onRowSelect(grid_id, lease_id) {
$("#invoice-deposit").html($(grid_id).getCell(lease_id, 'Lease-deposit')
? $(grid_id).getCell(lease_id, 'Lease-deposit')
: '-');
lease_charge_through = $(grid_id).getCell(lease_id, 'Lease-charge_through_date')
// Hide the "no lease" message and show the current lease
$(".lease-selection-invalid").hide();
@@ -167,6 +179,78 @@ function onGridState(grid_id, state) {
}
}
function setNextRent(id) {
var chg_thru;
$('.ChargeForm').each( function(i) {
if ($('.ChargeFormThroughDate', this).attr('id') == 'Entry'+id+'ThroughDate')
return;
if ($('.ChargeFormAccount option:selected', this).val() == <?php echo $rentAccount ?>
&& $('.ChargeFormThroughDate', this).val()) {
var dt = new Date($('.ChargeFormThroughDate', this).val());
//$('#debug').append('Rent in ' + i + '; date ' + dt + '<BR>');
if (chg_thru == null || dt > chg_thru)
chg_thru = dt;
}
});
if (!chg_thru)
chg_thru = new Date(lease_charge_through);
if (chg_thru < dateEOM(chg_thru)) {
// Add a charge to finish out the month
datepickerSet('Entry'+id+'EffectiveDate', dateTomorrow(chg_thru));
datepickerSet('Entry'+id+'ThroughDate', dateEOM(chg_thru));
} else {
// Add a whole month's charge for next month
datepickerSet('Entry'+id+'EffectiveDate', dateNextBOM(chg_thru));
datepickerSet('Entry'+id+'ThroughDate', dateNextEOM(chg_thru));
}
// Now add in the amount owed based on the calculated
// effective and through dates.
prorate(id);
}
function prorate(id) {
var edt = datepickerGet('Entry'+id+'EffectiveDate');
var tdt = datepickerGet('Entry'+id+'ThroughDate');
var rent = $('#invoice-rent').html().replace(/\$/,'');
// Reset the comment. It might wipe out a user comment,
// but it's probably low risk/concern
$('#Entry'+id+'Comment').val('');
if (edt == null || tdt == null) {
alert('Can only prorate with both effective and through dates');
rent = 0;
}
else if (edt > tdt) {
alert('Effective date is later than the Through date');
rent = 0;
}
else if (tdt.getMonth() == edt.getMonth() + 1 &&
edt.getDate() == tdt.getDate() + 1) {
// appears to be anniversary billing, one full cycle
}
else if (edt.getTime() == dateBOM(edt).getTime() &&
tdt.getTime() == dateEOM(edt).getTime()) {
// appears to be one full month
}
else {
var one_day=1000*60*60*24;
var days = Math.ceil((tdt.getTime()-edt.getTime()+1)/(one_day));
var dim =
((edt.getMonth() == tdt.getMonth())
? dateEOM(edt).getDate() // prorated within the month.
: 30); // prorated across months.
rent *= days / dim;
$('#Entry'+id+'Comment').val('Rent proration: '+days+'/'+dim+' days');
}
$('#Entry'+id+'Amount').val(fmtCurrency(rent));
}
function addChargeSource(flash) {
var id = $("#charge-entry-id").val();
addDiv('charge-entry-id', 'charge', 'charges', flash,
@@ -178,26 +262,32 @@ function addChargeSource(flash) {
echo FormatHelper::phpVarToJavascript
($this->element('form_table',
array('id' => 'Entry%{id}Form',
'class' => "item invoice ledger-entry entry",
'class' => "ChargeForm item invoice ledger-entry entry",
//'with_name_after' => ':',
'field_prefix' => 'Entry.%{id}',
'fields' => array
("account_id" => array('name' => 'Account',
'opts' =>
array('options' => $chargeAccounts,
array('class' => 'ChargeFormAccount',
'options' => $chargeAccounts,
'value' => $defaultAccount,
),
'between' => '<A HREF="#" ONCLICK="setNextRent(\'%{id}\'); return false;">Rent</A>',
),
"effective_date" => array('opts' =>
array('type' => 'text'),
array('class' => 'ChargeFormEffectiveDate',
'type' => 'text'),
'between' => '<A HREF="#" ONCLICK="datepickerBOM(\'TransactionStamp\',\'Entry%{id}EffectiveDate\'); return false;">BOM</A>',
),
"through_date" => array('opts' =>
array('type' => 'text'),
array('class' => 'ChargeFormThroughDate',
'type' => 'text'),
'between' => '<A HREF="#" ONCLICK="datepickerEOM(\'Entry%{id}EffectiveDate\',\'Entry%{id}ThroughDate\'); return false;">EOM</A>',
),
"amount" => array('opts' => array('class' => 'invoice amount')),
"comment" => array('opts' => array('size' => 50)),
"amount" => array('opts' => array('class' => 'ChargeFormAmount invoice amount'),
'between' => '<A HREF="#" ONCLICK="prorate(\'%{id}\'); return false;">Prorate</A>',
),
"comment" => array('opts' => array('class' => 'ChargeFormComment', 'size' => 50)),
),
))) . "+\n";
?>
@@ -233,7 +323,8 @@ if (empty($movein))
array('gridstate' =>
'onGridState("#"+$(this).attr("id"), gridstate)'),
),
'exclude' => array('Closed'),
'include' => array('Charge-Thru'),
'exclude' => array('Closed', 'Paid-Thru'),
'action' => 'active',
'nolinks' => true,
'limit' => 10,
@@ -330,9 +421,34 @@ Configure::write('debug', '0');
$('tr td:nth-child('+col+'), tr th:nth-child('+col+')', this).remove();
};
function addHidden(id, fld, name) {
$('#Entry'+id+fld).after
('<input type="hidden"' +
' name="data[Entry]['+id+']['+name+']"' +
' value="' + $('#Entry'+id+fld).val() + '">');
}
$(document).ready(function(){
datepicker('TransactionStamp');
<?php if (isset($lease['id'])): ?>
$("#lease-id").val(<?php echo $lease['id']; ?>);
$("#invoice-lease").html("<?php echo '#'.$lease['number']; ?>");
$("#invoice-unit").html("<?php echo $unit['name']; ?>");
$("#invoice-customer").html("<?php echo $customer['name']; ?>");
$("#invoice-rent").html("<?php echo FormatHelper::currency($lease['rent']); ?>");
$("#invoice-late").html("<?php echo FormatHelper::currency($defaultLate); ?>");
$("#invoice-deposit").html("<?php echo FormatHelper::currency($lease['deposit']); ?>");
lease_charge_through = <?php
if ($lease['charge_through_date'])
echo 'new Date("'.date('m/d/Y', strtotime($lease['charge_through_date'])).'")';
elseif ($lease['paid_through_date'])
echo 'new Date("'.date('m/d/Y', strtotime($lease['paid_through_date'])).'")';
else
echo 'dateYesterday("'.date('m/d/Y', strtotime($lease['movein_date'])).'")';
?>;
<?php else: ?>
$("#lease-id").val(0);
$("#invoice-lease").html("INTERNAL ERROR");
$("#invoice-unit").html("INTERNAL ERROR");
@@ -340,6 +456,8 @@ Configure::write('debug', '0');
$("#invoice-rent").html("INTERNAL ERROR");
$("#invoice-late").html("INTERNAL ERROR");
$("#invoice-deposit").html("INTERNAL ERROR");
<?php endif; ?>
<?php if (empty($movein)): ?>
@@ -356,7 +474,7 @@ Configure::write('debug', '0');
$('#TransactionStamp').after
('<input type="hidden"' +
' name="data[Transaction][stamp]"' +
' value="<?php echo date('m/d/Y', $movein['time']); ?>">');
' value="' + $("#TransactionStamp").val() + '">');
$("#TransactionComment").val('Move-In Charges');
<?php if ($movein['deposit'] != 0): ?>
@@ -364,61 +482,28 @@ Configure::write('debug', '0');
$('#Entry'+id+'Form').removeCol(2);
$('#Entry'+id+'Form input, #Entry'+id+'Form select').attr('disabled', true);
$('#Entry'+id+'EffectiveDate').val("<?php echo date('m/d/Y', $movein['effective_time']); ?>");
$('#Entry'+id+'EffectiveDate').after
('<input type="hidden"' +
' name="data[Entry]['+id+'][effective_date]"' +
' value="<?php echo date('m/d/Y', $movein['effective_time']); ?>">');
addHidden(id, 'EffectiveDate', 'effective_date');
$('#Entry'+id+'AccountId').val(<?php echo $securityDepositAccount; ?>);
$('#Entry'+id+'AccountId').after
('<input type="hidden"' +
' name="data[Entry]['+id+'][account_id]"' +
' value="<?php echo $securityDepositAccount; ?>">');
addHidden(id, 'AccountId', 'account_id');
$('#Entry'+id+'Amount').val("<?php echo FormatHelper::currency($movein['deposit']); ?>");
$('#Entry'+id+'Amount').after
('<input type="hidden"' +
' name="data[Entry]['+id+'][amount]"' +
' value="<?php echo FormatHelper::currency($movein['deposit']); ?>">');
//$('#Entry'+id+'Comment').val('Move-In Security Deposit');
addHidden(id, 'Amount', 'amount');
$('#Entry'+id+'Comment').removeAttr('disabled');
<?php endif; ?>
id = addChargeSource(false);
$('#Entry'+id+'Form').removeCol(2);
$('#Entry'+id+'Form input, #Entry'+id+'Form select').attr('disabled', true);
$('#Entry'+id+'EffectiveDate').val("<?php echo date('m/d/Y', $movein['effective_time']); ?>");
$('#Entry'+id+'EffectiveDate').after
('<input type="hidden"' +
' name="data[Entry]['+id+'][effective_date]"' +
' value="<?php echo date('m/d/Y', $movein['effective_time']); ?>">');
$('#Entry'+id+'ThroughDate').val("<?php echo date('m/d/Y', $movein['through_time']); ?>");
$('#Entry'+id+'ThroughDate').after
('<input type="hidden"' +
' name="data[Entry]['+id+'][through_date]"' +
' value="<?php echo date('m/d/Y', $movein['through_time']); ?>">');
$('#Entry'+id+'AccountId').val(<?php echo $rentAccount; ?>);
$('#Entry'+id+'AccountId').after
('<input type="hidden"' +
' name="data[Entry]['+id+'][account_id]"' +
' value="<?php echo $rentAccount; ?>">');
$('#Entry'+id+'Amount').val("<?php echo FormatHelper::currency($movein['prorated_rent']); ?>");
$('#Entry'+id+'Amount').after
('<input type="hidden"' +
' name="data[Entry]['+id+'][amount]"' +
' value="<?php echo FormatHelper::currency($movein['prorated_rent']); ?>">');
$('#Entry'+id+'Comment').val("<?php echo($movein['prorated'] ? 'Move-In Rent (Prorated)' : ''); ?>");
setNextRent(id);
addHidden(id, 'EffectiveDate', 'effective_date');
addHidden(id, 'ThroughDate', 'through_date');
addHidden(id, 'AccountId', 'account_id');
addHidden(id, 'Amount', 'amount');
$('#Entry'+id+'Comment').removeAttr('disabled');
<?php endif; ?>
<?php if (isset($lease['id'])): ?>
$("#lease-id").val(<?php echo $lease['id']; ?>);
$("#invoice-lease").html("<?php echo '#'.$lease['number']; ?>");
$("#invoice-unit").html("<?php echo $unit['name']; ?>");
$("#invoice-customer").html("<?php echo $customer['name']; ?>");
$("#invoice-rent").html("<?php echo FormatHelper::currency($lease['rent']); ?>");
$("#invoice-late").html("<?php echo FormatHelper::currency($defaultLate); ?>");
$("#invoice-deposit").html("<?php echo FormatHelper::currency($lease['deposit']); ?>");
onGridState(null, 'hidden');
<?php else: ?>
onGridState(null, 'visible');

View File

@@ -33,8 +33,10 @@ for ($i=1; $i<=4; ++$i)
if (!empty($ttype["data{$i}_name"]))
$rows[] = array($ttype["data{$i}_name"], $tender["data{$i}"]);
if (!empty($tender['deposit_transaction_id']))
$rows[] = array('Deposit', $html->link('#'.$tender['deposit_transaction_id'],
$rows[] = array('Deposit',
empty($tender['deposit_transaction_id'])
? "-"
: $html->link('#'.$tender['deposit_transaction_id'],
array('controller' => 'transactions',
'action' => 'deposit_slip',
$tender['deposit_transaction_id'])));

View File

@@ -16,6 +16,14 @@ div#debug-kit-toolbar
{ display: none; }
/************************************************************
* Form inputs
*/
/* The "page N / M" input box... make it look like normal text */
input[type='button'], input[type='submit'], input[type='reset']
{ display: none; }
/************************************************************
* Grid display
*/

View File

@@ -67,7 +67,17 @@ function dump(element, limit, depth) {
if (props.length == 0)
return '';
return pad + '<ol><li>' + props.join("</li>\n" + pad + pad1 + "<li>") + "</li>\n" + pad + "</ol>";
if (typeof dump.dumpid == 'undefined')
dump.dumpid = 0;
++dump.dumpid;
return (pad
+ '<A HREF="#" ONCLICK="$(\'#dumpid-'+dump.dumpid+'\').toggle(); return false;">(hide members)</A><BR>'
+ '<ol id="dumpid-'+dump.dumpid+'" STYLE="padding-top:0; margin-top:0;">'
+ '<li>'
+ props.join("</li>\n" + pad + pad1 + '<li id="dumpid-'+dump.dumpid+'">')
+ "</li>\n"
+ pad + "</ol>");
}
function dump_window(element, limit) {
@@ -158,69 +168,102 @@ function datepicker(id) {
}
}
function datepickerNow(id, usetime) {
var now = new Date();
if ($("#"+id).datepicker != null) {
// datepicker seems to squash the time portion,
// so we have to pass in a copy of now instead.
$("#"+id).datepicker('setDate', new Date(now));
}
else {
$("#"+id).val(((now.getMonth()+1) < 10 ? '0' : '')
+ (now.getMonth()+1) + '/'
+ (now.getDate() < 10 ? '0' : '')
+ now.getDate() + '/'
+ now.getFullYear());
}
if (usetime == null)
usetime = true;
$("#"+id).val($("#"+id).val() +
(usetime
? (' '
+ (now.getHours() < 10 ? '0' : '')
+ now.getHours() + ':'
+ (now.getMinutes() < 10 ? '0' : '')
+ now.getMinutes())
: ''));
}
function datepickerSet(fromid, id, a, b) {
var dt;
if (fromid == null)
function datepickerGet(id) {
if (id == null)
dt = new Date();
else {
if ($("#"+id).datepicker != null)
dt = new Date($("#"+fromid).datepicker('getDate'));
if ($("#"+id).datepicker != null && $("#"+id).datepicker('getDate') != null)
dt = new Date($("#"+id).datepicker('getDate'));
else if ($("#"+id).val())
dt = new Date($("#"+id).val());
else
dt = new Date($("#"+fromid).val());
dt = null;
}
if (a != null)
dt.setDate(a);
if (b != null)
dt.setDate(b);
return dt;
}
if ($("#"+id).datepicker != null)
$("#"+id).datepicker('setDate', dt);
function datepickerStr(id) {
return dateStr(datepickerGet(id));
}
function datepickerSet(id, dt_or_str, usetime) {
if ($("#"+id).datepicker != null && $("#"+id).datepicker('getDate') != null) {
// datepicker seems to squash the time portion,
// so we have to pass in a copy of dt instead.
$("#"+id).datepicker('setDate', new Date(dt_or_str));
if (usetime)
$("#"+id).val($("#"+id).val() + ' ' + timeStr(dt_or_str));
}
else {
$("#"+id).val(((dt.getMonth()+1) < 10 ? '0' : '')
$("#"+id).val(dateStr(dt_or_str), usetime);
}
}
function datepickerNow(id, usetime) {
datepickerSet(id, new Date(), usetime == null ? true : usetime);
}
function dateStr(dt_or_str, usetime) {
var dt = new Date(dt_or_str);
return (((dt.getMonth()+1) < 10 ? '0' : '')
+ (dt.getMonth()+1) + '/'
+ (dt.getDate() < 10 ? '0' : '')
+ dt.getDate() + '/'
+ dt.getFullYear());
}
+ dt.getFullYear()
+ (usetime ? ' ' + timeStr(dt) : ''));
}
function datepickerBOM(fromid, id) {
datepickerSet(fromid, id, 1);
function timeStr(dt_or_str) {
var dt = new Date(dt_or_str);
return ((dt.getHours() < 10 ? '0' : '')
+ dt.getHours() + ':'
+ (dt.getMinutes() < 10 ? '0' : '')
+ dt.getMinutes());
}
function datepickerEOM(fromid, id) {
datepickerSet(fromid, id, 32, 0);
function dateAdd(dt_or_str, a, b, m, d) {
var dt = new Date(dt_or_str);
if (m != null) {
dt.setDate(1);
dt.setMonth(dt.getMonth() + m);
//$('#debug').append('set month ('+m+') ' + (dt.getMonth() + m) + '= ' + dt + '<BR>');
}
if (d != null) {
dt.setDate(dt.getDate() + d);
//$('#debug').append('set day ('+d+') ' + (dt.getDate() + d) + '= ' + dt + '<BR>');
}
if (a != null) {
dt.setDate(a);
//$('#debug').append('set date ('+a+') = ' + dt + '<BR>');
}
if (b != null) {
dt.setDate(b);
//$('#debug').append('set date ('+b+') = ' + dt + '<BR>');
}
return dt;
}
function dateYesterday(dt) { return dateAdd(dt,null,null,null,-1); }
function dateTomorrow(dt) { return dateAdd(dt,null,null,null,1); }
function dateBOM(dt) { return dateAdd(dt,1); }
function dateNextBOM(dt) { return dateAdd(dt,1,null,1); }
function dateEOM(dt) { return dateAdd(dt,32,0); }
function dateNextEOM(dt) { return dateAdd(dt,32,0,1); }
function datepickerBOM(fromid, id)
{ datepickerSet(id, dateBOM(datepickerGet(fromid))); }
function datepickerEOM(fromid, id)
{ datepickerSet(id, dateEOM(datepickerGet(fromid))); }
function datepickerNextBOM(fromid, id)
{ datepickerSet(id, dateNextBOM(datepickerGet(fromid))); }
function datepickerNextEOM(fromid, id)
{ datepickerSet(id, dateNextEOM(datepickerGet(fromid))); }
// REVISIT <AP>: 20090617

View File

@@ -1,3 +1,9 @@
Reversing a rent charge is not considered as part of the
"charged-through" date on the lease. Consequently, the
reversal itself ensures the charge is fully "paid", and
the "paid-through" date is also out of whack.
Add NSF Fee to the NSF entry page (It's hardcoded right now
in Transaction to $35).
@@ -15,13 +21,6 @@ be closed and no more charges are possible. The other option
would just be a checkbox to say "close lease (no more charges)",
or let them clear it and have them close the lease manually.
Invoice
- Have some sort of rent-proration tool
- Have Rent automatically populate the Effective/Through
as well as rent (pro-rating if necessary). The dates
should take into account the customer charge through
date, as well as any other rents on the invoice.
Allow waiving a complete charge, even if it already has payments
applied (at the moment, we just can waive the charge balance).
@@ -52,11 +51,6 @@ Reduce the number of cached items. Figure out how to get Cake to
automatically make CONCAT(TenderType.name, ' #', Tender.id) part
of each returned query.
Implement, as part of the User model, a function to return the
security level. Have it be a static function, so that we don't
need to instantiate it, and right now, return a level based on
the route.
Add the opposite of the "collected" report, which provides a set of
checkboxes for the different incomes, and returns a list of where
the received monies were disbursed for the selected period.
@@ -193,3 +187,37 @@ Unit Size has no controller. Either remove the link from the
units grid, or implement the controller.
When performing a move-in, the receipt page is broken
when trying to enter a concession. javascript complains about
an invalid value, and the page is not submitted.
- Allegedly. I believe Shirley's browser was acting up
on her, and based on the logs, it seems that indeed
what ultimately worked just fine for a concession entry
was really the exact same page that was stuck. While
on the phone it was evident that here browser was
doing a javascript wig-out, and it wasn't related to
a slow internet connection.
Add invoice rent helpers
- monthly proration tool
- select from/to dates, and hit "prorate"
- charge through date
- enter charge through date, and the invoice
will automatically have charges for each month
from the current charge-through date to the
new charge-through date.
- charge N months
- enter number of months, and the invoice
will automatically have charges for each month
from the current charge-through date for N months
- next rent
- same as, or instead of, "charge N months", where
N is 1
Invoice
- Have some sort of rent-proration tool
- Have Rent automatically populate the Effective/Through
as well as rent (pro-rating if necessary). The dates
should take into account the customer charge through
date, as well as any other rents on the invoice.