Brought all notes to a top level directory, and got rid of the VSS database sql file. It has moved to its own repository: /svn/vss
git-svn-id: file:///svn-source/pmgr/branches/v0.2_work@967 97e9348a-65ac-dc4b-aefc-98561f571b83
This commit is contained in:
@@ -1,3 +0,0 @@
|
|||||||
@echo off
|
|
||||||
mysql --user=pmgr --password=pmgruser < %~dp0\db\property_manager.sql
|
|
||||||
echo Done!
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Please see previous revisions on /tags/v0.1.0
|
|
||||||
578
db/scratch.sql
578
db/scratch.sql
@@ -1,578 +0,0 @@
|
|||||||
-- Delete bad transaction(s)
|
|
||||||
DELETE M
|
|
||||||
FROM
|
|
||||||
pmgr_ledger_entries LE,
|
|
||||||
pmgr_tenders M
|
|
||||||
WHERE
|
|
||||||
M.ledger_entry_id = LE.id AND
|
|
||||||
LE.transaction_id
|
|
||||||
IN (467);
|
|
||||||
DELETE LE
|
|
||||||
FROM
|
|
||||||
pmgr_ledger_entries LE
|
|
||||||
WHERE
|
|
||||||
LE.transaction_id
|
|
||||||
IN (467);
|
|
||||||
DELETE SE
|
|
||||||
FROM
|
|
||||||
pmgr_statement_entries SE
|
|
||||||
WHERE
|
|
||||||
SE.transaction_id
|
|
||||||
IN (467);
|
|
||||||
DELETE T
|
|
||||||
FROM
|
|
||||||
pmgr_transactions T
|
|
||||||
WHERE
|
|
||||||
T.id
|
|
||||||
IN (467);
|
|
||||||
|
|
||||||
-- Delete bad transaction, one variable setting
|
|
||||||
SET @tid = 467;
|
|
||||||
DELETE M FROM pmgr_ledger_entries LE, pmgr_tenders M
|
|
||||||
WHERE M.ledger_entry_id = LE.id AND LE.transaction_id = @tid;
|
|
||||||
DELETE LE FROM pmgr_ledger_entries LE
|
|
||||||
WHERE LE.transaction_id = @tid;
|
|
||||||
DELETE SE FROM pmgr_statement_entries SE
|
|
||||||
WHERE SE.transaction_id = @tid;
|
|
||||||
DELETE T FROM pmgr_transactions T
|
|
||||||
WHERE T.id = @tid;
|
|
||||||
|
|
||||||
|
|
||||||
-- Delete all but one customer
|
|
||||||
SET @cid = 6;
|
|
||||||
-- DELETE T FROM pmgr_transactions T
|
|
||||||
-- LEFT JOIN pmgr_customers C ON C.id = T.customer_id
|
|
||||||
-- WHERE C.id IS NOT NULL AND C.id <> @cid;
|
|
||||||
DELETE C FROM pmgr_customers C
|
|
||||||
WHERE C.id <> @cid;
|
|
||||||
DELETE L FROM pmgr_leases L
|
|
||||||
LEFT JOIN pmgr_customers C ON C.id = L.customer_id
|
|
||||||
WHERE C.id IS NULL;
|
|
||||||
DELETE T FROM pmgr_transactions T
|
|
||||||
LEFT JOIN pmgr_customers C ON C.id = T.customer_id
|
|
||||||
WHERE C.id IS NULL;
|
|
||||||
DELETE SE FROM pmgr_statement_entries SE
|
|
||||||
LEFT JOIN pmgr_customers C ON C.id = SE.customer_id
|
|
||||||
WHERE C.id IS NULL;
|
|
||||||
DELETE LE FROM pmgr_ledger_entries LE
|
|
||||||
LEFT JOIN pmgr_transactions T ON T.id = LE.transaction_id
|
|
||||||
WHERE T.id IS NULL;
|
|
||||||
DELETE M FROM pmgr_tenders M
|
|
||||||
LEFT JOIN pmgr_ledger_entries LE ON M.ledger_entry_id = LE.id
|
|
||||||
WHERE LE.id IS NULL;
|
|
||||||
DELETE DE FROM pmgr_double_entries DE
|
|
||||||
LEFT JOIN pmgr_ledger_entries LE ON LE.id = DE.debit_entry_id
|
|
||||||
WHERE LE.id IS NULL;
|
|
||||||
DELETE DE FROM pmgr_double_entries DE
|
|
||||||
LEFT JOIN pmgr_ledger_entries LE ON LE.id = DE.credit_entry_id
|
|
||||||
WHERE LE.id IS NULL;
|
|
||||||
UPDATE pmgr_ledger_entries LE, pmgr_ledgers L, pmgr_accounts A
|
|
||||||
SET LE.ledger_id = L.id
|
|
||||||
WHERE A.id = LE.account_id AND L.account_id = A.id AND L.sequence = 1;
|
|
||||||
DELETE FROM pmgr_ledgers WHERE sequence > 1;
|
|
||||||
UPDATE pmgr_ledgers SET prior_ledger_id = NULL, close_transaction_id = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
-- Delete a ledger entry, associated double entry, and matching ledger_entry
|
|
||||||
SET @leid = 1365;
|
|
||||||
DELETE FROM pmgr_ledger_entries WHERE id = @leid;
|
|
||||||
DELETE DE FROM pmgr_double_entries DE
|
|
||||||
LEFT JOIN pmgr_ledger_entries LE ON LE.id = DE.debit_entry_id
|
|
||||||
WHERE LE.id IS NULL;
|
|
||||||
DELETE DE FROM pmgr_double_entries DE
|
|
||||||
LEFT JOIN pmgr_ledger_entries LE ON LE.id = DE.credit_entry_id
|
|
||||||
WHERE LE.id IS NULL;
|
|
||||||
DELETE LE FROM pmgr_ledger_entries LE
|
|
||||||
LEFT JOIN pmgr_double_entries DE
|
|
||||||
ON DE.credit_entry_id = LE.id OR DE.debit_entry_id = LE.id
|
|
||||||
WHERE DE.id IS NULL;
|
|
||||||
|
|
||||||
-- Add and update every Tender.ledger_entry_id (for rolling up old databases)
|
|
||||||
-- Takes a while to complete (~30s at time of writing)
|
|
||||||
ALTER TABLE `pmgr_tenders`
|
|
||||||
ADD `deposit_ledger_entry_id` INT UNSIGNED DEFAULT NULL
|
|
||||||
AFTER `nsf_ledger_entry_id`;
|
|
||||||
UPDATE
|
|
||||||
pmgr_tenders Tnd
|
|
||||||
JOIN pmgr_tender_types TndT ON TndT.id = Tnd.tender_type_id
|
|
||||||
JOIN pmgr_transactions T ON T.id = Tnd.deposit_transaction_id
|
|
||||||
JOIN pmgr_ledger_entries LE ON LE.transaction_id = T.id AND LE.account_id = TndT.account_id
|
|
||||||
JOIN pmgr_double_entries DE ON DE.debit_entry_id = LE.id OR DE.credit_entry_id = LE.id
|
|
||||||
JOIN pmgr_ledger_entries LEd ON (DE.debit_entry_id = LEd.id OR DE.credit_entry_id = LEd.id)
|
|
||||||
AND LEd.id <> LE.id
|
|
||||||
SET Tnd.deposit_ledger_entry_id = LEd.id;
|
|
||||||
|
|
||||||
|
|
||||||
-- Add auto_deposit and deposit_account_id to tenders
|
|
||||||
ALTER TABLE `pmgr_tender_types`
|
|
||||||
ADD `auto_deposit` TINYINT(1) UNSIGNED DEFAULT '0' NOT NULL
|
|
||||||
AFTER `tillable`;
|
|
||||||
ALTER TABLE `pmgr_tender_types`
|
|
||||||
ADD `deposit_account_id` INTEGER(10) UNSIGNED DEFAULT NULL
|
|
||||||
AFTER `account_id`;
|
|
||||||
|
|
||||||
|
|
||||||
-- Determine economic conditions
|
|
||||||
SELECT `status`, COUNT(id), SUM(rent) FROM pmgr_units
|
|
||||||
GROUP BY `status` WITH ROLLUP;
|
|
||||||
|
|
||||||
|
|
||||||
-- Check that transaction totals add up correctly
|
|
||||||
SELECT T.id, T.type, T.amount,
|
|
||||||
-- T.type, A.type, E.crdr,
|
|
||||||
SUM(IF(E.account_id = T.account_id,
|
|
||||||
IF(A.type IN ('ASSET','EXPENSE') XOR E.crdr='DEBIT',-1,1),0)
|
|
||||||
*E.amount) AS Tamt,
|
|
||||||
SUM(IF(E.account_id = T.account_id,
|
|
||||||
0,IF(A.type IN ('ASSET','EXPENSE') XOR E.crdr='DEBIT',-1,1))
|
|
||||||
*E.amount) AS Oamt,
|
|
||||||
COUNT(E.id) AS Ecnt
|
|
||||||
FROM pmgr_transactions T
|
|
||||||
-- LEFT JOIN pmgr_statement_entries E ON E.transaction_id = T.id
|
|
||||||
LEFT JOIN pmgr_ledger_entries E ON E.transaction_id = T.id
|
|
||||||
LEFT JOIN pmgr_accounts A ON A.id = T.account_id -- E.account_id
|
|
||||||
-- WHERE
|
|
||||||
-- E.account_id != T.account_id
|
|
||||||
GROUP BY T.id
|
|
||||||
HAVING
|
|
||||||
(T.type = 'INVOICE' AND Tamt <> T.amount)
|
|
||||||
OR
|
|
||||||
(T.type <> 'INVOICE' AND Oamt <> T.amount)
|
|
||||||
OR
|
|
||||||
(Tamt * -1 <> Oamt)
|
|
||||||
|
|
||||||
|
|
||||||
-- Verify that statement entries all have the correct type
|
|
||||||
SELECT SE.id, SE.type, T.id, T.type
|
|
||||||
FROM pmgr_statement_entries SE
|
|
||||||
LEFT JOIN pmgr_transactions T ON T.id = SE.transaction_id
|
|
||||||
WHERE
|
|
||||||
((T.type = 'RECEIPT' OR T.type = 'CREDIT_NOTE') AND
|
|
||||||
SE.type NOT IN ('DISBURSEMENT', 'WAIVER', 'REVERSAL', 'WRITEOFF', 'SURPLUS')
|
|
||||||
)
|
|
||||||
OR
|
|
||||||
((T.type = 'INVOICE' OR T.type = 'PAYMENT') AND
|
|
||||||
SE.type NOT IN ('CHARGE', 'PAYMENT', 'REFUND')
|
|
||||||
)
|
|
||||||
-- catch other types not considered in this query
|
|
||||||
OR T.type NOT IN ('RECEIPT', 'CREDIT_NOTE', 'INVOICE', 'PAYMENT')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- #################################################################
|
|
||||||
-- #################################################################
|
|
||||||
-- #################################################################
|
|
||||||
-- #################################################################
|
|
||||||
-- #################################################################
|
|
||||||
-- #################################################################
|
|
||||||
-- #################################################################
|
|
||||||
-- #################################################################
|
|
||||||
-- #################################################################
|
|
||||||
-- ## USER / GROUP
|
|
||||||
|
|
||||||
INSERT INTO pmgr_groups (`code`, `name`, `rank`)
|
|
||||||
VALUES('Owner', 'Owner Group', 25);
|
|
||||||
SET @o_gid = LAST_INSERT_ID();
|
|
||||||
|
|
||||||
INSERT INTO pmgr_groups (`code`, `name`, `rank`)
|
|
||||||
VALUES('Admin', 'Admin Group', 50);
|
|
||||||
SET @a_gid = LAST_INSERT_ID();
|
|
||||||
|
|
||||||
INSERT INTO pmgr_groups (`code`, `name`, `rank`)
|
|
||||||
VALUES('Manager', 'Manager Group', 75);
|
|
||||||
SET @m_gid = LAST_INSERT_ID();
|
|
||||||
|
|
||||||
INSERT INTO pmgr_groups (`code`, `name`)
|
|
||||||
VALUES('Temp', 'Temporary Help');
|
|
||||||
SET @t_gid = LAST_INSERT_ID();
|
|
||||||
|
|
||||||
INSERT INTO pmgr_users (`code`, `login`, `contact_id`)
|
|
||||||
VALUES('AP', 'abijah', 0);
|
|
||||||
SET @a_uid = LAST_INSERT_ID();
|
|
||||||
|
|
||||||
INSERT INTO pmgr_users (`code`, `login`, `contact_id`)
|
|
||||||
VALUES('SK', 'shirley', 0);
|
|
||||||
SET @s_uid = LAST_INSERT_ID();
|
|
||||||
|
|
||||||
INSERT INTO pmgr_users (`code`, `login`, `contact_id`)
|
|
||||||
VALUES('DE', 'dan', 0);
|
|
||||||
SET @d_uid = LAST_INSERT_ID();
|
|
||||||
|
|
||||||
INSERT INTO pmgr_users (`code`, `login`, `contact_id`)
|
|
||||||
VALUES('KD', 'kevin', 0);
|
|
||||||
SET @k_uid = LAST_INSERT_ID();
|
|
||||||
|
|
||||||
INSERT INTO pmgr_sites (`code`, `name`)
|
|
||||||
VALUES('VSS', 'Valley Storage');
|
|
||||||
SET @v_sid = LAST_INSERT_ID();
|
|
||||||
|
|
||||||
INSERT INTO pmgr_sites (`code`, `name`)
|
|
||||||
VALUES('FAKE', 'Fake Site');
|
|
||||||
SET @f_sid = LAST_INSERT_ID();
|
|
||||||
|
|
||||||
-- Site Membership
|
|
||||||
|
|
||||||
INSERT INTO pmgr_site_memberships (`site_id`, `user_id`, `group_id`)
|
|
||||||
VALUES(@v_sid, @a_uid, @o_gid);
|
|
||||||
INSERT INTO pmgr_site_memberships (`site_id`, `user_id`, `group_id`)
|
|
||||||
VALUES(@v_sid, @a_uid, @a_gid);
|
|
||||||
INSERT INTO pmgr_site_memberships (`site_id`, `user_id`, `group_id`)
|
|
||||||
VALUES(@v_sid, @a_uid, @m_gid);
|
|
||||||
INSERT INTO pmgr_site_memberships (`site_id`, `user_id`, `group_id`)
|
|
||||||
VALUES(@v_sid, @s_uid, @m_gid);
|
|
||||||
INSERT INTO pmgr_site_memberships (`site_id`, `user_id`, `group_id`)
|
|
||||||
VALUES(@v_sid, @d_uid, @t_gid);
|
|
||||||
INSERT INTO pmgr_site_memberships (`site_id`, `user_id`, `group_id`)
|
|
||||||
VALUES(@f_sid, @s_uid, @a_gid);
|
|
||||||
INSERT INTO pmgr_site_memberships (`site_id`, `user_id`, `group_id`)
|
|
||||||
VALUES(@f_sid, @s_uid, @m_gid);
|
|
||||||
INSERT INTO pmgr_site_memberships (`site_id`, `user_id`, `group_id`)
|
|
||||||
VALUES(@f_sid, @k_uid, @o_gid);
|
|
||||||
INSERT INTO pmgr_site_memberships (`site_id`, `user_id`, `group_id`)
|
|
||||||
VALUES(@f_sid, @d_uid, @t_gid);
|
|
||||||
|
|
||||||
|
|
||||||
-- Options
|
|
||||||
|
|
||||||
INSERT INTO pmgr_options (`name`) VALUES ('theme');
|
|
||||||
SET @t_oid = LAST_INSERT_ID();
|
|
||||||
INSERT INTO pmgr_options (`name`) VALUES ('menu');
|
|
||||||
SET @m_oid = LAST_INSERT_ID();
|
|
||||||
|
|
||||||
-- Default Option Values
|
|
||||||
|
|
||||||
INSERT INTO pmgr_option_values (`option_id`, `value`) VALUES (@t_oid, 'blue');
|
|
||||||
INSERT INTO pmgr_default_options (`option_value_id`) VALUES(LAST_INSERT_ID());
|
|
||||||
INSERT INTO pmgr_option_values (`option_id`, `value`) VALUES (@m_oid, 'basic');
|
|
||||||
INSERT INTO pmgr_default_options (`option_value_id`) VALUES(LAST_INSERT_ID());
|
|
||||||
|
|
||||||
-- Group options
|
|
||||||
|
|
||||||
INSERT INTO pmgr_option_values (`option_id`, `value`) VALUES (@t_oid, 'gold');
|
|
||||||
INSERT INTO pmgr_group_options (`group_id`, `option_value_id`)
|
|
||||||
VALUES(@o_gid, LAST_INSERT_ID());
|
|
||||||
INSERT INTO pmgr_option_values (`option_id`, `value`) VALUES (@t_oid, 'silver');
|
|
||||||
INSERT INTO pmgr_group_options (`group_id`, `option_value_id`)
|
|
||||||
VALUES(@a_gid, LAST_INSERT_ID());
|
|
||||||
INSERT INTO pmgr_option_values (`option_id`, `value`) VALUES (@t_oid, 'red');
|
|
||||||
INSERT INTO pmgr_group_options (`group_id`, `option_value_id`)
|
|
||||||
VALUES(@m_gid, LAST_INSERT_ID());
|
|
||||||
|
|
||||||
INSERT INTO pmgr_option_values (`option_id`, `value`) VALUES (@m_oid, 'advanced');
|
|
||||||
INSERT INTO pmgr_group_options (`group_id`, `option_value_id`)
|
|
||||||
VALUES(@o_gid, LAST_INSERT_ID());
|
|
||||||
INSERT INTO pmgr_option_values (`option_id`, `value`) VALUES (@m_oid, 'advanced');
|
|
||||||
INSERT INTO pmgr_group_options (`group_id`, `option_value_id`)
|
|
||||||
VALUES(@a_gid, LAST_INSERT_ID());
|
|
||||||
INSERT INTO pmgr_option_values (`option_id`, `value`) VALUES (@m_oid, 'restricted');
|
|
||||||
INSERT INTO pmgr_group_options (`group_id`, `option_value_id`)
|
|
||||||
VALUES(@t_gid, LAST_INSERT_ID());
|
|
||||||
|
|
||||||
-- User Options
|
|
||||||
INSERT INTO pmgr_option_values (`option_id`, `value`) VALUES (@m_oid, 'special');
|
|
||||||
INSERT INTO pmgr_user_options (`user_id`, `option_value_id`)
|
|
||||||
VALUES(@s_uid, LAST_INSERT_ID());
|
|
||||||
|
|
||||||
-- Site Options
|
|
||||||
INSERT INTO pmgr_option_values (`option_id`, `value`) VALUES (@t_oid, 'site-theme');
|
|
||||||
INSERT INTO pmgr_site_options (`site_id`, `option_value_id`)
|
|
||||||
VALUES(@f_sid, LAST_INSERT_ID());
|
|
||||||
|
|
||||||
|
|
||||||
-- SELECT U.id, P.name, MAX(P.access)
|
|
||||||
-- FROM pmgr_users U
|
|
||||||
-- LEFT JOIN pmgr_site_membership M ON M.user_id = U.id
|
|
||||||
-- LEFT JOIN pmgr_groups G ON G.id = M.group_id
|
|
||||||
-- LEFT JOIN pmgr_group_permissions P ON P.group_id = G.id
|
|
||||||
-- GROUP BY U.id, P.name
|
|
||||||
|
|
||||||
|
|
||||||
-- User access to site
|
|
||||||
SELECT U.id, U.login, COUNT(G.id) AS 'groups', MIN(G.rank) AS highest_rank
|
|
||||||
FROM pmgr_users U
|
|
||||||
JOIN pmgr_site_memberships M ON M.user_id = U.id
|
|
||||||
JOIN pmgr_sites S ON S.id = M.site_id
|
|
||||||
JOIN pmgr_groups G ON G.id = M.group_id
|
|
||||||
WHERE S.code = 'VSS'
|
|
||||||
GROUP BY U.id
|
|
||||||
|
|
||||||
|
|
||||||
-- User Options
|
|
||||||
SELECT O.id, O.name, O.default,
|
|
||||||
GROUP_CONCAT(Uopt.value) AS 'value', COUNT(U.id) AS 'count'
|
|
||||||
FROM pmgr_options O
|
|
||||||
LEFT JOIN pmgr_user_options Uopt ON Uopt.option_id = O.id
|
|
||||||
LEFT JOIN pmgr_users U ON U.id = Uopt.user_id
|
|
||||||
WHERE U.id = 1
|
|
||||||
GROUP BY O.id
|
|
||||||
|
|
||||||
-- Group Options
|
|
||||||
SELECT O.id, O.name, O.default,
|
|
||||||
GROUP_CONCAT(Gopt.value) AS 'value', COUNT(G.id) AS 'count'
|
|
||||||
FROM pmgr_options O
|
|
||||||
LEFT JOIN pmgr_group_options Gopt ON Gopt.option_id = O.id
|
|
||||||
LEFT JOIN pmgr_groups G ON G.id = Gopt.group_id
|
|
||||||
WHERE G.id = 1
|
|
||||||
GROUP BY O.id
|
|
||||||
|
|
||||||
|
|
||||||
-- Site Options
|
|
||||||
SELECT O.id, O.name, O.default,
|
|
||||||
GROUP_CONCAT(Sopt.value) AS 'value', COUNT(S.id) AS 'count'
|
|
||||||
FROM pmgr_options O
|
|
||||||
LEFT JOIN pmgr_site_options Sopt ON Sopt.option_id = O.id
|
|
||||||
LEFT JOIN pmgr_sites S ON S.id = Sopt.site_id
|
|
||||||
WHERE S.id = 1
|
|
||||||
GROUP BY O.id
|
|
||||||
|
|
||||||
|
|
||||||
-- Option value for member & site
|
|
||||||
SELECT O.id, O.name, O.default,
|
|
||||||
S.id AS site_id, Sopt.value,
|
|
||||||
G.id AS group_id, Gopt.value,
|
|
||||||
U.id AS user_id, Uopt.value
|
|
||||||
FROM pmgr_options O
|
|
||||||
LEFT JOIN pmgr_site_options Sopt ON Sopt.option_id = O.id
|
|
||||||
LEFT JOIN pmgr_sites S ON S.id = Sopt.site_id
|
|
||||||
LEFT JOIN pmgr_group_options Gopt ON Gopt.option_id = O.id
|
|
||||||
LEFT JOIN pmgr_groups G ON G.id = Gopt.group_id
|
|
||||||
LEFT JOIN pmgr_user_options Uopt ON Uopt.option_id = O.id
|
|
||||||
LEFT JOIN pmgr_users U ON U.id = Uopt.user_id
|
|
||||||
WHERE O.name = 'theme'
|
|
||||||
--GROUP BY O.id
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- Option value for member & site
|
|
||||||
-- 1) User
|
|
||||||
SET @sid = 1;
|
|
||||||
SET @uid = 1;
|
|
||||||
SET @oid = 1;
|
|
||||||
SELECT O.name, U.id, Uopt.value
|
|
||||||
FROM pmgr_options O
|
|
||||||
JOIN pmgr_user_options Uopt ON Uopt.option_id = O.id
|
|
||||||
JOIN pmgr_users U ON U.id = Uopt.user_id
|
|
||||||
-- JOIN pmgr_site_memberships M ON M.user_id = U.id
|
|
||||||
-- JOIN pmgr_groups G ON G.id = M.group_id
|
|
||||||
-- JOIN pmgr_sites S ON S.id = M.site_id
|
|
||||||
WHERE -- S.id = @sid AND
|
|
||||||
U.id = @uid AND O.id = @oid
|
|
||||||
;
|
|
||||||
|
|
||||||
-- 2) Group
|
|
||||||
SELECT O.name, G.rank, G.id, Gopt.value
|
|
||||||
FROM pmgr_options O
|
|
||||||
JOIN pmgr_group_options Gopt ON Gopt.option_id = O.id
|
|
||||||
JOIN pmgr_groups G ON G.id = Gopt.group_id
|
|
||||||
JOIN pmgr_site_memberships M ON M.group_id = G.id
|
|
||||||
JOIN pmgr_users U ON U.id = M.user_id
|
|
||||||
JOIN pmgr_sites S ON S.id = M.site_id
|
|
||||||
WHERE S.id = @sid AND U.id = @uid AND O.id = @oid
|
|
||||||
ORDER BY G.rank
|
|
||||||
;
|
|
||||||
|
|
||||||
-- 3) Site
|
|
||||||
SELECT O.name, S.id, Sopt.value
|
|
||||||
FROM pmgr_options O
|
|
||||||
JOIN pmgr_site_options Sopt ON Sopt.option_id = O.id
|
|
||||||
JOIN pmgr_sites S ON S.id = Sopt.site_id
|
|
||||||
-- JOIN pmgr_site_memberships M ON M.site_id = S.id
|
|
||||||
-- JOIN pmgr_groups G ON G.id = M.group_id
|
|
||||||
-- JOIN pmgr_users U ON U.id = M.user_id
|
|
||||||
WHERE S.id = @sid
|
|
||||||
-- AND U.id = @uid
|
|
||||||
AND O.id = @oid
|
|
||||||
;
|
|
||||||
|
|
||||||
-- 3) Default
|
|
||||||
SELECT O.name, O.default AS 'value'
|
|
||||||
FROM pmgr_options O
|
|
||||||
WHERE O.id = @oid
|
|
||||||
;
|
|
||||||
|
|
||||||
|
|
||||||
-- User Permissions
|
|
||||||
|
|
||||||
|
|
||||||
-- Group Permissions
|
|
||||||
|
|
||||||
-- All option values, in order
|
|
||||||
SELECT O.name, V.value,
|
|
||||||
U.id AS uid, G.id AS gid, S.id as sid,
|
|
||||||
Dopt.id AS did, G.rank
|
|
||||||
FROM pmgr_option_values V
|
|
||||||
JOIN pmgr_options O ON O.id = V.option_id
|
|
||||||
LEFT JOIN pmgr_user_options Uopt ON Uopt.option_value_id = V.id
|
|
||||||
LEFT JOIN pmgr_group_options Gopt ON Gopt.option_value_id = V.id
|
|
||||||
LEFT JOIN pmgr_site_options Sopt ON Sopt.option_value_id = V.id
|
|
||||||
LEFT JOIN pmgr_default_options Dopt ON Dopt.option_value_id = V.id
|
|
||||||
LEFT JOIN pmgr_groups G ON G.id = Gopt.group_id
|
|
||||||
LEFT JOIN pmgr_users U ON U.id = Uopt.user_id
|
|
||||||
LEFT JOIN pmgr_sites S ON S.id = Sopt.site_id
|
|
||||||
WHERE O.id = @oid
|
|
||||||
ORDER BY IF(U.id IS NOT NULL, 1,
|
|
||||||
IF (G.id IS NOT NULL, 2,
|
|
||||||
IF (S.id IS NOT NULL, 3, 4))) ASC,
|
|
||||||
IF (G.id IS NOT NULL, G.rank, 0) ASC
|
|
||||||
|
|
||||||
|
|
||||||
-- Option values relevant to the user and site, in order
|
|
||||||
SELECT O.name, V.value,
|
|
||||||
U.id AS uid, G.id AS gid, S.id as sid,
|
|
||||||
Dopt.id AS did, G.rank
|
|
||||||
FROM pmgr_option_values V
|
|
||||||
JOIN pmgr_options O ON O.id = V.option_id
|
|
||||||
LEFT JOIN pmgr_user_options Uopt ON Uopt.option_value_id = V.id
|
|
||||||
LEFT JOIN pmgr_group_options Gopt ON Gopt.option_value_id = V.id
|
|
||||||
LEFT JOIN pmgr_site_options Sopt ON Sopt.option_value_id = V.id
|
|
||||||
LEFT JOIN pmgr_default_options Dopt ON Dopt.option_value_id = V.id
|
|
||||||
LEFT JOIN pmgr_groups G ON G.id = Gopt.group_id
|
|
||||||
LEFT JOIN pmgr_users U ON U.id = Uopt.user_id
|
|
||||||
LEFT JOIN pmgr_sites S ON S.id = Sopt.site_id
|
|
||||||
JOIN pmgr_site_memberships M ON M.user_id = U.id AND M.site_id = S.id
|
|
||||||
WHERE S.id = @sid AND U.id = @uid AND O.id = @oid
|
|
||||||
ORDER BY IF(U.id IS NOT NULL, 1,
|
|
||||||
IF (G.id IS NOT NULL, 2,
|
|
||||||
IF (S.id IS NOT NULL, 3, 4))) ASC,
|
|
||||||
IF (G.id IS NOT NULL, G.rank, 0) ASC
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SET @sid = 1;
|
|
||||||
SET @uid = 1;
|
|
||||||
SET @oid = 1;
|
|
||||||
SELECT O.name, V.value,
|
|
||||||
U.id AS uid,
|
|
||||||
-- G.id AS gid,
|
|
||||||
S.id as sid,
|
|
||||||
Dopt.id AS did
|
|
||||||
-- G.rank
|
|
||||||
FROM pmgr_option_values V
|
|
||||||
JOIN pmgr_options O ON O.id = V.option_id
|
|
||||||
LEFT JOIN pmgr_user_options Uopt ON Uopt.option_value_id = V.id
|
|
||||||
LEFT JOIN pmgr_site_options Sopt ON Sopt.option_value_id = V.id
|
|
||||||
-- LEFT JOIN pmgr_users U ON U.id = Uopt.user_id
|
|
||||||
-- LEFT JOIN pmgr_group_options Gopt ON Gopt.option_value_id = V.id
|
|
||||||
LEFT JOIN pmgr_default_options Dopt ON Dopt.option_value_id = V.id
|
|
||||||
-- LEFT JOIN pmgr_groups G ON G.id = Gopt.group_id
|
|
||||||
LEFT JOIN pmgr_users U ON U.id = Uopt.user_id
|
|
||||||
LEFT JOIN pmgr_sites S ON S.id = Sopt.site_id
|
|
||||||
JOIN pmgr_site_memberships M ON M.user_id = U.id -- AND M.site_id = S.id
|
|
||||||
WHERE -- S.id = @sid AND U.id = @uid AND
|
|
||||||
O.id = @oid
|
|
||||||
ORDER BY IF(U.id IS NOT NULL, 1,
|
|
||||||
-- IF (G.id IS NOT NULL, 2,
|
|
||||||
IF (S.id IS NOT NULL, 3, 4)) -- ) ASC,
|
|
||||||
-- IF (G.id IS NOT NULL, G.rank, 0) ASC
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- ------------------------------------------------------------
|
|
||||||
-- ------------------------------------------------------------
|
|
||||||
-- ------------------------------------------------------------
|
|
||||||
-- Working version (without defaults)
|
|
||||||
SET @sid = 1;
|
|
||||||
SET @uid = 1;
|
|
||||||
SET @oid = 1;
|
|
||||||
SELECT O.name, O.id AS oid, V.value, V.id AS vid,
|
|
||||||
U.id AS uid,
|
|
||||||
G.id AS gid,
|
|
||||||
S.id AS sid,
|
|
||||||
-- Dopt.id AS did
|
|
||||||
G.rank
|
|
||||||
FROM pmgr_users U
|
|
||||||
JOIN pmgr_site_memberships M ON M.user_id = U.id
|
|
||||||
JOIN pmgr_sites S ON S.id = M.site_id
|
|
||||||
LEFT JOIN pmgr_groups G ON G.id = M.group_id
|
|
||||||
LEFT JOIN pmgr_user_options Uopt ON Uopt.user_id = U.id
|
|
||||||
LEFT JOIN pmgr_group_options Gopt ON Gopt.group_id = G.id
|
|
||||||
LEFT JOIN pmgr_site_options Sopt ON Sopt.site_id = S.id
|
|
||||||
LEFT JOIN pmgr_option_values V ON (V.id = Uopt.option_value_id OR
|
|
||||||
V.id = Gopt.option_value_id OR
|
|
||||||
V.id = Sopt.option_value_id)
|
|
||||||
JOIN pmgr_options O ON O.id = V.option_id
|
|
||||||
WHERE S.id = @sid AND U.id = @uid AND O.id = @oid
|
|
||||||
ORDER BY IF(U.id IS NOT NULL, 1,
|
|
||||||
IF (G.id IS NOT NULL, 2,
|
|
||||||
IF (S.id IS NOT NULL, 3, 4))) ASC,
|
|
||||||
IF (G.id IS NOT NULL, G.rank, 0) ASC
|
|
||||||
;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SET @sid = 1;
|
|
||||||
SET @uid = 1;
|
|
||||||
SET @oid = 1;
|
|
||||||
SELECT O.name, O.id AS oid, V.value, V.id AS vid,
|
|
||||||
U.id AS uid,
|
|
||||||
G.id AS gid,
|
|
||||||
S.id AS sid,
|
|
||||||
-- Dopt.id AS did
|
|
||||||
G.rank
|
|
||||||
FROM pmgr_options O
|
|
||||||
LEFT JOIN pmgr_option_values V ON V.option_id = O.id
|
|
||||||
-- Now have the option and all possible values
|
|
||||||
LEFT JOIN pmgr_user_options Uopt ON Uopt.option_value_id = V.id
|
|
||||||
LEFT JOIN pmgr_group_options Gopt ON Gopt.option_value_id = V.id
|
|
||||||
LEFT JOIN pmgr_site_options Sopt ON Sopt.option_value_id = V.id
|
|
||||||
-- Now have the user/group/site that each value applies to
|
|
||||||
LEFT JOIN pmgr_users U U ON Uopt.user_id = U.id OR Uopt.user_id IS NULL
|
|
||||||
-- Now restricted to our user
|
|
||||||
JOIN pmgr_site_memberships M ON M.user_id = U.id
|
|
||||||
JOIN pmgr_sites S ON S.id = M.site_id
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ON O.id = V.option_id
|
|
||||||
LEFT JOIN pmgr_groups G ON G.id = M.group_id
|
|
||||||
LEFT JOIN pmgr_option_values V ON (V.id = Uopt.option_value_id OR
|
|
||||||
V.id = Gopt.option_value_id OR
|
|
||||||
V.id = Sopt.option_value_id)
|
|
||||||
JOIN
|
|
||||||
WHERE S.id = @sid AND U.id = @uid AND O.id = @oid
|
|
||||||
ORDER BY IF(U.id IS NOT NULL, 1,
|
|
||||||
IF (G.id IS NOT NULL, 2,
|
|
||||||
IF (S.id IS NOT NULL, 3, 4))) ASC,
|
|
||||||
IF (G.id IS NOT NULL, G.rank, 0) ASC
|
|
||||||
;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SET @sid = 1;
|
|
||||||
SET @uid = 1;
|
|
||||||
SET @oid = 1;
|
|
||||||
SELECT O.name, O.id AS oid, V.value, V.id AS vid,
|
|
||||||
U.id AS uid,
|
|
||||||
G.id AS gid,
|
|
||||||
S.id AS sid,
|
|
||||||
-- Dopt.id AS did
|
|
||||||
G.rank
|
|
||||||
FROM pmgr_options O LEFT JOIN pmgr_option_values V ON V.option_id = O.id,
|
|
||||||
pmgr_users U
|
|
||||||
JOIN pmgr_site_memberships M ON M.user_id = U.id
|
|
||||||
JOIN pmgr_sites S ON S.id = M.site_id
|
|
||||||
LEFT JOIN pmgr_groups G ON G.id = M.group_id
|
|
||||||
LEFT JOIN pmgr_user_options Uopt ON Uopt.user_id = U.id
|
|
||||||
LEFT JOIN pmgr_group_options Gopt ON Gopt.group_id = G.id
|
|
||||||
LEFT JOIN pmgr_site_options Sopt ON Sopt.site_id = S.id,
|
|
||||||
WHERE S.id = @sid AND U.id = @uid AND O.id = @oid
|
|
||||||
AND (V.id = Uopt.option_value_id OR
|
|
||||||
V.id = Gopt.option_value_id OR
|
|
||||||
V.id = Sopt.option_value_id)
|
|
||||||
ORDER BY IF(U.id IS NOT NULL, 1,
|
|
||||||
IF (G.id IS NOT NULL, 2,
|
|
||||||
IF (S.id IS NOT NULL, 3, 4))) ASC,
|
|
||||||
IF (G.id IS NOT NULL, G.rank, 0) ASC
|
|
||||||
;
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
N - GATE
|
|
||||||
N - ACH / CREDIT CARD PROCESSING
|
|
||||||
Y - CREDIT CARD ENTRY
|
|
||||||
Y - ACH ENTRY
|
|
||||||
P - INVENTORY TRACKING / POS
|
|
||||||
Y - UNIT TYPES
|
|
||||||
Y - UNIT SIZES
|
|
||||||
Y - UNITS
|
|
||||||
Y - MOVE IN / OUT
|
|
||||||
Y - UNIT TRANSFERS
|
|
||||||
Y - LEASE TRACKING (PDF Generation)
|
|
||||||
Y - LETTERS (PDF Generation)
|
|
||||||
Y - REMINDERS
|
|
||||||
Y - MULTIPLE LATE RENT SCHEDULES (Tenant A vs Tenant B)
|
|
||||||
Y - ACCOUNTING (assign charges to accounts)
|
|
||||||
Y - DETAILED REPORTING (HTML & PDF)
|
|
||||||
Y - SITE MAP; HOT CLICKABLE
|
|
||||||
P - PROSPECTIVE TENANTS
|
|
||||||
Y - MARKETING
|
|
||||||
P - RESERVATIONS
|
|
||||||
P - MOVE OUT NOTICES
|
|
||||||
P - MULTI-SITE (One database, multiple sites)
|
|
||||||
Y - GENERATE GEOGRAPHIC MAP OF CUSTOMERS USING GOOGLE!
|
|
||||||
- Major advantage here... MapPoint only choice with competitors
|
|
||||||
Y - WEB BASED
|
|
||||||
Y - CUSTOMER VIEW / MANAGER VIEW
|
|
||||||
Y - CUSTOMERS CAN CREATE ACCOUNTS, VIEW HISTORY
|
|
||||||
Y - CUSTOMERS CAN SIGN UP FOR AUTO PAY
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
Operations to be functional
|
|
||||||
'X' marks functionality sufficiently completed
|
|
||||||
|
|
||||||
X - Create Customer ID/Account
|
|
||||||
X - Add Contact information to Customer
|
|
||||||
X - Move Customer into Unit
|
|
||||||
X - Enter Rent Concessions given
|
|
||||||
X - Asses Rent Charges
|
|
||||||
X - Asses Late Charges
|
|
||||||
X - Asses Security Deposits
|
|
||||||
X - Receive and record Checks
|
|
||||||
X - Receive and record Money Orders
|
|
||||||
X - Receive and record Cash
|
|
||||||
X - Receive and record ACH Deposits
|
|
||||||
X - Reverse rent charges (early moveout on prepaid occupancy)
|
|
||||||
X - Handle NSF checks
|
|
||||||
X - Assess NSF Fees
|
|
||||||
X - Determine Lease Paid-Through status
|
|
||||||
X - Report: List of customers overdue
|
|
||||||
X - Flag unit as overlocked
|
|
||||||
X - Flag unit as evicting
|
|
||||||
X - Flag unit as normal status
|
|
||||||
X - Flag unit as dirty
|
|
||||||
- Enter notes when communicating with Customer
|
|
||||||
X - Accept pre-payments
|
|
||||||
X - Record Customer Move-Out from Unit
|
|
||||||
X - Record utilization of Security Deposit
|
|
||||||
X - Record issuing of a refund
|
|
||||||
- Record Deposit into Petty Cash
|
|
||||||
- Record Payment from Petty Cash to expenses
|
|
||||||
X - Record Petty Cash to refund.
|
|
||||||
X - Write Off Bad Debt
|
|
||||||
X - Perform a Deposit
|
|
||||||
X - Close the Books (nightly / weekly, etc)
|
|
||||||
X - Determine Rents Collected for a given period.
|
|
||||||
223
todo.notes
223
todo.notes
@@ -1,223 +0,0 @@
|
|||||||
|
|
||||||
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).
|
|
||||||
|
|
||||||
NSF of an item with customer credit is broken.
|
|
||||||
|
|
||||||
Sub-Total is broken, since it will only subtotal the current
|
|
||||||
page of the grid. It needs to be implemented in SQL as it
|
|
||||||
was in early (VERY early) implementations. At that time, I
|
|
||||||
had to a use temporary variable to keep a running total. It
|
|
||||||
worked, but was MySQL specific.
|
|
||||||
|
|
||||||
Add a move-out charges field to the move-out page.
|
|
||||||
Otherwise, if the balance is zero, the lease will automatically
|
|
||||||
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.
|
|
||||||
|
|
||||||
Allow waiving a complete charge, even if it already has payments
|
|
||||||
applied (at the moment, we just can waive the charge balance).
|
|
||||||
|
|
||||||
Get Petty Cash working. We'll need to add one or more expense
|
|
||||||
accounts. We'll also need to implement purchase order
|
|
||||||
functionality, or at least simple an expense page.
|
|
||||||
|
|
||||||
Have a report indicating Needs-to-be-Locked. Allow manager
|
|
||||||
to go through this list and check off the units actually
|
|
||||||
locked (which will update the unit status).
|
|
||||||
|
|
||||||
Same as above, except needs-to-be-unlocked.
|
|
||||||
|
|
||||||
Make the default (initial) jqGrid sort order for balance be DESC.
|
|
||||||
|
|
||||||
Change menu to be
|
|
||||||
'Reports' (or 'Overview', or 'Summary')
|
|
||||||
'Activities'
|
|
||||||
- New Receipt
|
|
||||||
- New Customer
|
|
||||||
- Move-in
|
|
||||||
|
|
||||||
Add dynamic check to see if customer already exists before being
|
|
||||||
created. Ideally, check +/- a few characters to check for
|
|
||||||
alternate spellings. Same for contact.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
MUST reports:
|
|
||||||
- Delinquent customers
|
|
||||||
- Locked out units / customers
|
|
||||||
- To-Lock units
|
|
||||||
- Paid up until
|
|
||||||
|
|
||||||
WANT reports:
|
|
||||||
- ???
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
-- DONE !
|
|
||||||
|
|
||||||
|
|
||||||
VERIFY THAT OUR NEW BALANCE QUERY WORKS.
|
|
||||||
(The one that was added to lease). It works for
|
|
||||||
folks that have ledger entries, but I fear that the
|
|
||||||
inner join will prevent customers from showing up
|
|
||||||
in the list if they don't yet have any ledger entries
|
|
||||||
in account receivable. To resolve this we'll have to
|
|
||||||
go back to LEFT JOIN and check for NULL in our SUM()
|
|
||||||
statement.
|
|
||||||
|
|
||||||
Fix sorting on Lease list by Lease Number. Have it
|
|
||||||
reference ID instead.
|
|
||||||
|
|
||||||
Figure out why Brenda Harmon's lease #44, unit #B04, lists
|
|
||||||
the security deposit as $150. She's only paid $25, so it must
|
|
||||||
be a lease issue.
|
|
||||||
|
|
||||||
Modify LedgerEntry to have through_date, since a single
|
|
||||||
invoice could have charges for several months rent. It's
|
|
||||||
not clear whether due_date should also be moved to
|
|
||||||
LedgerEntry, since some charges could have different due
|
|
||||||
dates. The problem is that I can't picture an invoice
|
|
||||||
having more than one due date.
|
|
||||||
|
|
||||||
Consider adding a from_date to LedgerEntry as well.
|
|
||||||
|
|
||||||
Fix Customers index list. To replicate, add a brand
|
|
||||||
new customer. Select Customers. Notice it says
|
|
||||||
'Current Customers', but actually includes the new
|
|
||||||
one in the list.
|
|
||||||
|
|
||||||
There seems to be a problem with the account ledger for the
|
|
||||||
customer. To replicate, see Mancini's account (#47). There
|
|
||||||
are 4 entries in the Account ledger. One of them is was from
|
|
||||||
5/1/09. It's a receipt (Transaction #610, Entry #702). The
|
|
||||||
Transaction is for $111.33 as indicated, but the entry is only
|
|
||||||
for $16.33.
|
|
||||||
-- This was a problem with using notxgroup, the experimental
|
|
||||||
-- field that used to be hardcoded to false in ledger_entries.ctp
|
|
||||||
-- My rework eliminated that field, and everything was getting
|
|
||||||
-- grouped by transaction.
|
|
||||||
|
|
||||||
Figure out how to utilize the security deposit, whether
|
|
||||||
as part of move-out only, or as one of the payment options.
|
|
||||||
|
|
||||||
Having a grid of ledger entries grouped by transaction appears
|
|
||||||
to work, from the financial aspect, but the count of entries
|
|
||||||
is incorrect. The problem is the grouping only occurs after
|
|
||||||
the count, which it has to in order for the count to work. We
|
|
||||||
need to obliterate the group_by_tx parameter, and simply use
|
|
||||||
the transanction controller to generate the grid instead of
|
|
||||||
ledger_entries.
|
|
||||||
|
|
||||||
Handle a credit, ensuring that it's applied to new charges
|
|
||||||
- either automatically;
|
|
||||||
- by user opt-in to use credits when invoicing
|
|
||||||
- by user opt-in when entering a receipt
|
|
||||||
- by manually allowing a receipt of credits
|
|
||||||
|
|
||||||
Reconcile all entries of a ledger to the c/f entry when
|
|
||||||
"closing" the ledger and creating a new one.
|
|
||||||
|
|
||||||
Determine when each unit is paid up until. There is actually
|
|
||||||
two things here: invoiced up until, and paid up until. One or
|
|
||||||
both of these should be displayed on the Lease view page.
|
|
||||||
|
|
||||||
20090729: New Ledger doesn't seem to give a balance forward entry.
|
|
||||||
|
|
||||||
Sorting by Customer ID is broken. It must think it's already
|
|
||||||
sorted by ID because the first click shows the arrow as
|
|
||||||
DESC even though the sort is ASC. Subsequent clicks don't
|
|
||||||
change anything. You must sort on a different column first
|
|
||||||
then everything works.
|
|
||||||
- Not actually fixed in the app, although it's solved by
|
|
||||||
using jqGrid 3.5
|
|
||||||
|
|
||||||
Seems like security deposit is suddenly broken. I believe
|
|
||||||
the customer/lease infobox used to report only PAID
|
|
||||||
security deposits, but it now seems like it's reporting ALL
|
|
||||||
security deposits charged.
|
|
||||||
|
|
||||||
Customer Selection on the Receipt Page is broken.
|
|
||||||
(Selecting a row and waiting for the update).
|
|
||||||
|
|
||||||
Automatic assessment of rents, or at least for now, one
|
|
||||||
click manual mechanism to assess rents correctly for all
|
|
||||||
tenants.
|
|
||||||
|
|
||||||
Automatic assessment of late fees, or at least for now, one
|
|
||||||
click manual mechanism to assess late fees correctly for all
|
|
||||||
tenants.
|
|
||||||
|
|
||||||
Fix ACH deposits into bank. Make it happen automatically,
|
|
||||||
perhaps after 3 days. Without this, we cannot NSF an ACH
|
|
||||||
transaction.
|
|
||||||
|
|
||||||
Change the menu structure to be $menu['section']['item'], so that
|
|
||||||
items don't have to be added in order of section. Perhaps even
|
|
||||||
array(array(name, priority, items => array(name, priority, link)))
|
|
||||||
|
|
||||||
Change New Customer form to have contact 'New' radio pre-checked
|
|
||||||
|
|
||||||
Add explanatory information on the New Customer page
|
|
||||||
- Customer name can be omitted and will come from primary tenant.
|
|
||||||
- Phone numbers, etc can be added later directly to the contact
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user