Compare commits
4 Commits
v0.2.2
...
v0.3.0_wor
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f01e62fc6e | ||
|
|
9952673655 | ||
|
|
ccd1af6154 | ||
|
|
ce633d816a |
51
bookkeeping.notes
Normal file
51
bookkeeping.notes
Normal 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
|
||||||
|
|
||||||
10530
db/property_manager.sql
10530
db/property_manager.sql
File diff suppressed because it is too large
Load Diff
106
db/scratch.sql
106
db/scratch.sql
@@ -135,9 +135,7 @@ FROM pmgr_transactions T
|
|||||||
-- E.account_id != T.account_id
|
-- E.account_id != T.account_id
|
||||||
GROUP BY T.id
|
GROUP BY T.id
|
||||||
HAVING
|
HAVING
|
||||||
(T.type = 'INVOICE' AND Tamt <> T.amount)
|
(T.amount <> IF(T.type IN ('INVOICE','TRANSFER','DEPOSIT','PAYMENT'), Tamt, Oamt))
|
||||||
OR
|
|
||||||
(T.type <> 'INVOICE' AND Oamt <> T.amount)
|
|
||||||
OR
|
OR
|
||||||
(Tamt * -1 <> Oamt)
|
(Tamt * -1 <> Oamt)
|
||||||
|
|
||||||
@@ -576,3 +574,105 @@ ORDER BY IF(U.id IS NOT NULL, 1,
|
|||||||
IF (S.id IS NOT NULL, 3, 4))) ASC,
|
IF (S.id IS NOT NULL, 3, 4))) ASC,
|
||||||
IF (G.id IS NOT NULL, G.rank, 0) ASC
|
IF (G.id IS NOT NULL, G.rank, 0) ASC
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
-- ----------------------------------------------------
|
||||||
|
-- Income by Month
|
||||||
|
SELECT MONTH(SE.effective_date) AS mon, YEAR(SE.effective_date) AS yr,
|
||||||
|
SE.account_id AS acct, ROUND(SUM(SE.amount)) AS amt
|
||||||
|
FROM pmgr_statement_entries SE
|
||||||
|
WHERE SE.type = 'CHARGE'
|
||||||
|
AND SE.effective_date >= '2009-04-01' AND SE.effective_date <= NOW()
|
||||||
|
GROUP BY yr, mon, acct WITH ROLLUP
|
||||||
|
|
||||||
|
-- ----------------------------------------------------
|
||||||
|
-- Rent Income by Month
|
||||||
|
SELECT MONTH(SE.effective_date) AS mon, YEAR(SE.effective_date) AS yr,
|
||||||
|
ROUND(SUM(SE.amount)) AS amt
|
||||||
|
FROM pmgr_statement_entries SE
|
||||||
|
WHERE SE.type = 'CHARGE'
|
||||||
|
AND SE.effective_date >= '2009-04-01' AND SE.effective_date <= NOW()
|
||||||
|
AND SE.account_id = 13
|
||||||
|
GROUP BY yr, mon WITH ROLLUP
|
||||||
|
|
||||||
|
-- ----------------------------------------------------
|
||||||
|
-- Occupancy during given month
|
||||||
|
SELECT COUNT(L.id) FROM pmgr_leases L
|
||||||
|
WHERE L.movein_date < '2009-10-01'
|
||||||
|
AND (L.moveout_date IS NULL OR L.moveout_date > '2009-09-01')
|
||||||
|
|
||||||
|
-- ----------------------------------------------------
|
||||||
|
-- Move-ins by month
|
||||||
|
SELECT MONTH(L.movein_date) AS mon, YEAR(L.movein_date) AS yr, COUNT(L.id)
|
||||||
|
FROM pmgr_leases L
|
||||||
|
WHERE L.movein_date >= '2009-04-01'
|
||||||
|
GROUP BY yr, mon
|
||||||
|
|
||||||
|
-- ----------------------------------------------------
|
||||||
|
-- Move-outs by month
|
||||||
|
SELECT MONTH(L.moveout_date) AS mon, YEAR(L.moveout_date) AS yr, COUNT(L.id)
|
||||||
|
FROM pmgr_leases L
|
||||||
|
WHERE L.moveout_date >= '2009-04-01'
|
||||||
|
GROUP BY yr, mon
|
||||||
|
|
||||||
|
-- ----------------------------------------------------
|
||||||
|
-- Move-ins/Move-outs by month
|
||||||
|
SELECT
|
||||||
|
MONTH(L.movein_date) AS mon, YEAR(L.movein_date) AS yr,
|
||||||
|
IF(L.movein_date AS mon, YEAR(L.movein_date) AS yr,
|
||||||
|
FROM pmgr_leases L
|
||||||
|
WHERE L.movein_date >= '2009-04-01'
|
||||||
|
GROUP BY yr, mon
|
||||||
|
|
||||||
|
|
||||||
|
-- ----------------------------------------------------
|
||||||
|
-- Rent charged
|
||||||
|
SELECT SUM(SE.amount)
|
||||||
|
FROM pmgr_statement_entries SE
|
||||||
|
LEFT JOIN pmgr_accounts A ON A.id = SE.account_id
|
||||||
|
WHERE A.name = 'Rent'
|
||||||
|
-- AND SE.effective_date >= '2009-04-01'
|
||||||
|
-- AND SE.effective_date < '2009-12-01'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- --------------------------------------------------------------
|
||||||
|
-- Merge two customers
|
||||||
|
SELECT * FROM pmgr_statement_entries WHERE customer_id = 65
|
||||||
|
;
|
||||||
|
UPDATE pmgr_leases SET customer_id=21 WHERE customer_id=65;
|
||||||
|
UPDATE pmgr_reservations SET customer_id=21 WHERE customer_id=65;
|
||||||
|
UPDATE pmgr_statement_entries SET customer_id=21 WHERE customer_id=65;
|
||||||
|
UPDATE pmgr_tenders SET customer_id=21 WHERE customer_id=65;
|
||||||
|
UPDATE pmgr_transactions SET customer_id=21 WHERE customer_id=65;
|
||||||
|
-- Make sure to update customer info afterwards
|
||||||
|
|
||||||
|
|
||||||
|
-- --------------------------------------------------------------
|
||||||
|
-- Determine income from a customer
|
||||||
|
SELECT NT.name AS 'type', SUM(LE.amount) AS 'total'
|
||||||
|
FROM pmgr_tenders N
|
||||||
|
LEFT JOIN pmgr_tender_types NT ON NT.id = N.tender_type_id
|
||||||
|
LEFT JOIN pmgr_ledger_entries LE ON LE.id = N.ledger_entry_id
|
||||||
|
LEFT JOIN pmgr_customers C ON C.id = N.customer_id
|
||||||
|
WHERE
|
||||||
|
N.customer_id = 49
|
||||||
|
AND N.nsf_ledger_entry_id IS NULL
|
||||||
|
AND (NT.tillable OR NT.auto_deposit)
|
||||||
|
GROUP BY NT.name WITH ROLLUP
|
||||||
|
|
||||||
|
|
||||||
|
-- --------------------------------------------------------------
|
||||||
|
-- Determine rent charges by month
|
||||||
|
SELECT MONTH(SE.effective_date) AS 'mon',
|
||||||
|
YEAR(SE.effective_date) AS 'yr',
|
||||||
|
DATE_FORMAT(SE.effective_date, "%m/1/%Y") AS 'date',
|
||||||
|
SUM(SE.amount) AS 'total'
|
||||||
|
FROM pmgr_accounts A
|
||||||
|
LEFT JOIN pmgr_statement_entries SE ON SE.account_id = A.id
|
||||||
|
WHERE
|
||||||
|
A.name = 'Rent'
|
||||||
|
AND SE.effective_date < NOW()
|
||||||
|
GROUP BY yr, mon -- WITH ROLLUP
|
||||||
|
|
||||||
|
|||||||
@@ -32,22 +32,15 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function _box($type) {
|
function sandbox() {
|
||||||
static $box = array('type' => null, 'test' => array());
|
|
||||||
if (!isset($box['type']) && !isset($box['test'][$type])) {
|
|
||||||
$r = Router::requestRoute();
|
$r = Router::requestRoute();
|
||||||
/* if (!preg_match("/gridData/", $_SERVER['REQUEST_URI'])) { */
|
return !empty($r[3]['sand_route']);
|
||||||
/* print("<PRE>Route:\n");print_r($r);print("\n</PRE>\n"); */
|
|
||||||
/* } */
|
|
||||||
$box['test'][$type] = !empty($r[3]["${type}_route"]);
|
|
||||||
if ($box['test'][$type])
|
|
||||||
$box['type'] = $type;
|
|
||||||
}
|
|
||||||
return $box['type'] == $type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function sandbox() { return _box('sand'); }
|
function devbox() {
|
||||||
function devbox() { return _box('dev'); }
|
$r = Router::requestRoute();
|
||||||
|
return !empty($r[3]['dev_route']);
|
||||||
|
}
|
||||||
|
|
||||||
function server_request_var($var) {
|
function server_request_var($var) {
|
||||||
if (preg_match("/^HTTP_ACCEPT|REMOTE_PORT/", $var))
|
if (preg_match("/^HTTP_ACCEPT|REMOTE_PORT/", $var))
|
||||||
|
|||||||
@@ -43,16 +43,6 @@ Router::connect('/sand',
|
|||||||
array('sand_route' => true) + $default_path);
|
array('sand_route' => true) + $default_path);
|
||||||
Router::connect('/sand/:controller/:action/*',
|
Router::connect('/sand/:controller/:action/*',
|
||||||
array('sand_route' => true, 'action' => null));
|
array('sand_route' => true, 'action' => null));
|
||||||
/* Unfortunately, for some reason we need an extra route to solve
|
|
||||||
* a bug with form generation. When $this->data is set by the
|
|
||||||
* controller, and a URL is generated by the FormHelper, this
|
|
||||||
* route is required to ensure the form action is correct. An
|
|
||||||
* example of a broken page is for /customers/edit/XX. It appears
|
|
||||||
* the page location uses the route above, it's only URL generation
|
|
||||||
* that seems to be broken.
|
|
||||||
*/
|
|
||||||
Router::connect('/sand/:controller/:action/:id/*',
|
|
||||||
array('sand_route' => true,'action' => null, 'id'=>null));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Route for developement functionality
|
* Route for developement functionality
|
||||||
@@ -61,15 +51,5 @@ Router::connect('/dev',
|
|||||||
array('dev_route' => true) + $default_path);
|
array('dev_route' => true) + $default_path);
|
||||||
Router::connect('/dev/:controller/:action/*',
|
Router::connect('/dev/:controller/:action/*',
|
||||||
array('dev_route' => true, 'action' => null));
|
array('dev_route' => true, 'action' => null));
|
||||||
/* Unfortunately, for some reason we need an extra route to solve
|
|
||||||
* a bug with form generation. When $this->data is set by the
|
|
||||||
* controller, and a URL is generated by the FormHelper, this
|
|
||||||
* route is required to ensure the form action is correct. An
|
|
||||||
* example of a broken page is for /customers/edit/XX. It appears
|
|
||||||
* the page location uses the route above, it's only URL generation
|
|
||||||
* that seems to be broken.
|
|
||||||
*/
|
|
||||||
Router::connect('/dev/:controller/:action/:id/*',
|
|
||||||
array('dev_route' => true,'action' => null, 'id'=>null));
|
|
||||||
|
|
||||||
?>
|
?>
|
||||||
@@ -2,12 +2,6 @@
|
|||||||
|
|
||||||
class CustomersController extends AppController {
|
class CustomersController extends AppController {
|
||||||
|
|
||||||
// DEBUG FUNCTION ONLY!
|
|
||||||
// Call without id to update ALL customers
|
|
||||||
function force_update($id = null) {
|
|
||||||
$this->Customer->update($id);
|
|
||||||
$this->redirect(array('action'=>'index'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
|
|||||||
@@ -192,13 +192,6 @@ class Customer extends AppModel {
|
|||||||
}
|
}
|
||||||
$id = $this->id;
|
$id = $this->id;
|
||||||
|
|
||||||
// Appears that $this->save() "helpfully" choses to add in
|
|
||||||
// any missing data fields, populated with default values.
|
|
||||||
// So, after saving is complete, the fields 'lease_count',
|
|
||||||
// 'past_lease_count', and 'current_lease_count' have all
|
|
||||||
// been reset to zero. Gee, thanks Cake...
|
|
||||||
$this->update($id);
|
|
||||||
|
|
||||||
// Remove all associated Customer Contacts, as it ensures
|
// Remove all associated Customer Contacts, as it ensures
|
||||||
// any entries deleted by the user actually get deleted
|
// any entries deleted by the user actually get deleted
|
||||||
// in the system. We'll recreate the needed ones anyway.
|
// in the system. We'll recreate the needed ones anyway.
|
||||||
|
|||||||
@@ -148,11 +148,9 @@ class Lease extends AppModel {
|
|||||||
array('class' => 'StatementEntry',
|
array('class' => 'StatementEntry',
|
||||||
'fields' => array(),
|
'fields' => array(),
|
||||||
'conditions' => array
|
'conditions' => array
|
||||||
('SEx.lease_id = StatementEntry.lease_id',
|
('SEx.effective_date = DATE_ADD(StatementEntry.through_date, INTERVAL 1 day)',
|
||||||
'SEx.type' => 'CHARGE',
|
'SEx.lease_id = StatementEntry.lease_id',
|
||||||
'SEx.account_id' => $rent_account_id,
|
|
||||||
'SEx.reverse_transaction_id IS NULL',
|
'SEx.reverse_transaction_id IS NULL',
|
||||||
'SEx.effective_date = DATE_ADD(StatementEntry.through_date, INTERVAL 1 day)',
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
11
todo.notes
11
todo.notes
@@ -1,3 +1,14 @@
|
|||||||
|
Change the summary text "Balance Owed" to "Customer Credit"
|
||||||
|
or something similar when there is a negative balance owed.
|
||||||
|
|
||||||
|
Shrink the width of the detail view box so that the detail
|
||||||
|
and summary both fit on the same page on the Acer Netbook.
|
||||||
|
|
||||||
|
Remove Date from Ledger Entries on the Transaction page
|
||||||
|
(presuming that the Date is taken directly from the
|
||||||
|
Transaction and that all Ledger dates are all the same)
|
||||||
|
|
||||||
|
Add Deposit Slip # to the title bar when viewing deposit
|
||||||
|
|
||||||
Reversing a rent charge is not considered as part of the
|
Reversing a rent charge is not considered as part of the
|
||||||
"charged-through" date on the lease. Consequently, the
|
"charged-through" date on the lease. Consequently, the
|
||||||
|
|||||||
Reference in New Issue
Block a user