Compare commits
277 Commits
initial_20
...
invoice_re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3313a18407 | ||
|
|
b2ab134996 | ||
|
|
fbb751d054 | ||
|
|
fff6eaeeca | ||
|
|
1408a3dcb3 | ||
|
|
9507bfddc8 | ||
|
|
aa682c9bb2 | ||
|
|
0c8649d1c5 | ||
|
|
405e20f37f | ||
|
|
75ff8a2a40 | ||
|
|
20c1284788 | ||
|
|
116b014332 | ||
|
|
8fcecb7092 | ||
|
|
8a36b441de | ||
|
|
b1914f7cca | ||
|
|
0649329dde | ||
|
|
50c4ee225f | ||
|
|
d1075a2ea2 | ||
|
|
6210838b22 | ||
|
|
f5b87fa6b0 | ||
|
|
1d8ef76efa | ||
|
|
60f43efdb7 | ||
|
|
abc5f1feff | ||
|
|
8b7c27b5db | ||
|
|
865d9ee617 | ||
|
|
059dbd3190 | ||
|
|
8a3c6ae21b | ||
|
|
03af4e731f | ||
|
|
2cd73ed9e8 | ||
|
|
b97d071bb4 | ||
|
|
6a0a77c116 | ||
|
|
d6be905c08 | ||
|
|
6e1c684a06 | ||
|
|
0c13ef5cda | ||
|
|
9529431be2 | ||
|
|
d2ac8019ee | ||
|
|
1994512d6e | ||
|
|
a462e9be1c | ||
|
|
ccf0138eee | ||
|
|
288e4c05de | ||
|
|
b3ca719517 | ||
|
|
b8fd17efcf | ||
|
|
ece7ab25ae | ||
|
|
860006ed38 | ||
|
|
e067af589c | ||
|
|
546766d9be | ||
|
|
4b43433d2d | ||
|
|
5a1fdedad0 | ||
|
|
6ce9eec1a4 | ||
|
|
d44007a358 | ||
|
|
8d2a544042 | ||
|
|
d9297d89ab | ||
|
|
46db9c8341 | ||
|
|
ad17023570 | ||
|
|
9cac8c26a9 | ||
|
|
90d990e0a5 | ||
|
|
1cb56894ce | ||
|
|
f2f389ee45 | ||
|
|
5877874e82 | ||
|
|
de5f4208eb | ||
|
|
6507009acc | ||
|
|
6e1eba03a0 | ||
|
|
7a31f5cbd2 | ||
|
|
112aa7cf59 | ||
|
|
372578f171 | ||
|
|
645458c081 | ||
|
|
1afaede12a | ||
|
|
5a4cfb0581 | ||
|
|
17b6986758 | ||
|
|
00b473ee4f | ||
|
|
3463ae329b | ||
|
|
b3bceef570 | ||
|
|
80ddeeed6f | ||
|
|
43787d6434 | ||
|
|
72c55459ca | ||
|
|
977b21ed96 | ||
|
|
e4132237b9 | ||
|
|
c2d2a1c400 | ||
|
|
208aaaa504 | ||
|
|
21aa2c1d26 | ||
|
|
d3959e92e5 | ||
|
|
60c4d950fa | ||
|
|
d7db5a32d6 | ||
|
|
1932a9c316 | ||
|
|
d09af4f475 | ||
|
|
437ebabfd3 | ||
|
|
686c58afea | ||
|
|
754e2327c7 | ||
|
|
aca9d13a7d | ||
|
|
311d8be646 | ||
|
|
f77281835d | ||
|
|
1ed98b5e39 | ||
|
|
a2cb53a83b | ||
|
|
dff8394e91 | ||
|
|
014fa0feb9 | ||
|
|
3aacbb94aa | ||
|
|
5f9b9e15cb | ||
|
|
1f95e835f8 | ||
|
|
f7f9da92f3 | ||
|
|
3f275b127b | ||
|
|
f4319364f2 | ||
|
|
54ded6173a | ||
|
|
b36d3117a3 | ||
|
|
06b8ff2ae9 | ||
|
|
40264d3c39 | ||
|
|
5007890d09 | ||
|
|
aab8a994c8 | ||
|
|
a8c91d8b22 | ||
|
|
d5d2d07894 | ||
|
|
7b3f774304 | ||
|
|
e17cf21351 | ||
|
|
807dc48375 | ||
|
|
8491d81496 | ||
|
|
1c164cebc1 | ||
|
|
db5eed24f6 | ||
|
|
c7d7c9e7e4 | ||
|
|
eba1267f00 | ||
|
|
240a16367b | ||
|
|
cb39f6f0eb | ||
|
|
cd07f51ff9 | ||
|
|
cba8e16be7 | ||
|
|
fbeed43e61 | ||
|
|
1d82e263ad | ||
|
|
aa12a1efa4 | ||
|
|
758a5f700c | ||
|
|
9aa598f81f | ||
|
|
e953f2709d | ||
|
|
96dd06b58a | ||
|
|
5fd783dc50 | ||
|
|
689a6dc7aa | ||
|
|
3e60f8d45e | ||
|
|
09cb297dc7 | ||
|
|
ab0e85824b | ||
|
|
6def9cbb02 | ||
|
|
c7d772be53 | ||
|
|
e584997805 | ||
|
|
b7e0ea8313 | ||
|
|
bb61de60ad | ||
|
|
bc3bcd8312 | ||
|
|
c59f48fb84 | ||
|
|
6844513253 | ||
|
|
dc850f4e8e | ||
|
|
dea1454dcd | ||
|
|
6a8d21dad7 | ||
|
|
27503ac4f9 | ||
|
|
f6401c92be | ||
|
|
d77dcfca75 | ||
|
|
a796e9e82d | ||
|
|
504f1e7cc0 | ||
|
|
591e1db81d | ||
|
|
1ae1b6a4f3 | ||
|
|
021c0626a3 | ||
|
|
63b2e7360b | ||
|
|
3ad0cc1d20 | ||
|
|
8d87a0698c | ||
|
|
44df78e69f | ||
|
|
707c9a87ef | ||
|
|
0558c35ebc | ||
|
|
2b2991a13a | ||
|
|
c1aedde374 | ||
|
|
0b69e065ae | ||
|
|
1c8cc70a28 | ||
|
|
c6f68861b3 | ||
|
|
ce4fa4131a | ||
|
|
80f8bd36d5 | ||
|
|
7aa1100cac | ||
|
|
b9c1a81c3b | ||
|
|
bd0bbd768d | ||
|
|
20b8908a00 | ||
|
|
ab51fd32d2 | ||
|
|
b780ebeb3e | ||
|
|
117e31af69 | ||
|
|
28b3f35318 | ||
|
|
2b8a525718 | ||
|
|
dc6e399fea | ||
|
|
1508f963d3 | ||
|
|
3270ad9bf0 | ||
|
|
febd216810 | ||
|
|
c8b781804a | ||
|
|
3e5ac64108 | ||
|
|
9b6830468e | ||
|
|
063aec6c3c | ||
|
|
a2ae522b2d | ||
|
|
ba218fbeeb | ||
|
|
2e67695154 | ||
|
|
a136fd5313 | ||
|
|
1e3774cad6 | ||
|
|
518f7836ac | ||
|
|
416e230da8 | ||
|
|
cd416ea5fa | ||
|
|
001b156333 | ||
|
|
df1e0daafd | ||
|
|
9331b0a412 | ||
|
|
fae90c3fa9 | ||
|
|
a83edef049 | ||
|
|
4ada3d5bac | ||
|
|
ede1053de4 | ||
|
|
ce9142ffe2 | ||
|
|
0270e5ea89 | ||
|
|
4d2b4779d4 | ||
|
|
fe7d7c6b0f | ||
|
|
435b0614b2 | ||
|
|
708910870c | ||
|
|
8b067bf676 | ||
|
|
388dbc0540 | ||
|
|
ce20a44836 | ||
|
|
1495bb3373 | ||
|
|
eaea52a862 | ||
|
|
271207629b | ||
|
|
edca01f98c | ||
|
|
23f4a29fc7 | ||
|
|
543e2daa43 | ||
|
|
3911b3303f | ||
|
|
d859cb4dee | ||
|
|
39071b39fb | ||
|
|
3dcdcb03eb | ||
|
|
41636f5c75 | ||
|
|
1890a0490e | ||
|
|
2b9369b823 | ||
|
|
4ec3db7b58 | ||
|
|
9f876b78de | ||
|
|
31c603c757 | ||
|
|
4d49ad6516 | ||
|
|
015e6b082d | ||
|
|
cdec4c3301 | ||
|
|
404323c6c1 | ||
|
|
d5dbabd94a | ||
|
|
c90830d41a | ||
|
|
f6ca79d1a9 | ||
|
|
5fab94011b | ||
|
|
af2d5c38f3 | ||
|
|
6b8d05f2a0 | ||
|
|
336ec3b643 | ||
|
|
b4d640f7c2 | ||
|
|
90a16c721e | ||
|
|
e7b4b21328 | ||
|
|
3be775f9b2 | ||
|
|
0278c77610 | ||
|
|
508a8b08aa | ||
|
|
c5bd8b4b16 | ||
|
|
a49b86898e | ||
|
|
55dd94681a | ||
|
|
2f91dd456a | ||
|
|
e32a5e5d4c | ||
|
|
cca48fe86a | ||
|
|
839d9c1697 | ||
|
|
c80c66d958 | ||
|
|
a2fa71038a | ||
|
|
d3c7011fc8 | ||
|
|
2c224dbc62 | ||
|
|
13b2283d76 | ||
|
|
3d89da7a61 | ||
|
|
99263920a3 | ||
|
|
8ab8d087e6 | ||
|
|
18b928411b | ||
|
|
8d062ab92e | ||
|
|
147c1e7097 | ||
|
|
760420bdc5 | ||
|
|
fb48baf575 | ||
|
|
d60c9721ca | ||
|
|
f8eb45a0b9 | ||
|
|
4277962e3b | ||
|
|
a60d69ba52 | ||
|
|
55b896a9f0 | ||
|
|
9f8d4fa9b2 | ||
|
|
4988d2717f | ||
|
|
136d8e845a | ||
|
|
190a9259d4 | ||
|
|
374843aeee | ||
|
|
52032180f3 | ||
|
|
d14b715a88 | ||
|
|
2a2d11ba0f | ||
|
|
2e07cb87a5 | ||
|
|
bb5b563738 | ||
|
|
f3ffa3c079 | ||
|
|
30b934823c | ||
|
|
948ae28616 |
3
build.cmd
Normal file
3
build.cmd
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
@echo off
|
||||||
|
%~dp0\scripts\sitelink2pmgr.pl %~dp0\db\schema.sql %~dp0db\vss.mdb %*
|
||||||
|
echo Done!
|
||||||
624
db/schema.sql
624
db/schema.sql
@@ -22,9 +22,12 @@
|
|||||||
-- may have to move this logic into the application :-/
|
-- may have to move this logic into the application :-/
|
||||||
|
|
||||||
|
|
||||||
DROP DATABASE IF EXISTS `property_manager`;
|
-- REVISIT <AP>: 20090511
|
||||||
CREATE DATABASE `property_manager`;
|
-- By not specifying the database, the script can
|
||||||
USE `property_manager`;
|
-- make the determination of which one to use.
|
||||||
|
-- DROP DATABASE IF EXISTS `property_manager`;
|
||||||
|
-- CREATE DATABASE `property_manager`;
|
||||||
|
-- USE `property_manager`;
|
||||||
|
|
||||||
|
|
||||||
-- ######################################################################
|
-- ######################################################################
|
||||||
@@ -177,7 +180,7 @@ CREATE TABLE `pmgr_contact_phones` (
|
|||||||
`ext` VARCHAR(6) DEFAULT NULL,
|
`ext` VARCHAR(6) DEFAULT NULL,
|
||||||
`comment` VARCHAR(255) DEFAULT NULL,
|
`comment` VARCHAR(255) DEFAULT NULL,
|
||||||
|
|
||||||
KEY `number_key` (`phone`),
|
UNIQUE KEY `number_key` (`phone`, `ext`),
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
@@ -192,7 +195,7 @@ CREATE TABLE `pmgr_contact_emails` (
|
|||||||
`email` VARCHAR(128) NOT NULL,
|
`email` VARCHAR(128) NOT NULL,
|
||||||
`comment` VARCHAR(255) DEFAULT NULL,
|
`comment` VARCHAR(255) DEFAULT NULL,
|
||||||
|
|
||||||
KEY `email_key` (`email`),
|
UNIQUE KEY `email_key` (`email`),
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
@@ -204,7 +207,7 @@ CREATE TABLE `pmgr_contact_emails` (
|
|||||||
DROP TABLE IF EXISTS `pmgr_contacts_methods`;
|
DROP TABLE IF EXISTS `pmgr_contacts_methods`;
|
||||||
CREATE TABLE `pmgr_contacts_methods` (
|
CREATE TABLE `pmgr_contacts_methods` (
|
||||||
`contact_id` INT(10) UNSIGNED NOT NULL,
|
`contact_id` INT(10) UNSIGNED NOT NULL,
|
||||||
`method` ENUM('POST',
|
`method` ENUM('ADDRESS',
|
||||||
'PHONE',
|
'PHONE',
|
||||||
'EMAIL')
|
'EMAIL')
|
||||||
NOT NULL,
|
NOT NULL,
|
||||||
@@ -448,6 +451,45 @@ CREATE TABLE `pmgr_site_areas` (
|
|||||||
-- ##
|
-- ##
|
||||||
|
|
||||||
|
|
||||||
|
-- ----------------------------------------------------------------------
|
||||||
|
-- ----------------------------------------------------------------------
|
||||||
|
-- TABLE pmgr_units
|
||||||
|
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `pmgr_units`;
|
||||||
|
CREATE TABLE `pmgr_units` (
|
||||||
|
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
|
`unit_size_id` INT(10) UNSIGNED NOT NULL,
|
||||||
|
`code` VARCHAR(12) NOT NULL, -- User style "id"
|
||||||
|
`name` VARCHAR(80) NOT NULL,
|
||||||
|
|
||||||
|
`status` ENUM('DELETED',
|
||||||
|
'DAMAGED',
|
||||||
|
'COMPANY',
|
||||||
|
'UNAVAILABLE',
|
||||||
|
'RESERVED',
|
||||||
|
'DIRTY',
|
||||||
|
'VACANT',
|
||||||
|
'OCCUPIED',
|
||||||
|
'LATE', -- NOT SURE
|
||||||
|
'LOCKED',
|
||||||
|
'LIENED')
|
||||||
|
NOT NULL DEFAULT 'VACANT',
|
||||||
|
|
||||||
|
`current_lease_id` INT(10) UNSIGNED DEFAULT NULL,
|
||||||
|
|
||||||
|
`sort_order` MEDIUMINT UNSIGNED NOT NULL,
|
||||||
|
`walk_order` MEDIUMINT UNSIGNED NOT NULL,
|
||||||
|
|
||||||
|
`deposit` FLOAT(12,2) DEFAULT NULL,
|
||||||
|
`rent` FLOAT(12,2) DEFAULT NULL,
|
||||||
|
|
||||||
|
`comment` VARCHAR(255) DEFAULT NULL,
|
||||||
|
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
|
||||||
-- ----------------------------------------------------------------------
|
-- ----------------------------------------------------------------------
|
||||||
-- ----------------------------------------------------------------------
|
-- ----------------------------------------------------------------------
|
||||||
-- TABLE pmgr_unit_types
|
-- TABLE pmgr_unit_types
|
||||||
@@ -480,46 +522,7 @@ CREATE TABLE `pmgr_unit_sizes` (
|
|||||||
`comment` VARCHAR(255) DEFAULT NULL,
|
`comment` VARCHAR(255) DEFAULT NULL,
|
||||||
|
|
||||||
`deposit` FLOAT(12,2) DEFAULT NULL,
|
`deposit` FLOAT(12,2) DEFAULT NULL,
|
||||||
`amount` FLOAT(12,2) DEFAULT NULL,
|
`rent` FLOAT(12,2) DEFAULT NULL,
|
||||||
|
|
||||||
PRIMARY KEY (`id`)
|
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
|
||||||
|
|
||||||
|
|
||||||
-- ----------------------------------------------------------------------
|
|
||||||
-- ----------------------------------------------------------------------
|
|
||||||
-- TABLE pmgr_units
|
|
||||||
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `pmgr_units`;
|
|
||||||
CREATE TABLE `pmgr_units` (
|
|
||||||
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
||||||
`unit_size_id` INT(10) UNSIGNED NOT NULL,
|
|
||||||
`code` VARCHAR(12) NOT NULL, -- User style "id"
|
|
||||||
`name` VARCHAR(80) NOT NULL,
|
|
||||||
|
|
||||||
`status` ENUM('DELETED',
|
|
||||||
'DAMAGED',
|
|
||||||
'COMPANY',
|
|
||||||
'UNAVAILABLE',
|
|
||||||
'RESERVED',
|
|
||||||
'DIRTY',
|
|
||||||
'VACANT',
|
|
||||||
'OCCUPIED',
|
|
||||||
'LATE', -- NOT SURE
|
|
||||||
'LOCKED',
|
|
||||||
'LIENED')
|
|
||||||
NOT NULL DEFAULT 'VACANT',
|
|
||||||
|
|
||||||
`current_lease_id` INT(10) UNSIGNED DEFAULT NULL,
|
|
||||||
|
|
||||||
`sort_order` MEDIUMINT UNSIGNED NOT NULL,
|
|
||||||
`walk_order` MEDIUMINT UNSIGNED NOT NULL,
|
|
||||||
|
|
||||||
`deposit` FLOAT(12,2) DEFAULT NULL,
|
|
||||||
`amount` FLOAT(12,2) DEFAULT NULL,
|
|
||||||
|
|
||||||
`comment` VARCHAR(255) DEFAULT NULL,
|
|
||||||
|
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||||
@@ -619,25 +622,72 @@ CREATE TABLE `pmgr_actions_late_schedules` (
|
|||||||
-- ######################################################################
|
-- ######################################################################
|
||||||
-- ######################################################################
|
-- ######################################################################
|
||||||
-- ##
|
-- ##
|
||||||
-- ## LEASES
|
-- ## CUSTOMERS
|
||||||
-- ##
|
-- ##
|
||||||
|
|
||||||
|
|
||||||
-- ----------------------------------------------------------------------
|
-- ----------------------------------------------------------------------
|
||||||
-- ----------------------------------------------------------------------
|
-- ----------------------------------------------------------------------
|
||||||
-- TABLE pmgr_lease_types
|
-- TABLE pmgr_customers
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `pmgr_lease_types`;
|
DROP TABLE IF EXISTS `pmgr_customers`;
|
||||||
CREATE TABLE `pmgr_lease_types` (
|
CREATE TABLE `pmgr_customers` (
|
||||||
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
`code` VARCHAR(12) NOT NULL, -- User style "id"
|
|
||||||
|
-- Customer name may be the same as the primary contact
|
||||||
|
-- or it may entirely independent of that person.
|
||||||
`name` VARCHAR(80) NOT NULL,
|
`name` VARCHAR(80) NOT NULL,
|
||||||
|
|
||||||
|
-- Primary Contact... every customer must have one
|
||||||
|
-- (and presumably, most customers will _be_ one).
|
||||||
|
-- REVISIT <AP> 20090612:
|
||||||
|
-- Does this contact also get added to the
|
||||||
|
-- contacts_customers table?
|
||||||
|
`primary_contact_id` INT(10) UNSIGNED NOT NULL,
|
||||||
|
|
||||||
`comment` VARCHAR(255) DEFAULT NULL,
|
`comment` VARCHAR(255) DEFAULT NULL,
|
||||||
|
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
|
||||||
|
-- ----------------------------------------------------------------------
|
||||||
|
-- ----------------------------------------------------------------------
|
||||||
|
-- TABLE pmgr_contacts_customers
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `pmgr_contacts_customers`;
|
||||||
|
CREATE TABLE `pmgr_contacts_customers` (
|
||||||
|
`contact_id` INT(10) UNSIGNED NOT NULL,
|
||||||
|
`customer_id` INT(10) UNSIGNED NOT NULL,
|
||||||
|
|
||||||
|
-- What type of contact is this for the lease?
|
||||||
|
`type` ENUM('TENANT', -- TENANT
|
||||||
|
'ALTERNATE') -- ALTERNATE CONTACT ONLY
|
||||||
|
NOT NULL DEFAULT 'TENANT',
|
||||||
|
|
||||||
|
-- If the tenant is active as part of the lease
|
||||||
|
`active` TINYINT DEFAULT 1,
|
||||||
|
|
||||||
|
`comment` VARCHAR(255) DEFAULT NULL,
|
||||||
|
|
||||||
|
PRIMARY KEY (`customer_id`, `contact_id`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- ######################################################################
|
||||||
|
-- ######################################################################
|
||||||
|
-- ######################################################################
|
||||||
|
-- ######################################################################
|
||||||
|
-- ######################################################################
|
||||||
|
-- ######################################################################
|
||||||
|
-- ######################################################################
|
||||||
|
-- ######################################################################
|
||||||
|
-- ######################################################################
|
||||||
|
-- ##
|
||||||
|
-- ## LEASES
|
||||||
|
-- ##
|
||||||
|
|
||||||
|
|
||||||
-- ----------------------------------------------------------------------
|
-- ----------------------------------------------------------------------
|
||||||
-- ----------------------------------------------------------------------
|
-- ----------------------------------------------------------------------
|
||||||
-- TABLE pmgr_leases
|
-- TABLE pmgr_leases
|
||||||
@@ -652,23 +702,23 @@ CREATE TABLE `pmgr_leases` (
|
|||||||
|
|
||||||
`lease_type_id` INT(10) UNSIGNED NOT NULL,
|
`lease_type_id` INT(10) UNSIGNED NOT NULL,
|
||||||
`unit_id` INT(10) UNSIGNED NOT NULL,
|
`unit_id` INT(10) UNSIGNED NOT NULL,
|
||||||
`primary_contact_id` INT(10) UNSIGNED DEFAULT NULL, -- NOT NULL,
|
`customer_id` INT(10) UNSIGNED NOT NULL,
|
||||||
`late_schedule_id` INT(10) UNSIGNED DEFAULT NULL,
|
`late_schedule_id` INT(10) UNSIGNED DEFAULT NULL,
|
||||||
|
|
||||||
`lease_date` DATE NOT NULL,
|
`lease_date` DATE NOT NULL,
|
||||||
`movein_planed_date` DATE DEFAULT NULL,
|
`movein_planned_date` DATE DEFAULT NULL,
|
||||||
`movein_date` DATE DEFAULT NULL,
|
`movein_date` DATE DEFAULT NULL,
|
||||||
`moveout_date` DATE DEFAULT NULL,
|
`moveout_date` DATE DEFAULT NULL,
|
||||||
`moveout_planed_date` DATE DEFAULT NULL,
|
`moveout_planned_date` DATE DEFAULT NULL,
|
||||||
`notice_given_date` DATE DEFAULT NULL,
|
`notice_given_date` DATE DEFAULT NULL,
|
||||||
`notice_received_date` DATE DEFAULT NULL,
|
`notice_received_date` DATE DEFAULT NULL,
|
||||||
`close_date` DATE DEFAULT NULL,
|
`close_date` DATE DEFAULT NULL,
|
||||||
|
|
||||||
`deposit` FLOAT(12,2) DEFAULT NULL,
|
`deposit` FLOAT(12,2) DEFAULT NULL,
|
||||||
`amount` FLOAT(12,2) DEFAULT NULL,
|
`rent` FLOAT(12,2) DEFAULT NULL,
|
||||||
|
|
||||||
`next_amount` FLOAT(12,2) DEFAULT NULL,
|
`next_rent` FLOAT(12,2) DEFAULT NULL,
|
||||||
`next_amount_date` DATE DEFAULT NULL,
|
`next_rent_date` DATE DEFAULT NULL,
|
||||||
|
|
||||||
`comment` VARCHAR(255) DEFAULT NULL,
|
`comment` VARCHAR(255) DEFAULT NULL,
|
||||||
|
|
||||||
@@ -678,24 +728,16 @@ CREATE TABLE `pmgr_leases` (
|
|||||||
|
|
||||||
-- ----------------------------------------------------------------------
|
-- ----------------------------------------------------------------------
|
||||||
-- ----------------------------------------------------------------------
|
-- ----------------------------------------------------------------------
|
||||||
-- TABLE pmgr_contacts_leases
|
-- TABLE pmgr_lease_types
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `pmgr_contacts_leases`;
|
|
||||||
CREATE TABLE `pmgr_contacts_leases` (
|
|
||||||
`lease_id` INT(10) UNSIGNED NOT NULL,
|
|
||||||
`contact_id` INT(10) UNSIGNED NOT NULL,
|
|
||||||
|
|
||||||
-- What type of contact is this for the lease?
|
|
||||||
`type` ENUM('TENANT', -- TENANT
|
|
||||||
'ALTERNATE') -- ALTERNATE CONTACT ONLY
|
|
||||||
NOT NULL DEFAULT 'TENANT',
|
|
||||||
|
|
||||||
-- If the tenant is active as part of the lease
|
|
||||||
`active` TINYINT DEFAULT 1,
|
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `pmgr_lease_types`;
|
||||||
|
CREATE TABLE `pmgr_lease_types` (
|
||||||
|
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
|
`code` VARCHAR(12) NOT NULL, -- User style "id"
|
||||||
|
`name` VARCHAR(80) NOT NULL,
|
||||||
`comment` VARCHAR(255) DEFAULT NULL,
|
`comment` VARCHAR(255) DEFAULT NULL,
|
||||||
|
|
||||||
PRIMARY KEY (`lease_id`, `contact_id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
|
||||||
@@ -726,7 +768,7 @@ CREATE TABLE `pmgr_reservations` (
|
|||||||
-- If NULL, `id` will be used
|
-- If NULL, `id` will be used
|
||||||
`number` VARCHAR(20) DEFAULT NULL,
|
`number` VARCHAR(20) DEFAULT NULL,
|
||||||
|
|
||||||
`contact_id` INT(10) UNSIGNED NOT NULL,
|
`customer_id` INT(10) UNSIGNED NOT NULL,
|
||||||
`deposit` FLOAT(12,2) DEFAULT NULL,
|
`deposit` FLOAT(12,2) DEFAULT NULL,
|
||||||
|
|
||||||
`reservation_date` DATE NOT NULL,
|
`reservation_date` DATE NOT NULL,
|
||||||
@@ -784,104 +826,86 @@ DROP TABLE IF EXISTS `pmgr_accounts`;
|
|||||||
CREATE TABLE `pmgr_accounts` (
|
CREATE TABLE `pmgr_accounts` (
|
||||||
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
|
|
||||||
|
`type` ENUM('ASSET',
|
||||||
|
'LIABILITY',
|
||||||
|
'EQUITY',
|
||||||
|
'INCOME',
|
||||||
|
'EXPENSE')
|
||||||
|
NOT NULL DEFAULT 'ASSET',
|
||||||
|
|
||||||
|
-- Accounts Receivable / Accounts Payable
|
||||||
|
-- If this is a trackable account, any credit posted
|
||||||
|
-- to an ASSET OR EXPENSE account should have an
|
||||||
|
-- entry posted to the reconciliations table (unless
|
||||||
|
-- it is a "pre-payment" of sorts, in which case the
|
||||||
|
-- reconciliation will have to wait for the debit).
|
||||||
|
-- For LIABILITY, EQUITY, and INCOME, the opposite
|
||||||
|
-- is true, with reconciliations posted, under
|
||||||
|
-- normal circumstances, when a debit occurs.
|
||||||
|
`trackable` TINYINT(1) UNSIGNED NOT NULL DEFAULT 1,
|
||||||
|
`tillable` TINYINT(1) UNSIGNED NOT NULL DEFAULT 0, -- Does manager collect by hand?
|
||||||
|
`depositable` TINYINT(1) UNSIGNED NOT NULL DEFAULT 0, -- Does this account receive deposits?
|
||||||
|
`chargeable` TINYINT(1) UNSIGNED NOT NULL DEFAULT 0, -- Can be used for charges?
|
||||||
|
`payable` TINYINT(1) UNSIGNED NOT NULL DEFAULT 0, -- Can be used for payments?
|
||||||
|
`refundable` TINYINT(1) UNSIGNED NOT NULL DEFAULT 0, -- Can be used for refunds?
|
||||||
|
|
||||||
|
-- Security Level
|
||||||
|
`level` INT UNSIGNED DEFAULT 10,
|
||||||
|
|
||||||
`name` VARCHAR(80) NOT NULL,
|
`name` VARCHAR(80) NOT NULL,
|
||||||
`external_account` INT(10) UNSIGNED DEFAULT NULL,
|
`external_account` INT(10) UNSIGNED DEFAULT NULL,
|
||||||
`external_name` VARCHAR(80) DEFAULT NULL,
|
`external_name` VARCHAR(80) DEFAULT NULL,
|
||||||
|
|
||||||
`comment` VARCHAR(255) DEFAULT NULL,
|
`comment` VARCHAR(255) DEFAULT NULL,
|
||||||
|
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
LOCK TABLES `pmgr_accounts` WRITE;
|
||||||
|
INSERT INTO `pmgr_accounts` (`type`, `name`, `level`)
|
||||||
-- ######################################################################
|
|
||||||
-- ######################################################################
|
|
||||||
-- ######################################################################
|
|
||||||
-- ######################################################################
|
|
||||||
-- ######################################################################
|
|
||||||
-- ######################################################################
|
|
||||||
-- ######################################################################
|
|
||||||
-- ######################################################################
|
|
||||||
-- ######################################################################
|
|
||||||
-- ##
|
|
||||||
-- ## CHARGES
|
|
||||||
-- ##
|
|
||||||
|
|
||||||
|
|
||||||
-- ----------------------------------------------------------------------
|
|
||||||
-- ----------------------------------------------------------------------
|
|
||||||
-- TABLE pmgr_charge_types
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `pmgr_charge_types`;
|
|
||||||
CREATE TABLE `pmgr_charge_types` (
|
|
||||||
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
||||||
|
|
||||||
`name` VARCHAR(80) NOT NULL,
|
|
||||||
`comment` VARCHAR(255) DEFAULT NULL,
|
|
||||||
`account_id` INT(10) UNSIGNED NOT NULL, -- quickbooks tracking
|
|
||||||
|
|
||||||
PRIMARY KEY (`id`)
|
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
|
||||||
|
|
||||||
LOCK TABLES `pmgr_charge_types` WRITE;
|
|
||||||
INSERT INTO `pmgr_charge_types` (`id`, `name`, `account_id`)
|
|
||||||
VALUES
|
VALUES
|
||||||
(1, 'Security Deposit', 0),
|
('EQUITY', 'Equity', 1),
|
||||||
(2, 'Rent', 0),
|
('LIABILITY', 'Loan', 1);
|
||||||
(3, 'Late Charge', 0);
|
INSERT INTO `pmgr_accounts` (`type`, `name`)
|
||||||
|
VALUES
|
||||||
|
('ASSET', 'A/R' ),
|
||||||
|
('ASSET', 'Invoice' ),
|
||||||
|
('ASSET', 'Receipt' ),
|
||||||
|
-- REVISIT <AP>: 20090710 : We don't really need NSF, as it
|
||||||
|
-- will always run a zero balance. However, it will help
|
||||||
|
-- us identify how serious the NSF situation is.
|
||||||
|
('ASSET', 'NSF' ),
|
||||||
|
('LIABILITY', 'A/P' );
|
||||||
|
INSERT INTO `pmgr_accounts` (`type`, `name`, `tillable`, `payable`, `refundable`)
|
||||||
|
VALUES
|
||||||
|
('ASSET', 'Cash', 1, 1, 1),
|
||||||
|
('ASSET', 'Check', 1, 1, 0),
|
||||||
|
('ASSET', 'Money Order', 1, 1, 0),
|
||||||
|
('ASSET', 'ACH', 0, 1, 0),
|
||||||
|
('EXPENSE', 'Concession', 0, 1, 0);
|
||||||
|
INSERT INTO `pmgr_accounts` (`type`, `name`, `refundable`, `depositable`)
|
||||||
|
VALUES
|
||||||
|
-- REVISIT <AP>: 20090710 : We probably don't really want petty cash depositable.
|
||||||
|
-- This is just for testing our deposit code
|
||||||
|
('ASSET', 'Petty Cash', 1, 1);
|
||||||
|
INSERT INTO `pmgr_accounts` (`type`, `name`, `chargeable`, `trackable`)
|
||||||
|
VALUES
|
||||||
|
('LIABILITY', 'Tax', 1, 1),
|
||||||
|
('LIABILITY', 'Security Deposit', 1, 1),
|
||||||
|
('INCOME', 'Rent', 1, 0),
|
||||||
|
('INCOME', 'Late Charge', 1, 0),
|
||||||
|
('INCOME', 'NSF Charge', 1, 0),
|
||||||
|
('INCOME', 'Damage', 1, 0);
|
||||||
|
INSERT INTO `pmgr_accounts` (`type`, `name`, `depositable`, `trackable`)
|
||||||
|
VALUES
|
||||||
|
('ASSET', 'Bank', 1, 0);
|
||||||
|
INSERT INTO `pmgr_accounts` (`type`, `name`, `trackable`)
|
||||||
|
VALUES
|
||||||
|
('EXPENSE', 'Bad Debt', 0),
|
||||||
|
('EXPENSE', 'Maintenance', 0);
|
||||||
UNLOCK TABLES;
|
UNLOCK TABLES;
|
||||||
|
|
||||||
|
|
||||||
-- ----------------------------------------------------------------------
|
|
||||||
-- ----------------------------------------------------------------------
|
|
||||||
-- TABLE pmgr_charges
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `pmgr_charges`;
|
|
||||||
CREATE TABLE `pmgr_charges` (
|
|
||||||
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
||||||
|
|
||||||
`charge_type_id` INT(10) UNSIGNED NOT NULL,
|
|
||||||
`lease_id` INT(10) UNSIGNED NOT NULL,
|
|
||||||
`charge_date` DATE NOT NULL,
|
|
||||||
`charge_to_date` DATE DEFAULT NULL,
|
|
||||||
`due_date` DATE DEFAULT NULL,
|
|
||||||
`amount` FLOAT(12,2) NOT NULL,
|
|
||||||
`tax` FLOAT(12,2) NOT NULL,
|
|
||||||
`total` FLOAT(12,2) NOT NULL,
|
|
||||||
`comment` VARCHAR(255) DEFAULT NULL,
|
|
||||||
|
|
||||||
PRIMARY KEY (`id`)
|
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
|
||||||
|
|
||||||
|
|
||||||
-- -- ----------------------------------------------------------------------
|
|
||||||
-- -- ----------------------------------------------------------------------
|
|
||||||
-- -- TABLE pmgr_invoices
|
|
||||||
|
|
||||||
-- DROP TABLE IF EXISTS `pmgr_invoices`;
|
|
||||||
-- CREATE TABLE `pmgr_invoices` (
|
|
||||||
-- `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
||||||
-- `stamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
|
|
||||||
-- `comment` VARCHAR(255) DEFAULT NULL,
|
|
||||||
|
|
||||||
-- PRIMARY KEY (`id`)
|
|
||||||
-- ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
|
||||||
|
|
||||||
|
|
||||||
-- -- ----------------------------------------------------------------------
|
|
||||||
-- -- ----------------------------------------------------------------------
|
|
||||||
-- -- TABLE pmgr_charges_invoices
|
|
||||||
|
|
||||||
-- DROP TABLE IF EXISTS `pmgr_charges_invoices`;
|
|
||||||
-- CREATE TABLE `pmgr_charges_invoices` (
|
|
||||||
-- `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
||||||
-- `charge_id` INT(10) UNSIGNED NOT NULL,
|
|
||||||
-- `invoice_id` INT(10) UNSIGNED NOT NULL,
|
|
||||||
-- `amount` FLOAT(12,2) NOT NULL,
|
|
||||||
-- PRIMARY KEY (`id`)
|
|
||||||
-- ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
|
||||||
|
|
||||||
|
|
||||||
-- ######################################################################
|
-- ######################################################################
|
||||||
-- ######################################################################
|
-- ######################################################################
|
||||||
@@ -893,50 +917,30 @@ CREATE TABLE `pmgr_charges` (
|
|||||||
-- ######################################################################
|
-- ######################################################################
|
||||||
-- ######################################################################
|
-- ######################################################################
|
||||||
-- ##
|
-- ##
|
||||||
-- ## PAYMENTS
|
-- ## LEDGERS
|
||||||
-- ##
|
-- ##
|
||||||
|
|
||||||
|
|
||||||
-- ----------------------------------------------------------------------
|
-- ----------------------------------------------------------------------
|
||||||
-- ----------------------------------------------------------------------
|
-- ----------------------------------------------------------------------
|
||||||
-- TABLE pmgr_payment_types
|
-- TABLE pmgr_ledgers
|
||||||
|
--
|
||||||
|
-- REVISIT <AP>: 20090605
|
||||||
|
-- We may not really need a ledgers table.
|
||||||
|
-- It's not clear to me though, as we very
|
||||||
|
-- possibly need to close out certain
|
||||||
|
-- ledgers every so often, and just carry
|
||||||
|
-- the balance forward (year end, etc).
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `pmgr_payment_types`;
|
DROP TABLE IF EXISTS `pmgr_ledgers`;
|
||||||
CREATE TABLE `pmgr_payment_types` (
|
CREATE TABLE `pmgr_ledgers` (
|
||||||
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
|
|
||||||
`name` VARCHAR(80) NOT NULL,
|
`account_id` INT(10) UNSIGNED NOT NULL,
|
||||||
`comment` VARCHAR(255) DEFAULT NULL,
|
`sequence` INT(10) UNSIGNED DEFAULT 1,
|
||||||
`tillable` TINYINT(1) NOT NULL DEFAULT 1, -- Does manager collect by hand?
|
|
||||||
|
|
||||||
PRIMARY KEY (`id`)
|
`prior_ledger_id` INT(10) UNSIGNED DEFAULT NULL,
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
`close_id` INT(10) UNSIGNED DEFAULT NULL,
|
||||||
|
|
||||||
LOCK TABLES `pmgr_payment_types` WRITE;
|
|
||||||
INSERT INTO `pmgr_payment_types` (`id`, `name`, `tillable`)
|
|
||||||
VALUES
|
|
||||||
(1, 'Cash', 1),
|
|
||||||
(2, 'Check', 1),
|
|
||||||
(3, 'Money Order', 1),
|
|
||||||
(4, 'ACH', 0),
|
|
||||||
(5, 'Debit Card', 0),
|
|
||||||
(6, 'Credit Card', 0),
|
|
||||||
(7, 'Other Tillable', 1),
|
|
||||||
(8, 'Other Non-Tillable', 0);
|
|
||||||
UNLOCK TABLES;
|
|
||||||
|
|
||||||
|
|
||||||
-- ----------------------------------------------------------------------
|
|
||||||
-- ----------------------------------------------------------------------
|
|
||||||
-- TABLE pmgr_payments
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `pmgr_payments`;
|
|
||||||
CREATE TABLE `pmgr_payments` (
|
|
||||||
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
||||||
|
|
||||||
`receipt_id` INT(10) UNSIGNED NOT NULL,
|
|
||||||
`payment_type_id` INT(10) UNSIGNED NOT NULL,
|
|
||||||
`amount` FLOAT(12,2) NOT NULL,
|
|
||||||
|
|
||||||
`comment` VARCHAR(255) DEFAULT NULL,
|
`comment` VARCHAR(255) DEFAULT NULL,
|
||||||
|
|
||||||
@@ -944,126 +948,39 @@ CREATE TABLE `pmgr_payments` (
|
|||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- ######################################################################
|
|
||||||
-- ######################################################################
|
|
||||||
-- ######################################################################
|
|
||||||
-- ######################################################################
|
|
||||||
-- ######################################################################
|
|
||||||
-- ######################################################################
|
|
||||||
-- ######################################################################
|
|
||||||
-- ######################################################################
|
|
||||||
-- ######################################################################
|
|
||||||
-- ##
|
|
||||||
-- ## CREDITS
|
|
||||||
-- ##
|
|
||||||
|
|
||||||
|
|
||||||
-- ----------------------------------------------------------------------
|
-- ----------------------------------------------------------------------
|
||||||
-- ----------------------------------------------------------------------
|
-- ----------------------------------------------------------------------
|
||||||
-- TABLE pmgr_credit_types
|
-- TABLE pmgr_closes
|
||||||
|
|
||||||
-- DROP TABLE IF EXISTS `pmgr_credit_types`;
|
DROP TABLE IF EXISTS `pmgr_closes`;
|
||||||
-- CREATE TABLE `pmgr_credit_types` (
|
CREATE TABLE `pmgr_closes` (
|
||||||
-- `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
||||||
|
|
||||||
-- `name` VARCHAR(80) NOT NULL,
|
|
||||||
-- `comment` VARCHAR(255) DEFAULT NULL,
|
|
||||||
-- `account_id` INT(10) UNSIGNED NOT NULL, -- quickbooks tracking
|
|
||||||
|
|
||||||
-- PRIMARY KEY (`id`)
|
|
||||||
-- ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
|
||||||
|
|
||||||
-- LOCK TABLES `pmgr_credit_types` WRITE;
|
|
||||||
-- INSERT INTO `pmgr_credit_types` (`id`, `name`, `account_id`)
|
|
||||||
-- VALUES
|
|
||||||
-- (1, 'Security Deposit', 0),
|
|
||||||
-- (2, 'Rent', 0),
|
|
||||||
-- (3, 'Late Credit', 0);
|
|
||||||
-- UNLOCK TABLES;
|
|
||||||
|
|
||||||
|
|
||||||
-- ----------------------------------------------------------------------
|
|
||||||
-- ----------------------------------------------------------------------
|
|
||||||
-- TABLE pmgr_credits
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `pmgr_credits`;
|
|
||||||
CREATE TABLE `pmgr_credits` (
|
|
||||||
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
||||||
|
|
||||||
-- `credit_type_id` INT(10) UNSIGNED NOT NULL,
|
|
||||||
`lease_id` INT(10) UNSIGNED NOT NULL,
|
|
||||||
`credit_date` DATE NOT NULL,
|
|
||||||
`credit_to_date` DATE DEFAULT NULL,
|
|
||||||
`due_date` DATE DEFAULT NULL,
|
|
||||||
`amount` FLOAT(12,2) NOT NULL,
|
|
||||||
`tax` FLOAT(12,2) NOT NULL,
|
|
||||||
`total` FLOAT(12,2) NOT NULL,
|
|
||||||
`comment` VARCHAR(255) DEFAULT NULL,
|
|
||||||
|
|
||||||
PRIMARY KEY (`id`)
|
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
|
||||||
|
|
||||||
|
|
||||||
-- ######################################################################
|
|
||||||
-- ######################################################################
|
|
||||||
-- ######################################################################
|
|
||||||
-- ######################################################################
|
|
||||||
-- ######################################################################
|
|
||||||
-- ######################################################################
|
|
||||||
-- ######################################################################
|
|
||||||
-- ######################################################################
|
|
||||||
-- ######################################################################
|
|
||||||
-- ##
|
|
||||||
-- ## RECEIPTS
|
|
||||||
-- ##
|
|
||||||
|
|
||||||
-- # Charge
|
|
||||||
-- # - Issued against customer lease
|
|
||||||
-- # - associated with account (i.e. QuickBooks account / category)
|
|
||||||
-- # Receipt
|
|
||||||
-- # - Collections of payments paid at one time
|
|
||||||
-- # Payment
|
|
||||||
-- # - Credited towards customer (or lease?)
|
|
||||||
-- # - may be more than customer owes
|
|
||||||
-- # - cash/check/charge/ach/etc
|
|
||||||
-- # Reconciliation
|
|
||||||
-- # - Associates a payment with the charge
|
|
||||||
-- # - Indicates amount of credit towards charge
|
|
||||||
-- # - Payments may cover several charges
|
|
||||||
-- # - Several payments may cover the same charge
|
|
||||||
|
|
||||||
|
|
||||||
-- Which charges haven not been paid?
|
|
||||||
-- SELECT C.id AS cid, C.total AS total, COALESCE(SUM(R.amount),0) AS paid
|
|
||||||
-- FROM pmgr_charges C
|
|
||||||
-- LEFT JOIN pmgr_charges_receipts R ON R.charge_id = C.id
|
|
||||||
-- GROUP BY C.id
|
|
||||||
-- HAVING paid < C.total
|
|
||||||
|
|
||||||
-- SELECT ChL.lid AS lid, U.name, C.display_name,
|
|
||||||
-- SUM(ChL.total) AS total, SUM(ChL.paid) AS paid,
|
|
||||||
-- SUM(ChL.total) - SUM(ChL.paid) AS owing
|
|
||||||
-- FROM (SELECT Ch.lease_id AS lid, Ch.total AS total, COALESCE(SUM(R.amount),0) AS paid
|
|
||||||
-- FROM pmgr_charges Ch
|
|
||||||
-- LEFT JOIN pmgr_charges_receipts R ON R.charge_id = Ch.id
|
|
||||||
-- WHERE Ch.due_date < NOW()
|
|
||||||
-- GROUP BY Ch.id
|
|
||||||
-- HAVING paid < Ch.total) ChL
|
|
||||||
-- LEFT JOIN pmgr_leases L ON L.id = ChL.lid
|
|
||||||
-- LEFT JOIN pmgr_lease_contacts Lc ON Lc.lease_id = L.id AND Lc.type = 'TENANT'
|
|
||||||
-- LEFT JOIN pmgr_contacts C ON C.id = Lc.contact_id
|
|
||||||
-- LEFT JOIN pmgr_units U ON U.id = L.unit_id
|
|
||||||
|
|
||||||
|
|
||||||
-- ----------------------------------------------------------------------
|
|
||||||
-- ----------------------------------------------------------------------
|
|
||||||
-- TABLE pmgr_receipts
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `pmgr_receipts`;
|
|
||||||
CREATE TABLE `pmgr_receipts` (
|
|
||||||
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
`stamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`stamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`comment` VARCHAR(255) DEFAULT NULL,
|
||||||
|
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
|
||||||
|
-- ----------------------------------------------------------------------
|
||||||
|
-- ----------------------------------------------------------------------
|
||||||
|
-- TABLE pmgr_transactions
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `pmgr_transactions`;
|
||||||
|
CREATE TABLE `pmgr_transactions` (
|
||||||
|
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
|
|
||||||
|
-- `type` ENUM('INVOICE',
|
||||||
|
-- 'RECEIPT')
|
||||||
|
-- NOT NULL,
|
||||||
|
|
||||||
|
`stamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`due_date` DATE DEFAULT NULL,
|
||||||
|
|
||||||
|
-- REVISIT <AP>: 20090604
|
||||||
|
-- How should we track which charges have been paid?
|
||||||
|
-- `related_transaction_id` INT(10) UNSIGNED NOT NULL,
|
||||||
|
-- `related_entry_id` INT(10) UNSIGNED NOT NULL,
|
||||||
|
|
||||||
`comment` VARCHAR(255) DEFAULT NULL,
|
`comment` VARCHAR(255) DEFAULT NULL,
|
||||||
|
|
||||||
@@ -1073,16 +990,89 @@ CREATE TABLE `pmgr_receipts` (
|
|||||||
|
|
||||||
-- ----------------------------------------------------------------------
|
-- ----------------------------------------------------------------------
|
||||||
-- ----------------------------------------------------------------------
|
-- ----------------------------------------------------------------------
|
||||||
-- TABLE pmgr_charges_receipts
|
-- TABLE pmgr_ledger_entries
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `pmgr_charges_receipts`;
|
DROP TABLE IF EXISTS `pmgr_ledger_entries`;
|
||||||
CREATE TABLE `pmgr_charges_receipts` (
|
CREATE TABLE `pmgr_ledger_entries` (
|
||||||
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
`charge_id` INT(10) UNSIGNED NOT NULL,
|
|
||||||
-- REVISIT <AP>: 20090514
|
-- Effective date may be used for a variety of entries
|
||||||
-- THIS SHOULD BE RECEIPT_ID, NOT PAYMENT_ID, RIGHT??
|
-- charges & payments are not always effective at the
|
||||||
`receipt_id` INT(10) UNSIGNED NOT NULL,
|
-- time of transaction. Through date, on the other hand,
|
||||||
|
-- will probably only be relevant for charges, such as
|
||||||
|
-- rent, which is effective for a range of dates.
|
||||||
|
`effective_date` DATE DEFAULT NULL, -- first day
|
||||||
|
`through_date` DATE DEFAULT NULL, -- last day
|
||||||
|
|
||||||
|
`monetary_source_id` INT(10) UNSIGNED DEFAULT NULL, -- NULL if internal transfer
|
||||||
|
`transaction_id` INT(10) UNSIGNED NOT NULL,
|
||||||
|
`customer_id` INT(10) UNSIGNED DEFAULT NULL,
|
||||||
|
`lease_id` INT(10) UNSIGNED DEFAULT NULL,
|
||||||
`amount` FLOAT(12,2) NOT NULL,
|
`amount` FLOAT(12,2) NOT NULL,
|
||||||
|
|
||||||
|
-- REVISIT <AP>: 20090707
|
||||||
|
-- Experimental. Considering automatically hooking
|
||||||
|
-- charges to their invoice. This may help ease the
|
||||||
|
-- ongoing accounting dilema that we've been having.
|
||||||
|
-- It might allow us to keep the underlying invoice
|
||||||
|
-- ledgers without having to expose the user to them.
|
||||||
|
`root_transaction_id` INT(10) UNSIGNED DEFAULT NULL,
|
||||||
|
|
||||||
|
`debit_ledger_id` INT(10) UNSIGNED NOT NULL,
|
||||||
|
`credit_ledger_id` INT(10) UNSIGNED NOT NULL,
|
||||||
|
|
||||||
|
`comment` VARCHAR(255) DEFAULT NULL,
|
||||||
|
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
|
||||||
|
-- ----------------------------------------------------------------------
|
||||||
|
-- ----------------------------------------------------------------------
|
||||||
|
-- TABLE pmgr_reconciliations
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `pmgr_reconciliations`;
|
||||||
|
CREATE TABLE `pmgr_reconciliations` (
|
||||||
|
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
|
|
||||||
|
`debit_ledger_entry_id` INT(10) UNSIGNED NOT NULL,
|
||||||
|
`credit_ledger_entry_id` INT(10) UNSIGNED NOT NULL,
|
||||||
|
`amount` FLOAT(12,2) NOT NULL,
|
||||||
|
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
|
||||||
|
-- ----------------------------------------------------------------------
|
||||||
|
-- ----------------------------------------------------------------------
|
||||||
|
-- TABLE pmgr_monetary_sources
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `pmgr_monetary_sources`;
|
||||||
|
CREATE TABLE `pmgr_monetary_sources` (
|
||||||
|
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
|
|
||||||
|
`name` VARCHAR(80) DEFAULT NULL,
|
||||||
|
|
||||||
|
-- REVISIT <AP>: 20090605
|
||||||
|
-- Check Number;
|
||||||
|
-- Routing Number, Account Number;
|
||||||
|
-- Card Number, Expiration Date; CVV2 Code
|
||||||
|
-- etc.
|
||||||
|
-- REVISIT <AP> 20090630
|
||||||
|
-- I _think_ that CVV2 is NEVER supposed to
|
||||||
|
-- be stored ANYWHERE. Merchants agree to
|
||||||
|
-- use it only to verify the transaction and
|
||||||
|
-- then leave no record of it, so that even
|
||||||
|
-- if their security is compromised, no one
|
||||||
|
-- will know the CVV2 code unless they are
|
||||||
|
-- in physical possession of the card.
|
||||||
|
`data1` VARCHAR(80) DEFAULT NULL,
|
||||||
|
`data2` VARCHAR(80) DEFAULT NULL,
|
||||||
|
`data3` VARCHAR(80) DEFAULT NULL,
|
||||||
|
`data4` VARCHAR(80) DEFAULT NULL,
|
||||||
|
|
||||||
|
`comment` VARCHAR(255) DEFAULT NULL,
|
||||||
|
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
|||||||
69
requirements.txt
Normal file
69
requirements.txt
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
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
|
||||||
|
- Report: List of customers overdue
|
||||||
|
- Flag unit as overlocked
|
||||||
|
- Flag unit as evicting
|
||||||
|
- Flag unit as normal status
|
||||||
|
- Flag unit as dirty
|
||||||
|
- Enter notes when communicating with Customer
|
||||||
|
- Accept pre-payments
|
||||||
|
- NOTE: As a temporary solution, disallow customer to run
|
||||||
|
a credit. Require charges be entered first.
|
||||||
|
X - Record Customer Move-Out from Unit
|
||||||
|
X - Record utilization of Security Deposit
|
||||||
|
- Record issuing of a refund
|
||||||
|
- Record Deposit into Petty Cash
|
||||||
|
- Record Payment from Petty Cash to expenses
|
||||||
|
- Record Petty Cash to refund.
|
||||||
|
X - Write Off Bad Debt
|
||||||
|
X - Perform a Deposit and Close the Books
|
||||||
|
X - Determine Rents Collected for a given period.
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -35,14 +35,22 @@
|
|||||||
* @subpackage cake.app
|
* @subpackage cake.app
|
||||||
*/
|
*/
|
||||||
class AppController extends Controller {
|
class AppController extends Controller {
|
||||||
var $helpers = array('Html', 'Number', 'Time');
|
var $helpers = array('Html', 'Form', 'Javascript', 'Format', 'Time', 'Grid');
|
||||||
|
var $components = array('DebugKit.Toolbar');
|
||||||
|
|
||||||
function sideMenuLinks() {
|
function sideMenuLinks() {
|
||||||
return array(
|
return array(
|
||||||
array('name' => 'Common', 'header' => true),
|
array('name' => 'Common', 'header' => true),
|
||||||
array('name' => 'Site Map', 'url' => array('controller' => 'maps', 'action' => 'view', 1)),
|
array('name' => 'Site Map', 'url' => array('controller' => 'maps', 'action' => 'view', 1)),
|
||||||
array('name' => 'Tenants', 'url' => array('controller' => 'contacts', 'action' => 'index')),
|
|
||||||
array('name' => 'Units', 'url' => array('controller' => 'units', 'action' => 'index')),
|
array('name' => 'Units', 'url' => array('controller' => 'units', 'action' => 'index')),
|
||||||
|
array('name' => 'Leases', 'url' => array('controller' => 'leases', 'action' => 'index')),
|
||||||
|
array('name' => 'Customers', 'url' => array('controller' => 'customers', 'action' => 'index')),
|
||||||
|
array('name' => 'Accounts', 'url' => array('controller' => 'accounts', 'action' => 'index')),
|
||||||
|
array('name' => 'Debug', 'header' => true),
|
||||||
|
array('name' => 'Contacts', 'url' => array('controller' => 'contacts', 'action' => 'index')),
|
||||||
|
array('name' => 'Ledgers', 'url' => array('controller' => 'ledgers', 'action' => 'index')),
|
||||||
|
array('name' => 'New Ledgers', 'url' => array('controller' => 'accounts', 'action' => 'newledger')),
|
||||||
|
array('name' => 'RESET DATA', 'url' => array('controller' => 'accounts', 'action' => 'reset_data')),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,5 +58,404 @@ class AppController extends Controller {
|
|||||||
$this->set('sidemenu', $this->sideMenuLinks());
|
$this->set('sidemenu', $this->sideMenuLinks());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function reset_data() {
|
||||||
|
$this->layout = null;
|
||||||
|
$this->autoLayout = false;
|
||||||
|
$this->autoRender = false;
|
||||||
|
Configure::write('debug', '0');
|
||||||
|
$script = $_SERVER['DOCUMENT_ROOT'] . '/pmgr/build.cmd';
|
||||||
|
echo "<P>" . date('r') . "\n";
|
||||||
|
//echo "<P>Script: $script" . "\n";
|
||||||
|
$db = & $this->Account->getDataSource();
|
||||||
|
$script .= ' "' . $db->config['database'] . '"';
|
||||||
|
$script .= ' "' . $db->config['login'] . '"';
|
||||||
|
$script .= ' "' . $db->config['password'] . '"';
|
||||||
|
$handle = popen($script . ' 2>&1', 'r');
|
||||||
|
//echo "<P>Handle: $handle; " . gettype($handle) . "\n";
|
||||||
|
echo "<P><PRE>\n";
|
||||||
|
while (($read = fread($handle, 2096))) {
|
||||||
|
echo $read;
|
||||||
|
}
|
||||||
|
echo "</PRE>\n";
|
||||||
|
pclose($handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* helper: jqGridView
|
||||||
|
* - called by function to create an index listing
|
||||||
|
*/
|
||||||
|
|
||||||
|
function jqGridView($title, $action = null, $element = null) {
|
||||||
|
$this->set('title', $title);
|
||||||
|
// The resulting page will contain a jqGrid, which will
|
||||||
|
// use ajax to obtain the actual data for this action
|
||||||
|
$this->set('action', $action ? $action : $this->params['action']);
|
||||||
|
$this->render('/elements/' . ($element ? $element : $this->params['controller']));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: jqGridData
|
||||||
|
* - Fetches the actual data requested by jqGrid as XML
|
||||||
|
*/
|
||||||
|
|
||||||
|
function jqGridData() {
|
||||||
|
// Grab a copy of the parameters that control this request
|
||||||
|
$params = array();
|
||||||
|
if (isset($this->params['url']) && is_array($this->params['url']))
|
||||||
|
$params = $this->params['url'];
|
||||||
|
|
||||||
|
// Do any preliminary setup necessary
|
||||||
|
$this->jqGridDataSetup($params);
|
||||||
|
|
||||||
|
// Get the top level model for this grid
|
||||||
|
$model = $this->jqGridDataModel($params);
|
||||||
|
|
||||||
|
// Establish the basic query and conditions
|
||||||
|
$query = array_intersect_key($this->jqGridDataCountTables($params, $model),
|
||||||
|
array('link'=>1, 'contain'=>1));
|
||||||
|
$query['conditions'] = $this->jqGridDataCountConditions($params, $model);
|
||||||
|
$query['group'] = $this->jqGridDataCountGroup($params, $model);
|
||||||
|
|
||||||
|
// DEBUG PURPOSES ONLY!
|
||||||
|
$params['count_query'] = $query;
|
||||||
|
|
||||||
|
// Get the number of records prior to pagination
|
||||||
|
$count = $this->jqGridDataRecordCount($params, $model, $query);
|
||||||
|
|
||||||
|
// Start the query over, this time getting the actual set
|
||||||
|
// of tables needed, not just those needed for counting.
|
||||||
|
$query = array_intersect_key($this->jqGridDataTables($params, $model),
|
||||||
|
array('link'=>1, 'contain'=>1));
|
||||||
|
$query['conditions'] = $this->jqGridDataConditions($params, $model);
|
||||||
|
|
||||||
|
// Verify a few parameters and determine our starting row
|
||||||
|
$limit = $params['rows'];
|
||||||
|
$total = ($count < 0) ? 0 : ceil($count/$limit);
|
||||||
|
$page = ($params['page'] <= 1) ? 1 : (($params['page'] > $total) ? $total : $params['page']);
|
||||||
|
$start = $limit*$page - $limit;
|
||||||
|
|
||||||
|
// Grab the actual records taking pagination into account
|
||||||
|
$query['group'] = $this->jqGridDataGroup($params, $model);
|
||||||
|
$query['order'] = $this->jqGridDataOrder($params, $model,
|
||||||
|
isset($params['sidx']) ? $params['sidx'] : null,
|
||||||
|
isset($params['sord']) ? $params['sord'] : null);
|
||||||
|
$query['limit'] = $this->jqGridDataLimit($params, $model, $start, $limit);
|
||||||
|
$query['fields'] = $this->jqGridDataFields($params, $model);
|
||||||
|
$results = $this->jqGridDataRecords($params, $model, $query);
|
||||||
|
|
||||||
|
// DEBUG PURPOSES ONLY!
|
||||||
|
$params['query'] = $query;
|
||||||
|
|
||||||
|
// Post process the records
|
||||||
|
$this->jqGridRecordsPostProcess($params, $model, $results);
|
||||||
|
|
||||||
|
// Add in any needed hyperlinks
|
||||||
|
$this->jqGridRecordLinks($params, $model, $results, array());
|
||||||
|
|
||||||
|
// Finally, dump out the data
|
||||||
|
$this->jqGridDataOutputHeader($params, $model);
|
||||||
|
echo "<?xml version='1.0' encoding='utf-8'?>\n";
|
||||||
|
echo "<rows>\n";
|
||||||
|
$this->jqGridDataOutputSummary($params, $model, $page, $total, $count);
|
||||||
|
$this->jqGridDataOutputRecords($params, $model, $results);
|
||||||
|
echo "</rows>\n";
|
||||||
|
|
||||||
|
// Call out to finalize everything
|
||||||
|
$this->jqGridDataFinalize($params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* virtual: jqGridData* functions
|
||||||
|
* - These set up the context for the jqGrid data, and will
|
||||||
|
* need to be overridden in the derived class for anything
|
||||||
|
* other than the most basic of grids.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function jqGridDataSetup(&$params) {
|
||||||
|
// Assume we're debugging.
|
||||||
|
// The actual jqGrid request will set this to false
|
||||||
|
$debug = true;
|
||||||
|
|
||||||
|
if (isset($this->passedArgs['debug']))
|
||||||
|
$debug = $this->passedArgs['debug'];
|
||||||
|
|
||||||
|
$params['debug'] = $debug;
|
||||||
|
|
||||||
|
if (!$debug) {
|
||||||
|
$this->layout = null;
|
||||||
|
$this->autoLayout = false;
|
||||||
|
$this->autoRender = false;
|
||||||
|
Configure::write('debug', '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Establish some defaults (except for serialized items)
|
||||||
|
$params = array_merge(array('page' => 1,
|
||||||
|
'rows' => 20),
|
||||||
|
$params);
|
||||||
|
|
||||||
|
// Unserialize our complex structure of fields
|
||||||
|
// This SHOULD always be set, except when debugging
|
||||||
|
if (isset($params['fields']))
|
||||||
|
$params['fields'] = unserialize($params['fields']);
|
||||||
|
else
|
||||||
|
$params['fields'] = array($this->{$this->modelClass}->alias
|
||||||
|
.'.'.
|
||||||
|
$this->{$this->modelClass}->primarKey);
|
||||||
|
|
||||||
|
// Unserialize the list of ids, if present.
|
||||||
|
if (isset($params['custom']))
|
||||||
|
$params['custom'] = unserialize($params['custom']);
|
||||||
|
else
|
||||||
|
$params['custom'] = null;
|
||||||
|
|
||||||
|
// Unserialize the list of ids, if present.
|
||||||
|
if (isset($params['idlist']))
|
||||||
|
$params['idlist'] = unserialize($params['idlist']);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataModel(&$params) {
|
||||||
|
return $this->{$this->modelClass};
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataCountTables(&$params, &$model) {
|
||||||
|
// If not overridden, we use the same tables to
|
||||||
|
// perform our count as we do to for the actual query
|
||||||
|
return $this->jqGridDataTables($params, $model);
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataTables(&$params, &$model) {
|
||||||
|
return array('contain' => false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataCountConditions(&$params, &$model) {
|
||||||
|
return $this->jqGridDataConditions($params, $model);
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataConditions(&$params, &$model) {
|
||||||
|
$searches = array();
|
||||||
|
|
||||||
|
if (isset($params['_search']) && $params['_search'] === 'true') {
|
||||||
|
if (isset($params['searchOper'])) {
|
||||||
|
$searches[] = array('op' => $params['searchOper'],
|
||||||
|
'field' => $params['searchField'],
|
||||||
|
'value' => $params['searchString']);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// DOH! Crappy mechanism puts toolbar search terms
|
||||||
|
// directly into params as name/value pairs. No
|
||||||
|
// way to know which elements of params are search
|
||||||
|
// terms, so skipping this at the moment.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif (isset($params['filt']) && $params['filt']) {
|
||||||
|
$searches[] = array('op' => 'bw',
|
||||||
|
'field' => $params['filtField'],
|
||||||
|
'value' => $params['filtValue']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$ops = array('eq' => array('op' => null, 'pre' => '', 'post' => ''),
|
||||||
|
'ne' => array('op' => '<>', 'pre' => '', 'post' => ''),
|
||||||
|
'lt' => array('op' => '<', 'pre' => '', 'post' => ''),
|
||||||
|
'le' => array('op' => '<=', 'pre' => '', 'post' => ''),
|
||||||
|
'gt' => array('op' => '>', 'pre' => '', 'post' => ''),
|
||||||
|
'ge' => array('op' => '>=', 'pre' => '', 'post' => ''),
|
||||||
|
'bw' => array('op' => 'LIKE', 'pre' => '', 'post' => '%'),
|
||||||
|
'ew' => array('op' => 'LIKE', 'pre' => '%', 'post' => ''),
|
||||||
|
'cn' => array('op' => 'LIKE', 'pre' => '%', 'post' => '%'),
|
||||||
|
);
|
||||||
|
|
||||||
|
$conditions = array();
|
||||||
|
foreach ($searches AS $search) {
|
||||||
|
$op = $ops[$search['op']];
|
||||||
|
$field = $search['field'] . ($op['op'] ? ' '.$op['op'] : '');
|
||||||
|
$value = $op['pre'] . $search['value']. $op['post'];
|
||||||
|
$conditions[] = array($field => $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($params['action']) && $params['action'] === 'idlist') {
|
||||||
|
if (count($params['idlist']))
|
||||||
|
$conditions[] = array($model->alias.'.'.$model->primaryKey => $params['idlist']);
|
||||||
|
else
|
||||||
|
$conditions[] = '0=1';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $conditions;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataFields(&$params, &$model) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataCountGroup(&$params, &$model) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataGroup(&$params, &$model) {
|
||||||
|
return $model->alias.'.'.$model->primaryKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataOrder(&$params, &$model, $index, $direction) {
|
||||||
|
return $index ? array($index .' '. $direction) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataLimit(&$params, &$model, $start, $limit) {
|
||||||
|
return $start . ', ' . $limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataRecordCount(&$params, &$model, $query) {
|
||||||
|
return $model->find('count', $query);
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataRecords(&$params, &$model, $query) {
|
||||||
|
return $model->find('all', $query);
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridRecordsPostProcess(&$params, &$model, &$records) {
|
||||||
|
$model_alias = $model->alias;
|
||||||
|
$id = $model->primaryKey;
|
||||||
|
|
||||||
|
$subtotals = array();
|
||||||
|
foreach ($params['fields'] AS $field) {
|
||||||
|
if (preg_match('/subtotal-(.*)$/', $field, $matches))
|
||||||
|
$subtotals[] = array('field' => $matches[1],
|
||||||
|
'name' => $field,
|
||||||
|
'amount' => 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($records AS &$record) {
|
||||||
|
$record['jqGrid_id'] = $record[$model_alias][$id];
|
||||||
|
// Add the calculated fields (if any), to the model fields
|
||||||
|
if (isset($record[0])) {
|
||||||
|
$record[$model_alias] += $record[0];
|
||||||
|
unset($record[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($subtotals AS &$subtotal) {
|
||||||
|
$field = $subtotal['field'];
|
||||||
|
if (preg_match("/\./", $field)) {
|
||||||
|
list($tbl, $col) = explode(".", $field);
|
||||||
|
$record['subtotal-'.$tbl][$col] =
|
||||||
|
($subtotal['amount'] += $record[$tbl][$col]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$record[$model->alias]['subtotal-'.$field] =
|
||||||
|
($subtotal['amount'] += $record[$model->alias][$field]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DEBUG PURPOSES ONLY!
|
||||||
|
//$params['records'] = $records;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
|
||||||
|
// Don't create any links if ordered not to.
|
||||||
|
if (isset($params['nolinks']))
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach ($links AS $table => $fields) {
|
||||||
|
$special = array('controller', 'id');
|
||||||
|
$controller = Inflector::pluralize(Inflector::underscore($table));
|
||||||
|
$id = 'id';
|
||||||
|
extract(array_intersect_key($fields, array_flip($special)));
|
||||||
|
foreach ($records AS &$record) {
|
||||||
|
if (!isset($record[$table]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
foreach (array_diff_key($fields, array_flip($special)) AS $field) {
|
||||||
|
if (!isset($record[$table][$id]) || !isset($record[$table][$field]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// DEBUG PURPOSES ONLY!
|
||||||
|
//$params['linkrecord'][] = compact('table', 'field', 'id', 'controller', 'record');
|
||||||
|
$record[$table][$field] =
|
||||||
|
'<A HREF="' .
|
||||||
|
Router::url(array('controller' => $controller,
|
||||||
|
'action' => 'view',
|
||||||
|
$record[$table][$id])) .
|
||||||
|
'">' .
|
||||||
|
$record[$table][$field] .
|
||||||
|
'</A>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataOutputHeader(&$params, &$model) {
|
||||||
|
if ($params['debug']) {
|
||||||
|
ob_start();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
header("Content-type: text/xml;charset=utf-8");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataOutputSummary(&$params, &$model, $page, $total, $records) {
|
||||||
|
echo " <params><![CDATA[\n" . print_r($params, true) . "\n]]></params>\n";
|
||||||
|
echo " <page>$page</page>\n";
|
||||||
|
echo " <total>$total</total>\n";
|
||||||
|
echo " <records>$records</records>\n";
|
||||||
|
|
||||||
|
if (isset($params['userdata'])) {
|
||||||
|
foreach ($params['userdata'] AS $field => $value)
|
||||||
|
echo ' <userdata name="'.$field.'">' . "{$value}</userdata>\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataOutputRecords(&$params, &$model, &$records) {
|
||||||
|
$id_field = 'jqGrid_id';
|
||||||
|
foreach ($records AS $record) {
|
||||||
|
$this->jqGridDataOutputRecord($params, $model, $record,
|
||||||
|
$record[$id_field], $params['fields']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataOutputRecord(&$params, &$model, &$record, $id, $fields) {
|
||||||
|
echo " <row id='$id'>\n";
|
||||||
|
foreach ($fields AS $field) {
|
||||||
|
$this->jqGridDataOutputRecordField($params, $model, $record, $field);
|
||||||
|
}
|
||||||
|
echo " </row>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataOutputRecordField(&$params, &$model, &$record, $field) {
|
||||||
|
if (preg_match("/\./", $field)) {
|
||||||
|
list($tbl, $col) = explode(".", $field);
|
||||||
|
$data = $record[$tbl][$col];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$data = $record[$model->alias][$field];
|
||||||
|
}
|
||||||
|
$this->jqGridDataOutputRecordCell($params, $model, $record, $field, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataOutputRecordCell(&$params, &$model, &$record, $field, $data) {
|
||||||
|
// be sure to put text data in CDATA
|
||||||
|
if (preg_match("/^\d*$/", $data))
|
||||||
|
echo " <cell>$data</cell>\n";
|
||||||
|
else
|
||||||
|
echo " <cell><![CDATA[$data]]></cell>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataFinalize(&$params) {
|
||||||
|
if ($params['debug']) {
|
||||||
|
$xml = ob_get_contents();
|
||||||
|
ob_end_clean();
|
||||||
|
|
||||||
|
$xml = preg_replace("/&/", "&", $xml);
|
||||||
|
$xml = preg_replace("/</", "<", $xml);
|
||||||
|
$xml = preg_replace("/>/", ">", $xml);
|
||||||
|
|
||||||
|
echo ("\n<PRE>\n$xml\n</PRE>\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
@@ -38,8 +38,9 @@
|
|||||||
*/
|
*/
|
||||||
class AppModel extends Model {
|
class AppModel extends Model {
|
||||||
|
|
||||||
//var $actsAs = array('Containable');
|
var $actsAs = array('Containable', 'Linkable');
|
||||||
var $actsAs = array('Linkable');
|
var $useNullForEmpty = true;
|
||||||
|
var $formatDateFields = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Enum Values
|
* Get Enum Values
|
||||||
@@ -48,13 +49,15 @@ class AppModel extends Model {
|
|||||||
*
|
*
|
||||||
* Gets the enum values for MySQL 4 and 5 to use in selectTag()
|
* Gets the enum values for MySQL 4 and 5 to use in selectTag()
|
||||||
*/
|
*/
|
||||||
function getEnumValues($columnName=null, $respectDefault=false)
|
function getEnumValues($columnName=null, $tableName=null)
|
||||||
{
|
{
|
||||||
if ($columnName==null) { return array(); } //no field specified
|
if ($columnName==null) { return array(); } //no field specified
|
||||||
|
|
||||||
//Get the name of the table
|
if (!isset($tableName)) {
|
||||||
$db =& ConnectionManager::getDataSource($this->useDbConfig);
|
//Get the name of the table
|
||||||
$tableName = $db->fullTableName($this, false);
|
$db =& ConnectionManager::getDataSource($this->useDbConfig);
|
||||||
|
$tableName = $db->fullTableName($this, false);
|
||||||
|
}
|
||||||
|
|
||||||
//Get the values for the specified column (database and version specific, needs testing)
|
//Get the values for the specified column (database and version specific, needs testing)
|
||||||
$result = $this->query("SHOW COLUMNS FROM {$tableName} LIKE '{$columnName}'");
|
$result = $this->query("SHOW COLUMNS FROM {$tableName} LIKE '{$columnName}'");
|
||||||
@@ -73,37 +76,138 @@ class AppModel extends Model {
|
|||||||
|
|
||||||
//Get the values
|
//Get the values
|
||||||
return array_flip(array_merge(array(''), // MySQL sets 0 to be the empty string
|
return array_flip(array_merge(array(''), // MySQL sets 0 to be the empty string
|
||||||
explode("','", preg_replace("/(enum)\('(.+?)'\)/","\\2", $types))
|
explode("','", strtoupper(preg_replace("/(enum)\('(.+?)'\)/","\\2", $types)))
|
||||||
));
|
));
|
||||||
} //end getEnumValues
|
} //end getEnumValues
|
||||||
|
|
||||||
|
|
||||||
// Overriding pagination, since the stupid count mechanism blows.
|
|
||||||
// This is also a crappy solution, especially if the query returns
|
|
||||||
// a really large number of rows. However, trying to untagle this
|
|
||||||
// without changing a bunch of core code is near impossible.
|
|
||||||
|
|
||||||
var $paginate_rows_save;
|
/**************************************************************************
|
||||||
function paginate($conditions, $fields, $order, $limit, $page = 1, $recursive = null, $extra = null) {
|
**************************************************************************
|
||||||
/* pr("paginate"); */
|
**************************************************************************
|
||||||
/* pr(array_merge(compact('conditions', 'fields', 'order', 'limit', 'page', 'recursive', 'extra'))); */
|
* function: nameToID
|
||||||
if ($page > 1 && isset($limit))
|
* - Returns the ID of the named item
|
||||||
$offset = ($page - 1) * $limit;
|
*/
|
||||||
else
|
function nameToID($name) {
|
||||||
$offset = 0;
|
$this->cacheQueries = true;
|
||||||
return array_slice($this->paginate_rows_save, $offset, $limit);
|
$item = $this->find('first', array
|
||||||
|
('recursive' => -1,
|
||||||
|
'conditions' => compact('name'),
|
||||||
|
));
|
||||||
|
$this->cacheQueries = false;
|
||||||
|
if ($item) {
|
||||||
|
$item = current($item);
|
||||||
|
return $item['id'];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
function paginateCount($conditions = null, $recursive = null, $extra = null) {
|
|
||||||
/* pr("paginateCount"); */
|
|
||||||
/* pr(array_merge(compact('conditions', 'recursive', 'extra'))); */
|
|
||||||
|
|
||||||
if (!isset($recursive))
|
|
||||||
$recursive = $this->recursive;
|
|
||||||
$parameters = array_merge(compact('conditions', 'recursive'), $extra);
|
|
||||||
$results = $this->find('all', $parameters);
|
|
||||||
|
|
||||||
$this->paginate_rows_save = $results;
|
/**************************************************************************
|
||||||
return count($this->paginate_rows_save);
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: statMerge
|
||||||
|
* - Merges summary data from $b into $a
|
||||||
|
*/
|
||||||
|
|
||||||
|
function statsMerge (&$a, $b) {
|
||||||
|
if (!isset($b))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!isset($a)) {
|
||||||
|
$a = $b;
|
||||||
|
}
|
||||||
|
elseif (!is_array($a) && !is_array($b)) {
|
||||||
|
$a += $b;
|
||||||
|
}
|
||||||
|
elseif (is_array($a) && is_array($b)) {
|
||||||
|
foreach (array_intersect_key($a, $b) AS $k => $v)
|
||||||
|
{
|
||||||
|
if (preg_match("/^sp\./", $k))
|
||||||
|
$a[$k] .= '; ' . $b[$k];
|
||||||
|
else
|
||||||
|
$this->statsMerge($a[$k], $b[$k]);
|
||||||
|
}
|
||||||
|
$a = array_merge($a, array_diff_key($b, $a));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
die ("Can't yet merge array and non-array stats");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function recursive_array_replace($find, $replace, &$data) {
|
||||||
|
if (!isset($data))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (is_array($data)) {
|
||||||
|
foreach ($data as $key => &$value) {
|
||||||
|
$this->recursive_array_replace($find, $replace, $value);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($replace))
|
||||||
|
$data = preg_replace($find, $replace, $data);
|
||||||
|
elseif (preg_match($find, $data))
|
||||||
|
$data = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function beforeSave() {
|
||||||
|
/* pr(array('class' => $this->name, */
|
||||||
|
/* 'alias' => $this->alias, */
|
||||||
|
/* 'function' => 'AppModel::beforeSave')); */
|
||||||
|
|
||||||
|
// Replace all empty strings with NULL.
|
||||||
|
// If a particular model doesn't like this, they'll have to
|
||||||
|
// override the behavior, or set useNullForEmpty to false.
|
||||||
|
if ($this->useNullForEmpty)
|
||||||
|
$this->recursive_array_replace("/^\s*$/", null, $this->data);
|
||||||
|
|
||||||
|
if ($this->formatDateFields) {
|
||||||
|
$alias = $this->alias;
|
||||||
|
|
||||||
|
foreach ($this->_schema AS $field => $info) {
|
||||||
|
if ($info['type'] == 'date' || $info['type'] == 'timestamp') {
|
||||||
|
if (isset($this->data[$alias][$field])) {
|
||||||
|
/* pr("Fix Date for '$alias'.'$field'; current value = " . */
|
||||||
|
/* "'{$this->data[$alias][$field]}'"); */
|
||||||
|
if ($this->data[$alias][$field] === 'CURRENT_TIMESTAMP')
|
||||||
|
// Seems CakePHP is broken for the default timestamp.
|
||||||
|
// It tries to automagically set the value to CURRENT_TIMESTAMP
|
||||||
|
// which is wholly rejected by MySQL. Just put it back to NULL
|
||||||
|
// and let the SQL engine deal with the defaults... it's not
|
||||||
|
// Cake's place to do this anyway :-/
|
||||||
|
$this->data[$alias][$field] = null;
|
||||||
|
else
|
||||||
|
$this->data[$alias][$field] =
|
||||||
|
$this->dateFormatBeforeSave($this->data[$alias][$field]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: dateFormatBeforeSave
|
||||||
|
* - convert dates to database format
|
||||||
|
*/
|
||||||
|
|
||||||
|
function dateFormatBeforeSave($dateString) {
|
||||||
|
/* $time = ''; */
|
||||||
|
/* if (preg_match('/(\d+(:\d+))/', $dateString, $match)) */
|
||||||
|
/* $time = ' '.$match[1]; */
|
||||||
|
/* $dateString = preg_replace('/(\d+(:\d+))/', '', $dateString); */
|
||||||
|
/* return date('Y-m-d', strtotime($dateString)) . $time; */
|
||||||
|
|
||||||
|
if (preg_match('/:/', $dateString))
|
||||||
|
return date('Y-m-d H:i:s', strtotime($dateString));
|
||||||
|
else
|
||||||
|
return date('Y-m-d', strtotime($dateString));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,14 +26,12 @@
|
|||||||
* @lastmodified $Date: 2008-12-18 18:16:01 -0800 (Thu, 18 Dec 2008) $
|
* @lastmodified $Date: 2008-12-18 18:16:01 -0800 (Thu, 18 Dec 2008) $
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Here, we are connecting '/' (base path) to controller called 'Pages',
|
* Here, we are connecting '/' (base path) to our site map.
|
||||||
* its action called 'display', and we pass a param to select the view file
|
* It's hardcoded to map #1, but at some point we'll implement
|
||||||
* to use (in this case, /app/views/pages/home.ctp)...
|
* a login mechanism and the default path will be to log on instead.
|
||||||
*/
|
*/
|
||||||
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
|
Router::connect('/', array('controller' => 'maps', 'action' => 'view', '1'));
|
||||||
/**
|
|
||||||
* ...and connect the rest of 'Pages' controller's urls.
|
|
||||||
*/
|
|
||||||
Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
|
|
||||||
?>
|
?>
|
||||||
297
site/controllers/accounts_controller.php
Normal file
297
site/controllers/accounts_controller.php
Normal file
@@ -0,0 +1,297 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class AccountsController extends AppController {
|
||||||
|
|
||||||
|
var $uses = array('Account', 'LedgerEntry');
|
||||||
|
|
||||||
|
var $sidemenu_links =
|
||||||
|
array(array('name' => 'Accounts', 'header' => true),
|
||||||
|
array('name' => 'All', 'url' => array('controller' => 'accounts', 'action' => 'all')),
|
||||||
|
array('name' => 'Asset', 'url' => array('controller' => 'accounts', 'action' => 'asset')),
|
||||||
|
array('name' => 'Liability', 'url' => array('controller' => 'accounts', 'action' => 'liability')),
|
||||||
|
array('name' => 'Equity', 'url' => array('controller' => 'accounts', 'action' => 'equity')),
|
||||||
|
array('name' => 'Income', 'url' => array('controller' => 'accounts', 'action' => 'income')),
|
||||||
|
array('name' => 'Expense', 'url' => array('controller' => 'accounts', 'action' => 'expense')),
|
||||||
|
array('name' => 'Bank Deposit', 'url' => array('controller' => 'accounts', 'action' => 'deposit')),
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* override: sideMenuLinks
|
||||||
|
* - Generates controller specific links for the side menu
|
||||||
|
*/
|
||||||
|
function sideMenuLinks() {
|
||||||
|
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: index / asset / liability / equity / income / expense / all
|
||||||
|
* - Generate a chart of accounts
|
||||||
|
*/
|
||||||
|
|
||||||
|
function index() { $this->all(); }
|
||||||
|
function asset() { $this->jqGridView('Asset Accounts'); }
|
||||||
|
function liability() { $this->jqGridView('Liability Accounts'); }
|
||||||
|
function equity() { $this->jqGridView('Equity Accounts'); }
|
||||||
|
function income() { $this->jqGridView('Income Accounts'); }
|
||||||
|
function expense() { $this->jqGridView('Expense Accounts'); }
|
||||||
|
function all() { $this->jqGridView('All Accounts', 'all'); }
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* virtuals: jqGridData
|
||||||
|
* - With the application controller handling the jqGridData action,
|
||||||
|
* these virtual functions ensure that the correct data is passed
|
||||||
|
* to jqGrid.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function jqGridDataSetup(&$params) {
|
||||||
|
parent::jqGridDataSetup($params);
|
||||||
|
if (!isset($params['action']))
|
||||||
|
$params['action'] = 'all';
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataCountTables(&$params, &$model) {
|
||||||
|
return parent::jqGridDataTables($params, $model);
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataTables(&$params, &$model) {
|
||||||
|
return array
|
||||||
|
('link' =>
|
||||||
|
array(// Models
|
||||||
|
'CurrentLedger' => array
|
||||||
|
(// Models
|
||||||
|
'LedgerEntry'
|
||||||
|
/* REVISIT <AP> 20090615:
|
||||||
|
* I'll remove this 'conditions' section on a future checkin,
|
||||||
|
* after I've proven out the %{MODEL_ALIAS} feature will be
|
||||||
|
* sticking around.
|
||||||
|
|
||||||
|
=> array
|
||||||
|
('conditions' =>
|
||||||
|
array('OR' =>
|
||||||
|
array('LedgerEntry.debit_ledger_id = CurrentLedger.id',
|
||||||
|
'LedgerEntry.credit_ledger_id = CurrentLedger.id'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
* END REVISIT
|
||||||
|
*/
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataFields(&$params, &$model) {
|
||||||
|
return array
|
||||||
|
('Account.*',
|
||||||
|
'SUM(IF(LedgerEntry.debit_ledger_id = CurrentLedger.id,
|
||||||
|
LedgerEntry.amount, NULL)) AS debits',
|
||||||
|
'SUM(IF(LedgerEntry.credit_ledger_id = CurrentLedger.id,
|
||||||
|
LedgerEntry.amount, NULL)) AS credits',
|
||||||
|
"SUM(IF(Account.type IN ('ASSET', 'EXPENSE'),
|
||||||
|
IF(LedgerEntry.debit_ledger_id = CurrentLedger.id, 1, -1),
|
||||||
|
IF(LedgerEntry.credit_ledger_id = CurrentLedger.id, 1, -1)
|
||||||
|
) * IF(LedgerEntry.amount, LedgerEntry.amount, 0)
|
||||||
|
) AS balance",
|
||||||
|
'COUNT(LedgerEntry.id) AS entries');
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataConditions(&$params, &$model) {
|
||||||
|
$conditions = parent::jqGridDataConditions($params, $model);
|
||||||
|
|
||||||
|
if (in_array($params['action'], array('asset', 'liability', 'equity', 'income', 'expense'))) {
|
||||||
|
$conditions[] = array('Account.type' => strtoupper($params['action']));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $conditions;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
|
||||||
|
$links['Account'] = array('name');
|
||||||
|
return parent::jqGridRecordLinks($params, $model, $records, $links);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: newledger
|
||||||
|
* - Close the current account ledger and create a new one,
|
||||||
|
* carrying forward any balance if necessary.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function newledger($id = null) {
|
||||||
|
if (!$this->Account->closeCurrentLedger($id)) {
|
||||||
|
$this->Session->setFlash(__('Unable to create new Ledger.', true));
|
||||||
|
}
|
||||||
|
if ($id)
|
||||||
|
$this->redirect(array('action'=>'view', $id));
|
||||||
|
else
|
||||||
|
$this->redirect(array('action'=>'index'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: collected
|
||||||
|
* - Displays the items actually collected for the period
|
||||||
|
* e.g. How much was collected in rent from 4/1/09 - 5/1/09
|
||||||
|
*/
|
||||||
|
function collected($id = null) {
|
||||||
|
if (!$id) {
|
||||||
|
$this->Session->setFlash(__('Invalid Item.', true));
|
||||||
|
$this->redirect(array('action'=>'index'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$payment_accounts = $this->Account->collectableAccounts();
|
||||||
|
//$payment_accounts[$this->Account->nameToID('Bank')] = 'Bank';
|
||||||
|
$default_accounts = array_diff_key($payment_accounts,
|
||||||
|
array($this->Account->concessionAccountID() => 1));
|
||||||
|
$this->set(compact('payment_accounts', 'default_accounts'));
|
||||||
|
|
||||||
|
$this->Account->recursive = -1;
|
||||||
|
$account = $this->Account->read(null, $id);
|
||||||
|
$account = $account['Account'];
|
||||||
|
|
||||||
|
$title = ($account['name'] . ': Collected Report');
|
||||||
|
$this->set(compact('account', 'title'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: deposit
|
||||||
|
* - Prepares the books for a bank deposit
|
||||||
|
*/
|
||||||
|
function deposit() {
|
||||||
|
if ($this->data) {
|
||||||
|
// Action the close based on provided data
|
||||||
|
//pr($this->data);
|
||||||
|
|
||||||
|
// Get data about each closed ledger.
|
||||||
|
$deposit = array('total' => 0, 'ledgers' => array());
|
||||||
|
foreach ($this->data['Tillable']['Ledger'] AS $ledger_id => $ledger) {
|
||||||
|
if (!$ledger['checked'])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
$ledger_entries =
|
||||||
|
$this->Account->Ledger->find
|
||||||
|
('all',
|
||||||
|
array('link' => array
|
||||||
|
('Account' =>
|
||||||
|
array('fields' => array('name')),
|
||||||
|
|
||||||
|
'LedgerEntry' =>
|
||||||
|
array('fields' => array('id', 'amount'),
|
||||||
|
|
||||||
|
'MonetarySource' =>
|
||||||
|
array('fields' => array('name')),
|
||||||
|
|
||||||
|
'Customer' =>
|
||||||
|
array('fields' => array('name')),
|
||||||
|
|
||||||
|
//'Transaction' =>
|
||||||
|
//array('fields' => array('stamp')),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'fields' => false,
|
||||||
|
'conditions' => array(array('Ledger.id' => $ledger_id),
|
||||||
|
array('LedgerEntry.id IS NOT NULL'),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
$deposit['total'] += $ledger['amount'];
|
||||||
|
$deposit['ledgers'][] = array('id' => $ledger_id,
|
||||||
|
'name' => $ledger['account_name'],
|
||||||
|
'total' => $ledger['amount'],
|
||||||
|
'entries' => $ledger_entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform the accounting work necessary to close the
|
||||||
|
// monetary ledgers and deposit into the bank account.
|
||||||
|
$this->Account->closeAndDeposit($deposit['ledgers'], $this->data['Deposit']['Account']['id']);
|
||||||
|
|
||||||
|
$title = 'Account: Deposit Slip';
|
||||||
|
$this->set(compact('title', 'deposit'));
|
||||||
|
$this->render('deposit_slip');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare a close page...
|
||||||
|
$tillable_account = $this->Account->relatedAccounts('tillable');
|
||||||
|
$depositable_account = $this->Account->relatedAccounts('depositable');
|
||||||
|
|
||||||
|
foreach ($tillable_account AS &$acct) {
|
||||||
|
$acct['Account']['stats'] = $this->Account->stats($acct['Account']['id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$title = 'Account: Prepare Deposit';
|
||||||
|
$this->set(compact('title', 'tillable_account', 'depositable_account'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: view
|
||||||
|
* - Displays information about a specific account
|
||||||
|
*/
|
||||||
|
|
||||||
|
function view($id = null) {
|
||||||
|
if (!$id) {
|
||||||
|
$this->Session->setFlash(__('Invalid Item.', true));
|
||||||
|
$this->redirect(array('action'=>'index'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get details about the account and its ledgers (no ledger entries yet)
|
||||||
|
$account = $this->Account->find
|
||||||
|
('first',
|
||||||
|
array('contain' =>
|
||||||
|
array(// Models
|
||||||
|
'CurrentLedger' =>
|
||||||
|
array('fields' => array('id', 'sequence')),
|
||||||
|
|
||||||
|
'Ledger' =>
|
||||||
|
array('Close' => array
|
||||||
|
('order' => array('Close.stamp' => 'DESC'))),
|
||||||
|
),
|
||||||
|
'conditions' => array(array('Account.id' => $id)),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Get all ledger entries of the CURRENT ledger
|
||||||
|
$entries = $this->Account->findLedgerEntries($id);
|
||||||
|
$account['CurrentLedger']['LedgerEntry'] = $entries['Entries'];
|
||||||
|
|
||||||
|
// Summarize each ledger
|
||||||
|
foreach($account['Ledger'] AS &$ledger)
|
||||||
|
$ledger = array_merge($ledger,
|
||||||
|
$this->Account->Ledger->stats($ledger['id']));
|
||||||
|
|
||||||
|
// Obtain stats across ALL ledgers for the summary infobox
|
||||||
|
$stats = $this->Account->stats($id, true);
|
||||||
|
$stats = $stats['Ledger'];
|
||||||
|
|
||||||
|
$this->sidemenu_links[] =
|
||||||
|
array('name' => 'Operations', 'header' => true);
|
||||||
|
$this->sidemenu_links[] =
|
||||||
|
array('name' => 'New Ledger', 'url' => array('action' => 'newledger', $id));
|
||||||
|
$this->sidemenu_links[] =
|
||||||
|
array('name' => 'Collected', 'url' => array('action' => 'collected', $id));
|
||||||
|
|
||||||
|
// Prepare to render
|
||||||
|
$title = 'Account: ' . $account['Account']['name'];
|
||||||
|
$this->set(compact('account', 'title', 'stats'));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class ChargesController extends AppController {
|
|
||||||
var $paginate = array('limit' => 100,
|
|
||||||
'group' => 'Charge.id',
|
|
||||||
'order' => array('Charge.charge_date' => 'ASC'));
|
|
||||||
|
|
||||||
var $sidemenu_links =
|
|
||||||
array(array('name' => 'Charges', 'header' => true),
|
|
||||||
array('name' => 'Cleared', 'url' => array('controller' => 'charges', 'action' => 'cleared')),
|
|
||||||
array('name' => 'Unresolved', 'url' => array('controller' => 'charges', 'action' => 'unresolved')),
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* override: sideMenuLinks
|
|
||||||
* - Generates controller specific links for the side menu
|
|
||||||
*/
|
|
||||||
function sideMenuLinks() {
|
|
||||||
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: index
|
|
||||||
* - Lists all charges
|
|
||||||
*/
|
|
||||||
|
|
||||||
function index() {
|
|
||||||
$this->all();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: cleared
|
|
||||||
* - Lists cleared charges
|
|
||||||
*/
|
|
||||||
|
|
||||||
function cleared() {
|
|
||||||
$this->all();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: unresolved
|
|
||||||
* - Lists unresolved charges
|
|
||||||
*/
|
|
||||||
|
|
||||||
function unresolved() {
|
|
||||||
$this->all();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: all
|
|
||||||
* - Lists all charges
|
|
||||||
*/
|
|
||||||
|
|
||||||
function all() {
|
|
||||||
$this->paginate = array_merge
|
|
||||||
($this->paginate,
|
|
||||||
array('link' =>
|
|
||||||
array(// Models
|
|
||||||
'ChargeType',
|
|
||||||
'Receipt',
|
|
||||||
'Lease' => array('fields' => array('number'))
|
|
||||||
),
|
|
||||||
));
|
|
||||||
|
|
||||||
$title = 'All Charges';
|
|
||||||
$this->set('title', $title); $this->set('heading', $title);
|
|
||||||
$this->set('charges', $this->paginate());
|
|
||||||
$this->render('index');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: view
|
|
||||||
* - Displays information about a specific charge
|
|
||||||
*/
|
|
||||||
|
|
||||||
function view($id = null) {
|
|
||||||
if (!$id) {
|
|
||||||
$this->Session->setFlash(__('Invalid Item.', true));
|
|
||||||
$this->redirect(array('action'=>'index'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->Charge->Behaviors->attach('Containable');
|
|
||||||
$this->Charge->contain
|
|
||||||
(array(// Models
|
|
||||||
'ChargeType',
|
|
||||||
'Receipt',
|
|
||||||
'Lease' => array('fields' => array('number')),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
$charge = $this->Charge->read(null, $id);
|
|
||||||
//pr($charge);
|
|
||||||
|
|
||||||
$payment_amount = 0;
|
|
||||||
foreach($charge['Receipt'] AS $receipt)
|
|
||||||
$payment_amount += $receipt['ChargesReceipt']['amount'];
|
|
||||||
$balance_amount = $charge['Charge']['total'] - $payment_amount;
|
|
||||||
|
|
||||||
/* $this->sidemenu_links[] = */
|
|
||||||
/* array('name' => 'Operations', 'header' => true); */
|
|
||||||
/* $this->sidemenu_links[] = */
|
|
||||||
/* array('name' => 'Move-Out', 'url' => array('controller' => 'charges', 'action' => 'move-out')); */
|
|
||||||
|
|
||||||
$title = 'Charge #' . $charge['Charge']['id'];
|
|
||||||
$this->set(compact('charge', 'title',
|
|
||||||
'payment_amount',
|
|
||||||
'balance_amount'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
class ContactsController extends AppController {
|
class ContactsController extends AppController {
|
||||||
var $paginate = array('limit' => 100,
|
|
||||||
'group' => 'Contact.id',
|
|
||||||
'order' => array('Contact.last_name' => 'ASC',
|
|
||||||
'Contact.first_name' => 'ASC'));
|
|
||||||
|
|
||||||
var $sidemenu_links =
|
var $sidemenu_links = array();
|
||||||
array(array('name' => 'Tenants', 'header' => true),
|
|
||||||
array('name' => 'Current', 'url' => array('controller' => 'contacts', 'action' => 'current')),
|
|
||||||
array('name' => 'Past', 'url' => array('controller' => 'contacts', 'action' => 'past')),
|
|
||||||
array('name' => 'All Tenants', 'url' => array('controller' => 'contacts', 'action' => 'tenants')),
|
|
||||||
array('name' => 'All Contacts', 'url' => array('controller' => 'contacts', 'action' => 'all')),
|
|
||||||
);
|
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
@@ -28,110 +18,37 @@ class ContactsController extends AppController {
|
|||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
* action: index
|
* action: index / all
|
||||||
* - Lists all current tenants
|
* - Generate a listing of contacts
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function index() {
|
function index() { $this->all(); }
|
||||||
$this->current();
|
function all() { $this->jqGridView('All Contacts', 'all'); }
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
* action: past
|
* virtuals: jqGridData
|
||||||
* - Lists all tenants, past and present
|
* - With the application controller handling the jqGridData action,
|
||||||
|
* these virtual functions ensure that the correct data is passed
|
||||||
|
* to jqGrid.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function tenants() {
|
function jqGridDataOrder(&$params, &$model, $index, $direction) {
|
||||||
$this->paginate = array_merge
|
$order = parent::jqGridDataOrder($params, $model, $index, $direction);
|
||||||
($this->paginate,
|
if ($index === 'Contact.last_name') {
|
||||||
array('link' =>
|
$order[] = 'Contact.first_name ' . $direction;
|
||||||
array(// Models
|
}
|
||||||
'Lease' =>
|
if ($index === 'Contact.first_name') {
|
||||||
array('fields' => array(),
|
$order[] = 'Contact.last_name ' . $direction;
|
||||||
'type' => 'INNER',
|
}
|
||||||
),
|
return $order;
|
||||||
),
|
|
||||||
'conditions' => array('ContactsLease.type !=' => 'ALTERNATE')
|
|
||||||
));
|
|
||||||
|
|
||||||
$title = 'All Tenants';
|
|
||||||
$this->set('title', $title); $this->set('heading', $title);
|
|
||||||
$this->set('contacts', $this->paginate());
|
|
||||||
$this->render('index');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
|
||||||
/**************************************************************************
|
$links['Contact'] = array('id');
|
||||||
**************************************************************************
|
return parent::jqGridRecordLinks($params, $model, $records, $links);
|
||||||
**************************************************************************
|
|
||||||
* action: current
|
|
||||||
* - Lists all current tenants
|
|
||||||
*/
|
|
||||||
|
|
||||||
function current() {
|
|
||||||
$this->paginate = array_merge
|
|
||||||
($this->paginate,
|
|
||||||
array('link' =>
|
|
||||||
array(// Models
|
|
||||||
'Lease' =>
|
|
||||||
array('fields' => array(),
|
|
||||||
'type' => 'INNER',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
'conditions' => array('ContactsLease.type !=' => 'ALTERNATE',
|
|
||||||
'Lease.close_date IS NULL')
|
|
||||||
));
|
|
||||||
|
|
||||||
$title = 'Current Tenants';
|
|
||||||
$this->set('title', $title); $this->set('heading', $title);
|
|
||||||
$this->set('contacts', $this->paginate());
|
|
||||||
$this->render('index');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: past
|
|
||||||
* - Lists all past tenants
|
|
||||||
*/
|
|
||||||
|
|
||||||
function past() {
|
|
||||||
$this->paginate = array_merge
|
|
||||||
($this->paginate,
|
|
||||||
array('link' =>
|
|
||||||
array(// Models
|
|
||||||
'Lease' =>
|
|
||||||
array('fields' => array(),
|
|
||||||
'type' => 'INNER',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
'conditions' => array('ContactsLease.type !=' => 'ALTERNATE',
|
|
||||||
'Lease.close_date IS NOT NULL')
|
|
||||||
));
|
|
||||||
|
|
||||||
$title = 'Past Tenants';
|
|
||||||
$this->set('title', $title); $this->set('heading', $title);
|
|
||||||
$this->set('contacts', $this->paginate());
|
|
||||||
$this->render('index');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: all
|
|
||||||
* - Lists all contacts, including non-tenants
|
|
||||||
*/
|
|
||||||
|
|
||||||
function all() {
|
|
||||||
$title = 'All Contacts';
|
|
||||||
$this->set('title', $title); $this->set('heading', $title);
|
|
||||||
$this->set('contacts', $this->paginate());
|
|
||||||
$this->render('index');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -148,56 +65,140 @@ class ContactsController extends AppController {
|
|||||||
$this->redirect(array('action'=>'index'));
|
$this->redirect(array('action'=>'index'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->Contact->Behaviors->attach('Containable');
|
$contact = $this->Contact->find
|
||||||
$this->Contact->contain
|
('first', array
|
||||||
(array(// Models
|
('contain' => array
|
||||||
'ContactPhone',
|
(// Models
|
||||||
'ContactEmail',
|
'ContactPhone',
|
||||||
'ContactAddress',
|
'ContactEmail',
|
||||||
'Lease' =>
|
'ContactAddress',
|
||||||
array('order' => 'movein_date',
|
'Customer'),
|
||||||
'conditions' => array('Lease.lease_date IS NOT NULL',
|
|
||||||
'ContactsLease.type !=' => 'ALTERNATE'),
|
|
||||||
// Models
|
|
||||||
'Unit' =>
|
|
||||||
array('order' => array('sort_order'),
|
|
||||||
'fields' => array('id', 'name'),
|
|
||||||
),
|
|
||||||
'Charge' =>
|
|
||||||
array('order' => array('charge_date'),
|
|
||||||
// Models
|
|
||||||
'ChargeType',
|
|
||||||
'Receipt',
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
$contact = $this->Contact->read(null, $id);
|
|
||||||
|
|
||||||
$outstanding_deposit = 0;
|
'conditions' => array('Contact.id' => $id),
|
||||||
$outstanding_balance = 0;
|
));
|
||||||
foreach($contact['Lease'] AS $lease) {
|
|
||||||
foreach($lease['Charge'] AS $charge) {
|
// Set up dynamic menu items
|
||||||
$outstanding_balance += $charge['total'];
|
$this->sidemenu_links[] =
|
||||||
foreach ($charge['Receipt'] AS $receipt) {
|
array('name' => 'Operations', 'header' => true);
|
||||||
$outstanding_balance -= $receipt['ChargesReceipt']['amount'];
|
|
||||||
// REVISIT <AP> 20090530:
|
$this->sidemenu_links[] =
|
||||||
// Using hardcoded value for security deposit...
|
array('name' => 'Edit',
|
||||||
// That can't be good!
|
'url' => array('action' => 'edit',
|
||||||
if ($charge['charge_type_id'] == 1)
|
$id));
|
||||||
$outstanding_deposit += $receipt['ChargesReceipt']['amount'];
|
|
||||||
|
// Prepare to render.
|
||||||
|
$title = 'Contact: ' . $contact['Contact']['display_name'];
|
||||||
|
$this->set(compact('contact', 'title'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: edit
|
||||||
|
*/
|
||||||
|
|
||||||
|
function edit($id = null, $customer_id = null) {
|
||||||
|
if (isset($this->data)) {
|
||||||
|
|
||||||
|
if (isset($this->params['form']['cancel'])) {
|
||||||
|
if (isset($this->data['Contact']['id']))
|
||||||
|
$this->redirect(array('action'=>'view', $this->data['Contact']['id']));
|
||||||
|
/* else */
|
||||||
|
/* $this->redirect(array('controller' => 'customers', */
|
||||||
|
/* 'action'=>'add', $this->data['Customer']['id'])); */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go through each contact method and strip the bogus ID if new
|
||||||
|
foreach (array_intersect_key($this->data,
|
||||||
|
array('ContactPhone'=>1,
|
||||||
|
'ContactAddress'=>1,
|
||||||
|
'ContactEmail'=>1)) AS $type => $arr) {
|
||||||
|
foreach ($arr AS $idx => $item) {
|
||||||
|
if (isset($item['source']) && $item['source'] === 'new')
|
||||||
|
unset($this->data[$type][$idx]['id']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save the contact and all associated data
|
||||||
|
$this->Contact->saveContact($this->data['Contact']['id'], $this->data);
|
||||||
|
|
||||||
|
// Now that the work is done, let the user view the updated contact
|
||||||
|
$this->redirect(array('action'=>'view', $this->data['Contact']['id']));
|
||||||
|
//$this->render('/empty');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->sidemenu_links[] =
|
if ($id) {
|
||||||
array('name' => 'Operations', 'header' => true);
|
$this->data = $this->Contact->find
|
||||||
$this->sidemenu_links[] =
|
('first', array
|
||||||
array('name' => 'Move-Out', 'url' => array('controller' => 'units', 'action' => 'move-out'));
|
('contain' => array
|
||||||
|
(// Models
|
||||||
|
'ContactPhone',
|
||||||
|
'ContactEmail',
|
||||||
|
'ContactAddress',
|
||||||
|
'Customer'),
|
||||||
|
|
||||||
$title = $contact['Contact']['display_name'];
|
'conditions' => array('Contact.id' => $id),
|
||||||
$this->set(compact('contact', 'title',
|
));
|
||||||
'outstanding_balance',
|
|
||||||
'outstanding_deposit'));
|
$title = 'Contact: ' . $this->data['Contact']['display_name'] . " : Edit";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$title = "Enter New Contact";
|
||||||
|
$this->data = array('ContactPhone' => array(),
|
||||||
|
'ContactAddress' => array(),
|
||||||
|
'ContactEmail' => array());
|
||||||
|
}
|
||||||
|
|
||||||
|
$phone_types = array_flip($this->Contact->ContactPhone->getEnumValues('type'));
|
||||||
|
unset($phone_types[0]);
|
||||||
|
// REVISIT <AP> 20090705
|
||||||
|
// Use this to have a mixed case enum
|
||||||
|
// array_map('ucfirst', array_map('strtolower', $phone_types))
|
||||||
|
$phone_types = array_combine($phone_types, $phone_types);
|
||||||
|
$this->set(compact('phone_types'));
|
||||||
|
|
||||||
|
$method_types = array_flip($this->Contact->getEnumValues
|
||||||
|
('type',
|
||||||
|
$this->Contact->tablePrefix . 'contacts_methods'));
|
||||||
|
unset($method_types[0]);
|
||||||
|
$method_types = array_combine($method_types, $method_types);
|
||||||
|
$this->set(compact('method_types'));
|
||||||
|
|
||||||
|
$method_preferences = array_flip($this->Contact->getEnumValues
|
||||||
|
('preference',
|
||||||
|
$this->Contact->tablePrefix . 'contacts_methods'));
|
||||||
|
unset($method_preferences[0]);
|
||||||
|
$method_preferences = array_combine($method_preferences, $method_preferences);
|
||||||
|
$this->set(compact('method_preferences'));
|
||||||
|
|
||||||
|
$contact_phones = $this->Contact->ContactPhone->phoneList();
|
||||||
|
$this->set(compact('contact_phones'));
|
||||||
|
|
||||||
|
$contact_addresses = $this->Contact->ContactAddress->addressList();
|
||||||
|
$this->set(compact('contact_addresses'));
|
||||||
|
|
||||||
|
$contact_emails = $this->Contact->ContactEmail->emailList();
|
||||||
|
$this->set(compact('contact_emails'));
|
||||||
|
|
||||||
|
// Prepare to render.
|
||||||
|
//pr($this->data);
|
||||||
|
$this->set(compact('title'));
|
||||||
|
$this->render('edit');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: add
|
||||||
|
* - Adds a new contact
|
||||||
|
*/
|
||||||
|
|
||||||
|
function add($customer_id = null) {
|
||||||
|
$this->edit(null, $customer_id);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
485
site/controllers/customers_controller.php
Normal file
485
site/controllers/customers_controller.php
Normal file
@@ -0,0 +1,485 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class CustomersController extends AppController {
|
||||||
|
var $sidemenu_links =
|
||||||
|
array(array('name' => 'Customers', 'header' => true),
|
||||||
|
array('name' => 'Current', 'url' => array('controller' => 'customers', 'action' => 'current')),
|
||||||
|
array('name' => 'Past', 'url' => array('controller' => 'customers', 'action' => 'past')),
|
||||||
|
array('name' => 'All', 'url' => array('controller' => 'customers', 'action' => 'all')),
|
||||||
|
array('name' => 'Add Customer', 'url' => array('controller' => 'customers', 'action' => 'add')),
|
||||||
|
);
|
||||||
|
|
||||||
|
//var $components = array('RequestHandler');
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* override: sideMenuLinks
|
||||||
|
* - Generates controller specific links for the side menu
|
||||||
|
*/
|
||||||
|
function sideMenuLinks() {
|
||||||
|
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: index / current / past / all
|
||||||
|
* - Creates a list of customers
|
||||||
|
*/
|
||||||
|
|
||||||
|
function index() { $this->current(); }
|
||||||
|
function current() { $this->jqGridView('Current Tenants', 'current'); }
|
||||||
|
function past() { $this->jqGridView('Past Tenants'); }
|
||||||
|
function all() { $this->jqGridView('All Customers'); }
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* virtuals: jqGridData
|
||||||
|
* - With the application controller handling the jqGridData action,
|
||||||
|
* these virtual functions ensure that the correct data is passed
|
||||||
|
* to jqGrid.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function jqGridDataSetup(&$params) {
|
||||||
|
parent::jqGridDataSetup($params);
|
||||||
|
if (!isset($params['action']))
|
||||||
|
$params['action'] = 'all';
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataCountTables(&$params, &$model) {
|
||||||
|
return array
|
||||||
|
('link' =>
|
||||||
|
array(// Models
|
||||||
|
'PrimaryContact',
|
||||||
|
'CurrentLease' => array('fields' => array()),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataTables(&$params, &$model) {
|
||||||
|
$link = $this->jqGridDataCountTables($params, $model);
|
||||||
|
$link['link']['LedgerEntry'] = array('fields' => array());
|
||||||
|
$link['link']['LedgerEntry']['Ledger'] = array('fields' => array());
|
||||||
|
$link['link']['LedgerEntry']['Ledger']['Account'] = array('fields' => array());
|
||||||
|
// INNER JOIN would be great, as it would ensure we're only looking
|
||||||
|
// at the ledger entries that we truly want. However, this also
|
||||||
|
// removes from the query any units that do not yet have a ledger
|
||||||
|
// entry in A/R. A solution would be to INNER JOIN these tables,
|
||||||
|
// and LEFT JOIN it to the rest. Grouping of JOINs, however, is
|
||||||
|
// implemented with the 'joins' tag, and is not available through
|
||||||
|
// the Linkable behavior interface.
|
||||||
|
//$link['link']['LedgerEntry']['Ledger']['Account']['type'] = 'INNER';
|
||||||
|
$link['link']['LedgerEntry']['Ledger']['Account']['conditions']
|
||||||
|
= array('Account.id' =>
|
||||||
|
$this->Customer->LedgerEntry->Ledger->Account->accountReceivableAccountID());
|
||||||
|
return $link;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataFields(&$params, &$model) {
|
||||||
|
$db = &$model->getDataSource();
|
||||||
|
$fields = $db->fields($model, $model->alias);
|
||||||
|
$fields[] = ('COUNT(DISTINCT CurrentLease.id) AS lease_count');
|
||||||
|
$fields[] = ("SUM(IF(Account.id IS NULL, 0," .
|
||||||
|
" IF(LedgerEntry.debit_ledger_id = Account.id," .
|
||||||
|
" 1, -1))" .
|
||||||
|
" * IF(LedgerEntry.amount IS NULL, 0, LedgerEntry.amount))" .
|
||||||
|
" AS 'balance'");
|
||||||
|
return $fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataConditions(&$params, &$model) {
|
||||||
|
$conditions = parent::jqGridDataConditions($params, $model);
|
||||||
|
|
||||||
|
if ($params['action'] === 'current') {
|
||||||
|
$conditions[] = 'CurrentLease.id IS NOT NULL';
|
||||||
|
}
|
||||||
|
elseif ($params['action'] === 'past') {
|
||||||
|
$conditions[] = 'CurrentLease.id IS NULL';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $conditions;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataOrder(&$params, &$model, $index, $direction) {
|
||||||
|
$order = array();
|
||||||
|
$order[] = parent::jqGridDataOrder($params, $model, $index, $direction);
|
||||||
|
|
||||||
|
if ($index !== 'PrimaryContact.last_name')
|
||||||
|
$order[] = parent::jqGridDataOrder($params, $model,
|
||||||
|
'PrimaryContact.last_name', $direction);
|
||||||
|
if ($index !== 'PrimaryContact.first_name')
|
||||||
|
$order[] = parent::jqGridDataOrder($params, $model,
|
||||||
|
'PrimaryContact.first_name', $direction);
|
||||||
|
if ($index !== 'Customer.id')
|
||||||
|
$order[] = parent::jqGridDataOrder($params, $model,
|
||||||
|
'Customer.id', $direction);
|
||||||
|
|
||||||
|
return $order;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataRecordCount(&$params, &$model, $query) {
|
||||||
|
|
||||||
|
// We don't have a good way to use the query to obtain
|
||||||
|
// our count. The problem is that we're relying on the
|
||||||
|
// group by for the query, which will destroy the count,
|
||||||
|
// whether we omit the group by or leave it in.
|
||||||
|
// So, build a fresh query for counting.
|
||||||
|
|
||||||
|
$query['conditions'] = parent::jqGridDataConditions($params, $model);
|
||||||
|
|
||||||
|
$count = $model->find('count',
|
||||||
|
array_merge(array('link' => array_diff_key($query['link'],
|
||||||
|
array('CurrentLease'=>1))),
|
||||||
|
array_diff_key($query, array('link'=>1))));
|
||||||
|
|
||||||
|
if ($params['action'] === 'all')
|
||||||
|
return $count;
|
||||||
|
|
||||||
|
$query['conditions'][] = 'CurrentLease.id IS NULL';
|
||||||
|
$count_past = $model->find('count', $query);
|
||||||
|
|
||||||
|
// Since we can't easily count 'current' directly, we
|
||||||
|
// can quickly derive it since 'current' customers
|
||||||
|
// are mutually exclusive to 'past' customers.
|
||||||
|
if ($params['action'] == 'current')
|
||||||
|
$count = $count - $count_past;
|
||||||
|
elseif ($params['action'] == 'past') {
|
||||||
|
$count = $count_past;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $count;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataRecords(&$params, &$model, $query) {
|
||||||
|
$customers = parent::jqGridDataRecords($params, $model, $query);
|
||||||
|
|
||||||
|
// Get the balance on each customer.
|
||||||
|
foreach ($customers AS &$customer) {
|
||||||
|
$stats = $this->Customer->stats($customer['Customer']['id']);
|
||||||
|
$customer['Customer']['balance'] = $stats['balance'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $customers;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
|
||||||
|
$links['Customer'] = array('name');
|
||||||
|
return parent::jqGridRecordLinks($params, $model, $records, $links);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: move_in
|
||||||
|
* - Sets up the move-in page for the given customer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function move_in($id = null) {
|
||||||
|
$customer = array();
|
||||||
|
$unit = array();
|
||||||
|
|
||||||
|
if (isset($id)) {
|
||||||
|
$this->Customer->recursive = -1;
|
||||||
|
$customer = current($this->Customer->read(null, $id));
|
||||||
|
}
|
||||||
|
$this->set(compact('customer', 'unit'));
|
||||||
|
|
||||||
|
$title = 'Customer Move-In';
|
||||||
|
$this->set(compact('title'));
|
||||||
|
$this->render('/leases/move');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: move_out
|
||||||
|
* - prepare to move a customer out of one of their units
|
||||||
|
*/
|
||||||
|
|
||||||
|
function move_out($id) {
|
||||||
|
|
||||||
|
$customer = $this->Customer->find
|
||||||
|
('first', array
|
||||||
|
('contain' => array
|
||||||
|
(// Models
|
||||||
|
'Lease' =>
|
||||||
|
array('conditions' => array('Lease.moveout_date' => null),
|
||||||
|
// Models
|
||||||
|
'Unit' =>
|
||||||
|
array('order' => array('sort_order'),
|
||||||
|
'fields' => array('id', 'name'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
'conditions' => array('Customer.id' => $id),
|
||||||
|
));
|
||||||
|
$this->set('customer', $lease['Customer']);
|
||||||
|
$this->set('unit', array());
|
||||||
|
|
||||||
|
$redirect = array('controller' => 'customers',
|
||||||
|
'action' => 'view',
|
||||||
|
$id);
|
||||||
|
|
||||||
|
$title = $customer['Customer']['name'] . ': Prepare Move-Out';
|
||||||
|
$this->set(compact('title', 'customer', 'redirect'));
|
||||||
|
$this->render('/leases/move');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: view
|
||||||
|
* - Displays information about a specific customer
|
||||||
|
*/
|
||||||
|
|
||||||
|
function view($id = null) {
|
||||||
|
if (!$id) {
|
||||||
|
$this->Session->setFlash(__('Invalid Item.', true));
|
||||||
|
$this->redirect(array('action'=>'index'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$customer = $this->Customer->details($id);
|
||||||
|
|
||||||
|
$outstanding_balance = $customer['stats']['balance'];
|
||||||
|
$outstanding_deposit = $customer['deposits']['summary']['balance'];
|
||||||
|
|
||||||
|
// Figure out if this customer has any non-closed leases
|
||||||
|
$show_moveout = false;
|
||||||
|
$show_payment = false;
|
||||||
|
foreach ($customer['Lease'] AS $lease) {
|
||||||
|
if (!isset($lease['close_date']))
|
||||||
|
$show_payment = true;
|
||||||
|
if (!isset($lease['moveout_date']))
|
||||||
|
$show_moveout = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up dynamic menu items
|
||||||
|
$this->sidemenu_links[] =
|
||||||
|
array('name' => 'Operations', 'header' => true);
|
||||||
|
|
||||||
|
$this->sidemenu_links[] =
|
||||||
|
array('name' => 'Edit',
|
||||||
|
'url' => array('action' => 'edit',
|
||||||
|
$id));
|
||||||
|
|
||||||
|
$this->sidemenu_links[] =
|
||||||
|
array('name' => 'Move-In',
|
||||||
|
'url' => array('action' => 'move_in',
|
||||||
|
$id));
|
||||||
|
|
||||||
|
/* if ($show_moveout) { */
|
||||||
|
/* $this->sidemenu_links[] = */
|
||||||
|
/* array('name' => 'Move-Out', */
|
||||||
|
/* 'url' => array('action' => 'move_out', */
|
||||||
|
/* $id)); */
|
||||||
|
/* } */
|
||||||
|
|
||||||
|
if ($show_payment) {
|
||||||
|
$this->sidemenu_links[] =
|
||||||
|
array('name' => 'Payment',
|
||||||
|
'url' => array('action' => 'receipt',
|
||||||
|
$id));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare to render.
|
||||||
|
$title = 'Customer: ' . $customer['Customer']['name'];
|
||||||
|
$this->set(compact('customer', 'title',
|
||||||
|
'outstanding_balance',
|
||||||
|
'outstanding_deposit'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: edit
|
||||||
|
* - Edit customer information
|
||||||
|
*/
|
||||||
|
|
||||||
|
function edit($id = null) {
|
||||||
|
if (isset($this->data)) {
|
||||||
|
// Check to see if the operation was cancelled.
|
||||||
|
if (isset($this->params['form']['cancel'])) {
|
||||||
|
if (isset($this->data['Customer']['id']))
|
||||||
|
$this->redirect(array('action'=>'view', $this->data['Customer']['id']));
|
||||||
|
else
|
||||||
|
$this->redirect(array('action'=>'index'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure we have at least one contact
|
||||||
|
if (!isset($this->data['Contact']) || count($this->data['Contact']) == 0) {
|
||||||
|
$this->Session->setFlash("MUST SPECIFY AT LEAST ONE CONTACT", true);
|
||||||
|
$this->redirect(array('action'=>'view', $this->data['Customer']['id']));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure there is a primary contact
|
||||||
|
if (!isset($this->data['Customer']['primary_contact_entry'])) {
|
||||||
|
$this->Session->setFlash("MUST SPECIFY A PRIMARY CONTACT", true);
|
||||||
|
$this->redirect(array('action'=>'view', $this->data['Customer']['id']));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go through each customer and strip the bogus ID if new
|
||||||
|
foreach ($this->data['Contact'] AS &$contact) {
|
||||||
|
if (isset($contact['source']) && $contact['source'] === 'new')
|
||||||
|
unset($contact['id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the customer and all associated data
|
||||||
|
if (!$this->Customer->saveCustomer($this->data['Customer']['id'],
|
||||||
|
$this->data,
|
||||||
|
$this->data['Customer']['primary_contact_entry'])) {
|
||||||
|
$this->Session->setFlash("CUSTOMER SAVE FAILED", true);
|
||||||
|
pr("CUSTOMER SAVE FAILED");
|
||||||
|
}
|
||||||
|
|
||||||
|
// If existing customer, then view it. Otherwise, since
|
||||||
|
// this is a new customer, go to the move in screen.
|
||||||
|
if ($this->data['Customer']['id'])
|
||||||
|
$this->redirect(array('action'=>'view', $this->Customer->id));
|
||||||
|
else
|
||||||
|
$this->redirect(array('action'=>'move_in', $this->Customer->id));
|
||||||
|
|
||||||
|
// For debugging, only if the redirects above have been
|
||||||
|
// commented out, otherwise this section isn't reached.
|
||||||
|
$this->render('/empty');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($id) {
|
||||||
|
$this->data = $this->Customer->details($id);
|
||||||
|
$title = 'Customer: ' . $this->data['Customer']['name'] . " : Edit";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$title = "Enter New Customer";
|
||||||
|
$this->data = array('Contact' => array(), 'PrimaryContact' => null);
|
||||||
|
}
|
||||||
|
|
||||||
|
$contact_types = array_flip($this->Customer->ContactsCustomer->getEnumValues('type'));
|
||||||
|
unset($contact_types[0]);
|
||||||
|
$contact_types = array_combine($contact_types, $contact_types);
|
||||||
|
$this->set(compact('contact_types'));
|
||||||
|
|
||||||
|
$contacts = $this->Customer->Contact->contactList();
|
||||||
|
$this->set(compact('contacts'));
|
||||||
|
|
||||||
|
// Prepare to render.
|
||||||
|
//pr($this->data);
|
||||||
|
$this->set(compact('title'));
|
||||||
|
$this->render('edit');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: add
|
||||||
|
* - Add a new customer
|
||||||
|
*/
|
||||||
|
|
||||||
|
function add() {
|
||||||
|
$this->edit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: receipt
|
||||||
|
* - Sets up the receipt entry page for the given customer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function receipt($id = null) {
|
||||||
|
if (isset($id)) {
|
||||||
|
$this->Customer->recursive = -1;
|
||||||
|
$customer = $this->Customer->read(null, $id);
|
||||||
|
$customer = $customer['Customer'];
|
||||||
|
$unreconciled = $this->Customer->findUnreconciledLedgerEntries($id);
|
||||||
|
$charges = $unreconciled['debit'];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$customer = null;
|
||||||
|
$charges = array('balance' => 0, 'entry' => array());
|
||||||
|
}
|
||||||
|
|
||||||
|
$A = new Account();
|
||||||
|
$payment_accounts = $A->paymentAccounts();
|
||||||
|
$default_account = $A->cashAccountID();
|
||||||
|
$this->set(compact('payment_accounts', 'default_account'));
|
||||||
|
|
||||||
|
$title = ($customer['name'] . ': Payment Entry');
|
||||||
|
$this->set(compact('customer', 'charges', 'title'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: refund
|
||||||
|
* - Refunds customer charges
|
||||||
|
*/
|
||||||
|
|
||||||
|
function refund() {
|
||||||
|
$entries = $this->Customer->LedgerEntry->find
|
||||||
|
('all', array
|
||||||
|
('contain' => false,
|
||||||
|
'conditions' => array('LedgerEntry.id' =>
|
||||||
|
//array(199,200,201)
|
||||||
|
61
|
||||||
|
),
|
||||||
|
));
|
||||||
|
pr(compact('entries'));
|
||||||
|
|
||||||
|
$this->Customer->LedgerEntry->reverse($entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: unreconciledEntries
|
||||||
|
* - returns the list of unreconciled entries
|
||||||
|
*/
|
||||||
|
|
||||||
|
function unreconciled($id) {
|
||||||
|
|
||||||
|
//$this->layout = 'ajax';
|
||||||
|
$this->layout = null;
|
||||||
|
$this->autoLayout = false;
|
||||||
|
$this->autoRender = false;
|
||||||
|
Configure::write('debug', '0');
|
||||||
|
header("Content-type: text/xml;charset=utf-8");
|
||||||
|
|
||||||
|
App::import('Helper', 'Xml');
|
||||||
|
$xml = new XmlHelper();
|
||||||
|
|
||||||
|
// Find the unreconciled entries, then manipulate the structure
|
||||||
|
// slightly to accomodate the format necessary for XML Helper.
|
||||||
|
$unreconciled = $this->Customer->findUnreconciledLedgerEntries($id);
|
||||||
|
$unreconciled = array('entries' =>
|
||||||
|
array_intersect_key($unreconciled['debit'],
|
||||||
|
array('entry'=>1, 'balance'=>1)));
|
||||||
|
|
||||||
|
// XML Helper will dump an empty tag if the array is empty
|
||||||
|
if (!count($unreconciled['entries']['entry']))
|
||||||
|
unset($unreconciled['entries']['entry']);
|
||||||
|
|
||||||
|
pr($unreconciled);
|
||||||
|
//$reconciled = $cust->reconcileNewLedgerEntry($cust_id, 'credit', $amount);
|
||||||
|
|
||||||
|
$opts = array();
|
||||||
|
//$opts['format'] = 'tags';
|
||||||
|
echo $xml->header();
|
||||||
|
echo $xml->serialize($unreconciled, $opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
507
site/controllers/leases_controller.php
Normal file
507
site/controllers/leases_controller.php
Normal file
@@ -0,0 +1,507 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class LeasesController extends AppController {
|
||||||
|
|
||||||
|
var $sidemenu_links =
|
||||||
|
array(array('name' => 'Leases', 'header' => true),
|
||||||
|
array('name' => 'Active', 'url' => array('controller' => 'leases', 'action' => 'active')),
|
||||||
|
array('name' => 'Closed', 'url' => array('controller' => 'leases', 'action' => 'closed')),
|
||||||
|
array('name' => 'All', 'url' => array('controller' => 'leases', 'action' => 'all')),
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* override: sideMenuLinks
|
||||||
|
* - Generates controller specific links for the side menu
|
||||||
|
*/
|
||||||
|
function sideMenuLinks() {
|
||||||
|
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: index / active / closed / all
|
||||||
|
* - Generate a listing of leases
|
||||||
|
*/
|
||||||
|
|
||||||
|
function index() { $this->all(); }
|
||||||
|
function active() { $this->jqGridView('Active Leases'); }
|
||||||
|
function closed() { $this->jqGridView('Closed Leases'); }
|
||||||
|
function all() { $this->jqGridView('All Leases', 'all'); }
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* virtuals: jqGridData
|
||||||
|
* - With the application controller handling the jqGridData action,
|
||||||
|
* these virtual functions ensure that the correct data is passed
|
||||||
|
* to jqGrid.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function jqGridDataSetup(&$params) {
|
||||||
|
parent::jqGridDataSetup($params);
|
||||||
|
if (!isset($params['action']))
|
||||||
|
$params['action'] = 'all';
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataCountTables(&$params, &$model) {
|
||||||
|
return array
|
||||||
|
('link' => array('Unit' => array('fields' => array('Unit.id', 'Unit.name')),
|
||||||
|
'Customer' => array('fields' => array('Customer.id', 'Customer.name'))));
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataTables(&$params, &$model) {
|
||||||
|
$link = $this->jqGridDataCountTables($params, $model);
|
||||||
|
$link['link']['LedgerEntry'] = array('fields' => array());
|
||||||
|
$link['link']['LedgerEntry']['Ledger'] = array('fields' => array());
|
||||||
|
$link['link']['LedgerEntry']['Ledger']['Account'] = array('fields' => array());
|
||||||
|
// INNER JOIN would be great, as it would ensure we're only looking
|
||||||
|
// at the ledger entries that we truly want. However, this also
|
||||||
|
// removes from the query any leases that do not yet have a ledger
|
||||||
|
// entry in A/R. A solution would be to INNER JOIN these tables,
|
||||||
|
// and LEFT JOIN it to the rest. Grouping of JOINs, however, is
|
||||||
|
// implemented with the 'joins' tag, and is not available through
|
||||||
|
// the Linkable behavior interface.
|
||||||
|
//$link['link']['LedgerEntry']['Ledger']['Account']['type'] = 'INNER';
|
||||||
|
$link['link']['LedgerEntry']['Ledger']['Account']['conditions']
|
||||||
|
= array('Account.id' =>
|
||||||
|
$this->Lease->LedgerEntry->Ledger->Account->accountReceivableAccountID());
|
||||||
|
return $link;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataFields(&$params, &$model) {
|
||||||
|
$db = &$model->getDataSource();
|
||||||
|
$fields = $db->fields($model, $model->alias);
|
||||||
|
$fields[] = ("SUM(IF(Account.id IS NULL, 0," .
|
||||||
|
" IF(LedgerEntry.debit_ledger_id = Account.id," .
|
||||||
|
" 1, -1))" .
|
||||||
|
" * IF(LedgerEntry.amount IS NULL, 0, LedgerEntry.amount))" .
|
||||||
|
" AS 'balance'");
|
||||||
|
return $fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataConditions(&$params, &$model) {
|
||||||
|
$conditions = parent::jqGridDataConditions($params, $model);
|
||||||
|
|
||||||
|
if ($params['action'] === 'active') {
|
||||||
|
$conditions[] = 'Lease.close_date IS NULL';
|
||||||
|
}
|
||||||
|
elseif ($params['action'] === 'closed') {
|
||||||
|
$conditions[] = 'Lease.close_date IS NOT NULL';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $conditions;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataOrder(&$params, &$model, $index, $direction) {
|
||||||
|
// Do not sort by number, which is type varchar and
|
||||||
|
// sorts on an ascii basis. Sort by ID instead.
|
||||||
|
if ($index === 'Lease.number')
|
||||||
|
$index = 'Lease.id';
|
||||||
|
|
||||||
|
// Instead of sorting by name, sort by defined order
|
||||||
|
if ($index === 'Unit.name')
|
||||||
|
$index = 'Unit.sort_order';
|
||||||
|
|
||||||
|
$order = array();
|
||||||
|
$order[] = parent::jqGridDataOrder($params, $model, $index, $direction);
|
||||||
|
|
||||||
|
// If sorting by anything other than id/number
|
||||||
|
// add sorting by id as a secondary condition.
|
||||||
|
if ($index !== 'Lease.id' && $index !== 'Lease.number')
|
||||||
|
$order[] = parent::jqGridDataOrder($params, $model,
|
||||||
|
'Lease.id', $direction);
|
||||||
|
|
||||||
|
return $order;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* function jqGridRecordsPostProcess(&$params, &$model, &$records) { */
|
||||||
|
/* foreach ($records AS &$record) { */
|
||||||
|
/* $record['Lease']['through_date'] */
|
||||||
|
/* = $this->Lease->rentChargeThrough($record['Lease']['id']); */
|
||||||
|
/* } */
|
||||||
|
|
||||||
|
/* parent::jqGridRecordsPostProcess($params, $model, $records); */
|
||||||
|
/* } */
|
||||||
|
|
||||||
|
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
|
||||||
|
$links['Lease'] = array('number');
|
||||||
|
$links['Unit'] = array('name');
|
||||||
|
$links['Customer'] = array('name');
|
||||||
|
return parent::jqGridRecordLinks($params, $model, $records, $links);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: move_in
|
||||||
|
* - execute a move in on a new lease
|
||||||
|
*/
|
||||||
|
|
||||||
|
function move_in() {
|
||||||
|
if (!$this->data)
|
||||||
|
die("Should have some data");
|
||||||
|
|
||||||
|
// Handle the move in based on the data given
|
||||||
|
//pr(array('Move-in data', $this->data));
|
||||||
|
|
||||||
|
$lid = $this->Lease->moveIn($this->data['Lease']['customer_id'],
|
||||||
|
$this->data['Lease']['unit_id'],
|
||||||
|
null, null,
|
||||||
|
$this->data['Lease']['movein_date'],
|
||||||
|
$this->data['Lease']['comment']
|
||||||
|
);
|
||||||
|
|
||||||
|
// Since this is a new lease, go to the invoice
|
||||||
|
// screen so we can start assessing charges.
|
||||||
|
$this->redirect(array('action'=>'invoice', $lid));
|
||||||
|
|
||||||
|
// For debugging, only if the redirect above have been
|
||||||
|
// commented out, otherwise this section isn't reached.
|
||||||
|
$this->render('/empty');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: move_out
|
||||||
|
* - prepare or execute a move out on a specific lease
|
||||||
|
*/
|
||||||
|
|
||||||
|
function move_out($id = null) {
|
||||||
|
if ($this->data) {
|
||||||
|
// Handle the move out based on the data given
|
||||||
|
//pr($this->data);
|
||||||
|
|
||||||
|
$this->Lease->moveOut($this->data['Lease']['id'],
|
||||||
|
'VACANT',
|
||||||
|
$this->data['Lease']['moveout_date'],
|
||||||
|
//true // Close this lease, if able
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->redirect($this->data['redirect']);
|
||||||
|
$this->autoRender = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($id))
|
||||||
|
die("Oh Nooooo!!");
|
||||||
|
|
||||||
|
$lease = $this->Lease->find
|
||||||
|
('first', array
|
||||||
|
('contain' => array
|
||||||
|
(// Models
|
||||||
|
'Unit' =>
|
||||||
|
array('order' => array('sort_order'),
|
||||||
|
'fields' => array('id', 'name'),
|
||||||
|
),
|
||||||
|
|
||||||
|
'Customer' =>
|
||||||
|
array('fields' => array('id', 'name'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
'conditions' => array(array('Lease.id' => $id),
|
||||||
|
array('Lease.close_date' => null),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
$this->set('customer', $lease['Customer']);
|
||||||
|
$this->set('unit', $lease['Unit']);
|
||||||
|
$this->set('lease', $lease['Lease']);
|
||||||
|
|
||||||
|
$redirect = array('controller' => 'leases',
|
||||||
|
'action' => 'view',
|
||||||
|
$id);
|
||||||
|
|
||||||
|
$title = ('Lease #' . $lease['Lease']['number'] . ': ' .
|
||||||
|
$lease['Unit']['name'] . ': ' .
|
||||||
|
$lease['Customer']['name'] . ': Prepare Move-Out');
|
||||||
|
$this->set(compact('title', 'redirect'));
|
||||||
|
$this->render('/leases/move');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: apply_deposit
|
||||||
|
* - Applies the security deposit to charges. This is much
|
||||||
|
* like a receipt, but it's separated to keep it simple and
|
||||||
|
* to prevent feature overload on the receipt page.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function apply_deposit($id) {
|
||||||
|
$A = new Account();
|
||||||
|
|
||||||
|
$lease = $this->Lease->find
|
||||||
|
('first', array
|
||||||
|
('contain' => array
|
||||||
|
(// Models
|
||||||
|
'Unit' =>
|
||||||
|
array('order' => array('sort_order'),
|
||||||
|
'fields' => array('id', 'name'),
|
||||||
|
),
|
||||||
|
|
||||||
|
'Customer' =>
|
||||||
|
array('fields' => array('id', 'name'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
'conditions' => array(array('Lease.id' => $id),
|
||||||
|
array('Lease.close_date' => null),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
|
||||||
|
// Get the lease balance, part of lease stats
|
||||||
|
$this->Lease->statsMerge($lease['Lease'],
|
||||||
|
array('stats' => $this->Lease->stats($id)));
|
||||||
|
|
||||||
|
// Determine the lease security deposit
|
||||||
|
$deposit = $this->Lease->findSecurityDeposits($lease['Lease']['id']);
|
||||||
|
$this->set(compact('deposit'));
|
||||||
|
$this->set('customer', $lease['Customer']);
|
||||||
|
$this->set('unit', $lease['Unit']);
|
||||||
|
$this->set('lease', $lease['Lease']);
|
||||||
|
$this->set('account', array('id' => $A->securityDepositAccountID()));
|
||||||
|
|
||||||
|
/* $redirect = array('controller' => 'leases', */
|
||||||
|
/* 'action' => 'view', */
|
||||||
|
/* $id); */
|
||||||
|
|
||||||
|
$title = ('Lease #' . $lease['Lease']['number'] . ': ' .
|
||||||
|
$lease['Unit']['name'] . ': ' .
|
||||||
|
$lease['Customer']['name'] . ': Utilize Security Deposit');
|
||||||
|
$this->set(compact('title', 'redirect'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: bad_debt
|
||||||
|
* - Writes off remaining charges on a lease.
|
||||||
|
* REVISIT <AP>: 20090710
|
||||||
|
* Should this be a customer function? What customer
|
||||||
|
* would have only one lease that results in bad debt.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function bad_debt($id) {
|
||||||
|
$A = new Account();
|
||||||
|
|
||||||
|
$lease = $this->Lease->find
|
||||||
|
('first', array
|
||||||
|
('contain' => array
|
||||||
|
(// Models
|
||||||
|
'Unit' =>
|
||||||
|
array('order' => array('sort_order'),
|
||||||
|
'fields' => array('id', 'name'),
|
||||||
|
),
|
||||||
|
|
||||||
|
'Customer' =>
|
||||||
|
array('fields' => array('id', 'name'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
'conditions' => array(array('Lease.id' => $id),
|
||||||
|
array('Lease.close_date' => null),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
|
||||||
|
// Get the lease balance, part of lease stats
|
||||||
|
$this->Lease->statsMerge($lease['Lease'],
|
||||||
|
array('stats' => $this->Lease->stats($id)));
|
||||||
|
|
||||||
|
// Determine the lease security deposit
|
||||||
|
$deposit = $this->Lease->findSecurityDeposits($lease['Lease']['id']);
|
||||||
|
if ($deposit['summary']['balance'] > 0)
|
||||||
|
die("Still have un-utilized security deposit");
|
||||||
|
|
||||||
|
$this->set('customer', $lease['Customer']);
|
||||||
|
$this->set('unit', $lease['Unit']);
|
||||||
|
$this->set('lease', $lease['Lease']);
|
||||||
|
$this->set('account', array('id' => $A->badDebtAccountID()));
|
||||||
|
|
||||||
|
/* $redirect = array('controller' => 'leases', */
|
||||||
|
/* 'action' => 'view', */
|
||||||
|
/* $id); */
|
||||||
|
|
||||||
|
$title = ('Lease #' . $lease['Lease']['number'] . ': ' .
|
||||||
|
$lease['Unit']['name'] . ': ' .
|
||||||
|
$lease['Customer']['name'] . ': Write Off Bad Debt');
|
||||||
|
$this->set(compact('title', 'redirect'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: refund
|
||||||
|
* - Provides user with a refund
|
||||||
|
* REVISIT <AP>: 20090710
|
||||||
|
* Should this be a customer function?
|
||||||
|
*/
|
||||||
|
|
||||||
|
function refund($id) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: close
|
||||||
|
* - Closes a lease to any further action
|
||||||
|
*/
|
||||||
|
|
||||||
|
function close($id) {
|
||||||
|
// REVISIT <AP>: 20090708
|
||||||
|
// We should probably seek confirmation first...
|
||||||
|
$this->Lease->close($id);
|
||||||
|
$this->redirect(array('action'=>'view', $id));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: invoice
|
||||||
|
* - Sets up the invoice entry page for the given customer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function invoice($id = null, $type = null) {
|
||||||
|
|
||||||
|
$lease = $this->Lease->find
|
||||||
|
('first', array
|
||||||
|
('contain' => array
|
||||||
|
(// Models
|
||||||
|
'Unit' =>
|
||||||
|
array('order' => array('sort_order'),
|
||||||
|
'fields' => array('id', 'name'),
|
||||||
|
),
|
||||||
|
|
||||||
|
'Customer' =>
|
||||||
|
array('fields' => array('id', 'name'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
'conditions' => array(array('Lease.id' => $id),
|
||||||
|
array('Lease.close_date' => null),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
$A = new Account();
|
||||||
|
$charge_accounts = $A->chargeAccounts();
|
||||||
|
$default_account = $A->rentAccountID();
|
||||||
|
$this->set(compact('charge_accounts', 'default_account'));
|
||||||
|
|
||||||
|
// REVISIT <AP> 20090705:
|
||||||
|
// Of course, the late charge should come from the late_schedule
|
||||||
|
$default_rent = $lease['Lease']['rent'];
|
||||||
|
$default_late = 10;
|
||||||
|
$this->set(compact('default_rent', 'default_late'));
|
||||||
|
|
||||||
|
$title = ('Lease #' . $lease['Lease']['number'] . ': ' .
|
||||||
|
$lease['Unit']['name'] . ': ' .
|
||||||
|
$lease['Customer']['name'] . ': Charge Entry');
|
||||||
|
$this->set(compact('title', 'lease', 'charge'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: view
|
||||||
|
* - Displays information about a specific lease
|
||||||
|
*/
|
||||||
|
|
||||||
|
function view($id = null) {
|
||||||
|
if (!$id) {
|
||||||
|
$this->Session->setFlash(__('Invalid Item.', true));
|
||||||
|
$this->redirect(array('action'=>'index'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get details about the lease and its ledgers (no ledger entries yet)
|
||||||
|
$lease = $this->Lease->find
|
||||||
|
('first',
|
||||||
|
array('contain' =>
|
||||||
|
array(// Models
|
||||||
|
'LeaseType',
|
||||||
|
'Unit',
|
||||||
|
'Customer',
|
||||||
|
),
|
||||||
|
'conditions' => array(array('Lease.id' => $id)),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$lease['Lease']['paid_through'] = $this->Lease->rentPaidThrough($id);
|
||||||
|
|
||||||
|
|
||||||
|
$this->set('charge_gaps', $this->Lease->rentChargeGaps($id));
|
||||||
|
$this->set('charge_through', $this->Lease->rentChargeThrough($id));
|
||||||
|
|
||||||
|
// Obtain the overall lease balance
|
||||||
|
$this->Lease->statsMerge($lease['Lease'],
|
||||||
|
array('stats' => $this->Lease->stats($id)));
|
||||||
|
$outstanding_balance = $lease['Lease']['stats']['balance'];
|
||||||
|
|
||||||
|
// Determine the lease security deposit
|
||||||
|
$deposits = $this->Lease->findSecurityDeposits($lease['Lease']['id']);
|
||||||
|
$outstanding_deposit = $deposits['summary']['balance'];
|
||||||
|
|
||||||
|
// Set up dynamic menu items
|
||||||
|
if (!isset($lease['Lease']['close_date'])) {
|
||||||
|
$this->sidemenu_links[] =
|
||||||
|
array('name' => 'Operations', 'header' => true);
|
||||||
|
|
||||||
|
if (!isset($lease['Lease']['moveout_date']))
|
||||||
|
$this->sidemenu_links[] =
|
||||||
|
array('name' => 'Move-Out', 'url' => array('action' => 'move_out',
|
||||||
|
$id));
|
||||||
|
|
||||||
|
$this->sidemenu_links[] =
|
||||||
|
array('name' => 'Charges', 'url' => array('action' => 'invoice',
|
||||||
|
$id));
|
||||||
|
|
||||||
|
$this->sidemenu_links[] =
|
||||||
|
array('name' => 'Payments', 'url' => array('controller' => 'customers',
|
||||||
|
'action' => 'receipt',
|
||||||
|
$lease['Customer']['id']));
|
||||||
|
|
||||||
|
if (isset($lease['Lease']['moveout_date']) && $outstanding_deposit > 0 && $outstanding_balance > 0)
|
||||||
|
$this->sidemenu_links[] =
|
||||||
|
array('name' => 'Apply Deposit', 'url' => array('action' => 'apply_deposit',
|
||||||
|
$id));
|
||||||
|
|
||||||
|
if (isset($lease['Lease']['moveout_date']) &&
|
||||||
|
$outstanding_balance <= 0 &&
|
||||||
|
($outstanding_deposit - $outstanding_balance) > 0)
|
||||||
|
$this->sidemenu_links[] =
|
||||||
|
array('name' => 'Issue Refund', 'url' => array('action' => 'refund',
|
||||||
|
$id));
|
||||||
|
|
||||||
|
if (isset($lease['Lease']['moveout_date']) && $outstanding_deposit == 0 && $outstanding_balance > 0)
|
||||||
|
$this->sidemenu_links[] =
|
||||||
|
array('name' => 'Write-Off', 'url' => array('action' => 'bad_debt',
|
||||||
|
$id));
|
||||||
|
|
||||||
|
if ($this->Lease->closeable($id))
|
||||||
|
$this->sidemenu_links[] =
|
||||||
|
array('name' => 'Close', 'url' => array('action' => 'close',
|
||||||
|
$id));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare to render
|
||||||
|
$title = 'Lease: #' . $lease['Lease']['id'];
|
||||||
|
$this->set(compact('lease', 'title',
|
||||||
|
'outstanding_deposit',
|
||||||
|
'outstanding_balance'));
|
||||||
|
}
|
||||||
|
}
|
||||||
467
site/controllers/ledger_entries_controller.php
Normal file
467
site/controllers/ledger_entries_controller.php
Normal file
@@ -0,0 +1,467 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class LedgerEntriesController extends AppController {
|
||||||
|
|
||||||
|
var $sidemenu_links = array();
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* override: sideMenuLinks
|
||||||
|
* - Generates controller specific links for the side menu
|
||||||
|
*/
|
||||||
|
function sideMenuLinks() {
|
||||||
|
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* virtuals: jqGridData
|
||||||
|
* - With the application controller handling the jqGridData action,
|
||||||
|
* these virtual functions ensure that the correct data is passed
|
||||||
|
* to jqGrid.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function jqGridDataSetup(&$params) {
|
||||||
|
parent::jqGridDataSetup($params);
|
||||||
|
if (isset($params['custom']['ar_account'])) {
|
||||||
|
$params['custom']['account_id'] =
|
||||||
|
$this->LedgerEntry->DebitLedger->Account->accountReceivableAccountID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataTables(&$params, &$model) {
|
||||||
|
$link =
|
||||||
|
array(// Models
|
||||||
|
'Transaction' =>
|
||||||
|
array('fields' => array('id', 'stamp'),
|
||||||
|
),
|
||||||
|
|
||||||
|
'MonetarySource' =>
|
||||||
|
array('fields' => array('id', 'name'),
|
||||||
|
),
|
||||||
|
|
||||||
|
'Customer' =>
|
||||||
|
array('fields' => array('id', 'name'),
|
||||||
|
),
|
||||||
|
|
||||||
|
'Lease' =>
|
||||||
|
array('fields' => array('id', 'number'),
|
||||||
|
'Unit' =>
|
||||||
|
array('fields' => array('id', 'name'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isset($params['custom']['account_ftype'])) {
|
||||||
|
$ftype = $params['custom']['account_ftype'];
|
||||||
|
$ftype = ucfirst($ftype);
|
||||||
|
//$ftype = $this->LedgerEntry->DebitLedger->Account->fundamentalOpposite($ftype);
|
||||||
|
$link[$ftype . 'Ledger'] =
|
||||||
|
array('fields' => array('id', 'sequence'),
|
||||||
|
'Account' => array('class' => 'Account',
|
||||||
|
'fields' => array('id', 'name'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
elseif (isset($params['custom']['ledger_id'])) {
|
||||||
|
$ledger_id = $params['custom']['ledger_id'];
|
||||||
|
$link['Ledger'] =
|
||||||
|
array('fields' => array('id', 'sequence'),
|
||||||
|
'conditions' => ("Ledger.id = IF(LedgerEntry.debit_ledger_id = $ledger_id," .
|
||||||
|
" LedgerEntry.credit_ledger_id," .
|
||||||
|
" LedgerEntry.debit_ledger_id)"),
|
||||||
|
'Account' => array(
|
||||||
|
'fields' => array('id', 'name'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
elseif ($params['action'] === 'collected') {
|
||||||
|
// Income / Receipt / Money
|
||||||
|
// debit: A/R credit: Income <-- this entry
|
||||||
|
// debit: Receipt credit: A/R <-- ReceiptLedgerEntry, below
|
||||||
|
// debit: Money credit: Receipt <-- MoneyLedgerEntry, below
|
||||||
|
|
||||||
|
$link['CreditLedger'] =
|
||||||
|
array('fields' => 'sequence',
|
||||||
|
'Account' =>
|
||||||
|
array('fields' => array('id', 'name'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// We're searching for the Receipt<->A/R entries,
|
||||||
|
// which are debits on the A/R account. Find the
|
||||||
|
// reconciling entries to that A/R debit.
|
||||||
|
$link['DebitReconciliationLedgerEntry'] =
|
||||||
|
array('alias' => 'ReceiptLedgerEntry',
|
||||||
|
|
||||||
|
'Transaction' =>
|
||||||
|
array('alias' => 'ReceiptTransaction'),
|
||||||
|
|
||||||
|
// Credit Ledger should be A/R;
|
||||||
|
// Debit Ledger should be Receipt
|
||||||
|
'DebitLedger' =>
|
||||||
|
array('alias' => 'ReceiptLedger',
|
||||||
|
'Account' => array('alias' => 'ReceiptAccount'),
|
||||||
|
),
|
||||||
|
|
||||||
|
// Finally, the Money (Cash/Check/etc) Entry is the one
|
||||||
|
// which reconciles our ReceiptLedgerEntry debit
|
||||||
|
'DebitReconciliationLedgerEntry' =>
|
||||||
|
array('alias' => 'MoneyLedgerEntry',
|
||||||
|
'linkalias' => 'MoneyLedgerEntryR',
|
||||||
|
|
||||||
|
// Credit Ledger should be Receipt;
|
||||||
|
// Debit Ledger should be our Money Account
|
||||||
|
'DebitLedger' =>
|
||||||
|
array('alias' => 'MoneyLedger',
|
||||||
|
'Account' =>
|
||||||
|
array('alias' => 'MoneyAccount'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$link['DebitLedger'] =
|
||||||
|
array('fields' => array('id', 'sequence'),
|
||||||
|
'DebitAccount' => array('class' => 'Account',
|
||||||
|
'fields' => array('id', 'name'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
$link['CreditLedger'] =
|
||||||
|
array('fields' => array('id', 'sequence'),
|
||||||
|
'CreditAccount' => array('class' => 'Account',
|
||||||
|
'fields' => array('id', 'name'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($params['custom']['account_id'])) {
|
||||||
|
$account_id = $params['custom']['account_id'];
|
||||||
|
$link['Ledger'] =
|
||||||
|
array('fields' => array('id', 'sequence'),
|
||||||
|
'conditions' => ("Ledger.id = IF(DebitLedger.account_id = $account_id," .
|
||||||
|
" LedgerEntry.credit_ledger_id," .
|
||||||
|
" LedgerEntry.debit_ledger_id)"),
|
||||||
|
'Account' => array(
|
||||||
|
'fields' => array('id', 'name'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($params['custom']['reconcile_id'])) {
|
||||||
|
$ftype = $params['custom']['account_ftype'];
|
||||||
|
$ftype = $this->LedgerEntry->DebitLedger->Account->fundamentalOpposite($ftype);
|
||||||
|
$ftype = ucfirst($ftype);
|
||||||
|
$link[$ftype.'ReconciliationLedgerEntry'] =
|
||||||
|
array('fields' => array('Reconciliation.amount'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return array('link' => $link);
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataFields(&$params, &$model) {
|
||||||
|
$ledger_id = (isset($params['custom']['ledger_id'])
|
||||||
|
? $params['custom']['ledger_id']
|
||||||
|
: null);
|
||||||
|
$account_id = (isset($params['custom']['account_id'])
|
||||||
|
? $params['custom']['account_id']
|
||||||
|
: null);
|
||||||
|
$account_type = (isset($params['custom']['account_type'])
|
||||||
|
? $params['custom']['account_type']
|
||||||
|
: null);
|
||||||
|
|
||||||
|
$fields = $model->ledgerContextFields2($ledger_id, $account_id, $account_type);
|
||||||
|
|
||||||
|
if (count(array_intersect($params['fields'], array('applied'))) == 1)
|
||||||
|
$fields[] = 'SUM(Reconciliation.amount) AS applied';
|
||||||
|
|
||||||
|
if ($params['action'] === 'collected')
|
||||||
|
$fields[] = 'MAX(ReceiptTransaction.stamp) AS last_paid';
|
||||||
|
|
||||||
|
return $fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataConditions(&$params, &$model) {
|
||||||
|
$ledger_id = (isset($params['custom']['ledger_id'])
|
||||||
|
? $params['custom']['ledger_id']
|
||||||
|
: null);
|
||||||
|
$account_type = (isset($params['custom']['account_type'])
|
||||||
|
? $params['custom']['account_type']
|
||||||
|
: null);
|
||||||
|
|
||||||
|
$conditions = parent::jqGridDataConditions($params, $model);
|
||||||
|
|
||||||
|
if ($params['action'] === 'collected') {
|
||||||
|
extract($params['custom']);
|
||||||
|
|
||||||
|
if (isset($collected_account_id))
|
||||||
|
$conditions[] = array('Account.id' => $params['custom']['collected_account_id']);
|
||||||
|
else
|
||||||
|
die("INTERNAL ERROR: COLLECTED ACCOUNT ID NOT SET");
|
||||||
|
|
||||||
|
if (!empty($collected_from_date))
|
||||||
|
$conditions[]
|
||||||
|
= array('ReceiptTransaction.stamp >=' =>
|
||||||
|
$this->LedgerEntry->Transaction->dateFormatBeforeSave($collected_from_date));
|
||||||
|
|
||||||
|
if (!empty($collected_through_date))
|
||||||
|
$conditions[]
|
||||||
|
= array('ReceiptTransaction.stamp <=' =>
|
||||||
|
$this->LedgerEntry->Transaction->dateFormatBeforeSave($collected_through_date . ' 23:59:59'));
|
||||||
|
|
||||||
|
if (isset($collected_payment_accounts))
|
||||||
|
$conditions[] = array('MoneyAccount.id' => $collected_payment_accounts);
|
||||||
|
else
|
||||||
|
$conditions[] = array('NOT' => array(array('MoneyAccount.id' => null)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($params['action'] === 'ledger') {
|
||||||
|
$conditions[] = $model->ledgerContextConditions($ledger_id, $account_type);
|
||||||
|
}
|
||||||
|
if (isset($params['custom']['reconcile_id'])) {
|
||||||
|
$ftype = $params['custom']['account_ftype'];
|
||||||
|
//$ftype = $this->LedgerEntry->DebitLedger->Account->fundamentalOpposite($ftype);
|
||||||
|
$conditions[] = array('Reconciliation.'.$ftype.'_ledger_entry_id' => $params['custom']['reconcile_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($params['custom']['account_id'])) {
|
||||||
|
$conditions[] =
|
||||||
|
array('OR' =>
|
||||||
|
array(array('CreditAccount.id' => $params['custom']['account_id']),
|
||||||
|
array('DebitAccount.id' => $params['custom']['account_id'])));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($params['custom']['customer_id'])) {
|
||||||
|
$conditions[] =
|
||||||
|
array('Customer.id' => $params['custom']['customer_id']);
|
||||||
|
|
||||||
|
/* $Account = new Account(); */
|
||||||
|
/* if (isset($params['custom']['account_ftype']) || */
|
||||||
|
/* isset($params['custom']['ledger_id'])) { */
|
||||||
|
/* $conditions[] = */
|
||||||
|
/* array('OR' => array('Account.id' => $Account->invoiceAccountID(), */
|
||||||
|
/* 'Account.id' => $Account->receiptAccountID())); */
|
||||||
|
/* } else { */
|
||||||
|
/* $conditions[] = */
|
||||||
|
/* array('OR' => array('DebitAccount.id' => $Account->invoiceAccountID(), */
|
||||||
|
/* //'CreditAccount.id' => $Account->invoiceAccountID(), */
|
||||||
|
/* //'DebitAccount.id' => $Account->receiptAccountID(), */
|
||||||
|
/* 'CreditAccount.id' => $Account->receiptAccountID(), */
|
||||||
|
/* )); */
|
||||||
|
/* } */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($params['custom']['lease_id'])) {
|
||||||
|
$conditions[] =
|
||||||
|
array('Lease.id' => $params['custom']['lease_id']);
|
||||||
|
|
||||||
|
/* $Account = new Account(); */
|
||||||
|
/* if (isset($params['custom']['account_ftype']) || */
|
||||||
|
/* isset($params['custom']['ledger_id'])) { */
|
||||||
|
/* $conditions[] = */
|
||||||
|
/* array('OR' => array('Account.id' => $Account->invoiceAccountID(), */
|
||||||
|
/* 'Account.id' => $Account->receiptAccountID())); */
|
||||||
|
/* } else { */
|
||||||
|
/* $conditions[] = */
|
||||||
|
/* array('OR' => array('DebitAccount.id' => $Account->invoiceAccountID(), */
|
||||||
|
/* //'CreditAccount.id' => $Account->invoiceAccountID(), */
|
||||||
|
/* //'DebitAccount.id' => $Account->receiptAccountID(), */
|
||||||
|
/* 'CreditAccount.id' => $Account->receiptAccountID(), */
|
||||||
|
/* )); */
|
||||||
|
/* } */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($params['custom']['transaction_id'])) {
|
||||||
|
$conditions[] =
|
||||||
|
array('Transaction.id' => $params['custom']['transaction_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($params['custom']['monetary_source_id'])) {
|
||||||
|
$conditions[] =
|
||||||
|
array('MonetarySource.id' => $params['custom']['monetary_source_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $conditions;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
|
||||||
|
$links['Transaction'] = array('id');
|
||||||
|
$links['LedgerEntry'] = array('id');
|
||||||
|
$links['Account'] = array('controller' => 'accounts', 'name');
|
||||||
|
$links['DebitAccount'] = array('controller' => 'accounts', 'name');
|
||||||
|
$links['CreditAccount'] = array('controller' => 'accounts', 'name');
|
||||||
|
$links['MonetarySource'] = array('name');
|
||||||
|
$links['Customer'] = array('name');
|
||||||
|
$links['Lease'] = array('number');
|
||||||
|
$links['Unit'] = array('name');
|
||||||
|
return parent::jqGridRecordLinks($params, $model, $records, $links);
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataGroup(&$params, &$model) {
|
||||||
|
if (isset($params['custom']['group_by_tx']) && $params['custom']['group_by_tx'])
|
||||||
|
return $model->alias.'.transaction_id';
|
||||||
|
|
||||||
|
return parent::jqGridDataGroup($params, $model);
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataOrder(&$params, &$model, $index, $direction) {
|
||||||
|
/* if ($index === 'balance') */
|
||||||
|
/* return ($index .' '. $direction); */
|
||||||
|
$order = parent::jqGridDataOrder($params, $model, $index, $direction);
|
||||||
|
|
||||||
|
if ($index === 'Transaction.stamp') {
|
||||||
|
$order[] = 'LedgerEntry.id ' . $direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $order;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataRecords(&$params, &$model, $query) {
|
||||||
|
if ($params['action'] === 'collected') {
|
||||||
|
$tquery = array_diff_key($query, array('fields'=>1,'group'=>1,'limit'=>1,'order'=>1));
|
||||||
|
$tquery['fields'] = array('SUM(Reconciliation.amount) AS applied');
|
||||||
|
$total = $model->find('first', $tquery);
|
||||||
|
|
||||||
|
$params['userdata']['total'] = $total[0]['applied'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::jqGridDataRecords($params, $model, $query);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: reverse the ledger entry
|
||||||
|
*/
|
||||||
|
|
||||||
|
function reverse($id) {
|
||||||
|
$this->LedgerEntry->reverse($id);
|
||||||
|
$this->redirect(array('action'=>'view', $id));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: view
|
||||||
|
* - Displays information about a specific entry
|
||||||
|
*/
|
||||||
|
|
||||||
|
function view($id = null) {
|
||||||
|
if (!$id) {
|
||||||
|
$this->Session->setFlash(__('Invalid Item.', true));
|
||||||
|
$this->redirect(array('controller' => 'accounts', 'action'=>'index'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the LedgerEntry and related fields
|
||||||
|
$entry = $this->LedgerEntry->find
|
||||||
|
('first',
|
||||||
|
array('contain' => array('MonetarySource.id',
|
||||||
|
'MonetarySource.name',
|
||||||
|
'Transaction.id',
|
||||||
|
'Transaction.stamp',
|
||||||
|
'DebitLedger.id',
|
||||||
|
'DebitLedger.sequence',
|
||||||
|
'DebitLedger.account_id',
|
||||||
|
'CreditLedger.id',
|
||||||
|
'CreditLedger.sequence',
|
||||||
|
'CreditLedger.account_id',
|
||||||
|
'Customer.id',
|
||||||
|
'Customer.name',
|
||||||
|
'Lease.id',
|
||||||
|
),
|
||||||
|
|
||||||
|
'fields' => array('LedgerEntry.*'),
|
||||||
|
|
||||||
|
'conditions' => array('LedgerEntry.id' => $id),
|
||||||
|
));
|
||||||
|
//pr($entry);
|
||||||
|
|
||||||
|
// Because 'DebitLedger' and 'CreditLedger' both relate to 'Account',
|
||||||
|
// CakePHP will not include them in the LedgerEntry->find (or so it
|
||||||
|
// seems). We'll have to break out each Account separately.
|
||||||
|
|
||||||
|
// Get the Account from DebitLedger
|
||||||
|
$entry['DebitLedger'] += $this->LedgerEntry->DebitLedger->Account->find
|
||||||
|
('first',
|
||||||
|
array('contain' => true,
|
||||||
|
'fields' => array('Account.id', 'Account.name', 'Account.type', 'Account.trackable'),
|
||||||
|
'conditions' => array('Account.id' => $entry['DebitLedger']['account_id']),
|
||||||
|
));
|
||||||
|
$entry['DebitLedger']['Account']['ftype'] =
|
||||||
|
$this->LedgerEntry->DebitLedger->Account
|
||||||
|
->fundamentalType($entry['DebitLedger']['Account']['type']);
|
||||||
|
|
||||||
|
// Get the Account from CreditLedger
|
||||||
|
$entry['CreditLedger'] += $this->LedgerEntry->CreditLedger->Account->find
|
||||||
|
('first',
|
||||||
|
array('contain' => true,
|
||||||
|
'fields' => array('Account.id', 'Account.name', 'Account.type', 'Account.trackable'),
|
||||||
|
'conditions' => array('Account.id' => $entry['CreditLedger']['account_id']),
|
||||||
|
));
|
||||||
|
$entry['CreditLedger']['Account']['ftype'] =
|
||||||
|
$this->LedgerEntry->CreditLedger->Account
|
||||||
|
->fundamentalType($entry['CreditLedger']['Account']['type']);
|
||||||
|
|
||||||
|
// Get the reconciliation balances for this ledger entry
|
||||||
|
$stats = $this->LedgerEntry->stats($id);
|
||||||
|
$stats['debit']['amount_reconciled'] = $stats['debit_amount_reconciled'];
|
||||||
|
$stats['credit']['amount_reconciled'] = $stats['credit_amount_reconciled'];
|
||||||
|
if ($entry['DebitLedger']['Account']['trackable'])
|
||||||
|
$stats['debit']['amount_remaining'] = $entry['LedgerEntry']['amount'] - $stats['debit']['amount_reconciled'];
|
||||||
|
if ($entry['CreditLedger']['Account']['trackable'])
|
||||||
|
$stats['credit']['amount_remaining'] = $entry['LedgerEntry']['amount'] - $stats['credit']['amount_reconciled'];
|
||||||
|
//pr($stats);
|
||||||
|
|
||||||
|
$reconciled = $this->LedgerEntry->findReconciledLedgerEntries($id);
|
||||||
|
//pr($reconciled);
|
||||||
|
|
||||||
|
|
||||||
|
// REVISIT <AP>: 20090711
|
||||||
|
// It's not clear whether we should be able to reverse charges that have
|
||||||
|
// already been paid/cleared/reconciled. Certainly, that will be the
|
||||||
|
// case when someone has pre-paid and then moves out early. However, this
|
||||||
|
// will work well for items accidentally charged but not yet paid for.
|
||||||
|
if ((!$entry['DebitLedger']['Account']['trackable'] ||
|
||||||
|
$stats['debit']['amount_reconciled'] == 0) &&
|
||||||
|
(!$entry['CreditLedger']['Account']['trackable'] ||
|
||||||
|
$stats['credit']['amount_reconciled'] == 0)
|
||||||
|
|
||||||
|
&& 0
|
||||||
|
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Set up dynamic menu items
|
||||||
|
$this->sidemenu_links[] =
|
||||||
|
array('name' => 'Operations', 'header' => true);
|
||||||
|
|
||||||
|
$this->sidemenu_links[] =
|
||||||
|
array('name' => 'Undo',
|
||||||
|
'url' => array('action' => 'reverse',
|
||||||
|
$id));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->LedgerEntry->Ledger->Account->type
|
||||||
|
($entry['CreditLedger']['Account']['id']) == 'INCOME')
|
||||||
|
{
|
||||||
|
// Set up dynamic menu items
|
||||||
|
$this->sidemenu_links[] =
|
||||||
|
array('name' => 'Operations', 'header' => true);
|
||||||
|
|
||||||
|
$this->sidemenu_links[] =
|
||||||
|
array('name' => 'Reverse',
|
||||||
|
'url' => array('action' => 'reverse',
|
||||||
|
$id));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare to render.
|
||||||
|
$title = "Double Ledger Entry #{$entry['LedgerEntry']['id']}";
|
||||||
|
$this->set(compact('entry', 'title', 'reconciled', 'stats'));
|
||||||
|
}
|
||||||
|
}
|
||||||
150
site/controllers/ledgers_controller.php
Normal file
150
site/controllers/ledgers_controller.php
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class LedgersController extends AppController {
|
||||||
|
|
||||||
|
var $sidemenu_links =
|
||||||
|
array(array('name' => 'Ledgers', 'header' => true),
|
||||||
|
array('name' => 'Current', 'url' => array('controller' => 'ledgers', 'action' => 'current')),
|
||||||
|
array('name' => 'Closed', 'url' => array('controller' => 'ledgers', 'action' => 'closed')),
|
||||||
|
array('name' => 'All', 'url' => array('controller' => 'ledgers', 'action' => 'all')),
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* override: sideMenuLinks
|
||||||
|
* - Generates controller specific links for the side menu
|
||||||
|
*/
|
||||||
|
function sideMenuLinks() {
|
||||||
|
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: index / current / closed / all
|
||||||
|
* - Generate a list of ledgers
|
||||||
|
*/
|
||||||
|
|
||||||
|
function index() { $this->all(); }
|
||||||
|
function current() { $this->jqGridView('Current Ledgers'); }
|
||||||
|
function closed() { $this->jqGridView('Closed Ledgers'); }
|
||||||
|
function all() { $this->jqGridView('All Ledgers', 'all'); }
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* virtuals: jqGridData
|
||||||
|
* - With the application controller handling the jqGridData action,
|
||||||
|
* these virtual functions ensure that the correct data is passed
|
||||||
|
* to jqGrid.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function jqGridDataSetup(&$params) {
|
||||||
|
parent::jqGridDataSetup($params);
|
||||||
|
if (!isset($params['action']))
|
||||||
|
$params['action'] = 'all';
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataCountTables(&$params, &$model) {
|
||||||
|
return array('contain' => false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataTables(&$params, &$model) {
|
||||||
|
return array
|
||||||
|
('link' =>
|
||||||
|
array(// Models
|
||||||
|
'Account',
|
||||||
|
'LedgerEntry',
|
||||||
|
'Close',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataFields(&$params, &$model) {
|
||||||
|
return array
|
||||||
|
('Ledger.*',
|
||||||
|
'CONCAT(Account.id, "-", Ledger.sequence) AS id_sequence',
|
||||||
|
'SUM(IF(LedgerEntry.debit_ledger_id = Ledger.id,
|
||||||
|
LedgerEntry.amount, NULL)) AS debits',
|
||||||
|
'SUM(IF(LedgerEntry.credit_ledger_id = Ledger.id,
|
||||||
|
LedgerEntry.amount, NULL)) AS credits',
|
||||||
|
"SUM(IF(Account.type IN ('ASSET', 'EXPENSE'),
|
||||||
|
IF(LedgerEntry.debit_ledger_id = Ledger.id, 1, -1),
|
||||||
|
IF(LedgerEntry.credit_ledger_id = Ledger.id, 1, -1)
|
||||||
|
) * IF(LedgerEntry.amount, LedgerEntry.amount, 0)
|
||||||
|
) AS balance",
|
||||||
|
'COUNT(LedgerEntry.id) AS entries');
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataConditions(&$params, &$model) {
|
||||||
|
$conditions = parent::jqGridDataConditions($params, $model);
|
||||||
|
|
||||||
|
if ($params['action'] === 'current') {
|
||||||
|
$conditions[] = array('NOT' => array('Ledger.closed'));
|
||||||
|
}
|
||||||
|
elseif ($params['action'] === 'closed') {
|
||||||
|
$conditions[] = 'Ledger.closed';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $conditions;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataOrder(&$params, &$model, $index, $direction) {
|
||||||
|
$id_sequence = false;
|
||||||
|
if ($index === 'id_sequence') {
|
||||||
|
$id_sequence = true;
|
||||||
|
$index = 'Ledger.account_id';
|
||||||
|
}
|
||||||
|
|
||||||
|
$order = parent::jqGridDataOrder($params, $model, $index, $direction);
|
||||||
|
|
||||||
|
if ($id_sequence) {
|
||||||
|
$order[] = 'Ledger.sequence ' . $direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $order;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
|
||||||
|
$links['Ledger'] = array('id_sequence');
|
||||||
|
$links['Account'] = array('name');
|
||||||
|
return parent::jqGridRecordLinks($params, $model, $records, $links);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: view
|
||||||
|
* - Displays information about a specific ledger
|
||||||
|
*/
|
||||||
|
|
||||||
|
function view($id = null) {
|
||||||
|
if (!$id) {
|
||||||
|
$this->Session->setFlash(__('Invalid Item.', true));
|
||||||
|
$this->redirect(array('action'=>'index'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get details about the ledger itself (no entries yet)
|
||||||
|
$ledger = $this->Ledger->find
|
||||||
|
('first',
|
||||||
|
array('contain' =>
|
||||||
|
array(// Models
|
||||||
|
'Account',
|
||||||
|
),
|
||||||
|
'conditions' => array(array('Ledger.id' => $id)),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Get ledger stats for our summary box
|
||||||
|
$stats = $this->Ledger->stats($id);
|
||||||
|
|
||||||
|
// OK, set our view variables and render!
|
||||||
|
$title = 'Ledger: #' . $ledger['Account']['id'] .'-'. $ledger['Ledger']['sequence'];
|
||||||
|
$this->set(compact('ledger', 'title', 'stats'));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,22 +2,44 @@
|
|||||||
|
|
||||||
class MapsController extends AppController {
|
class MapsController extends AppController {
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
* action: index
|
* action: index / all
|
||||||
* - Generates a list of all site maps
|
* - Generate a listing of maps
|
||||||
*
|
*
|
||||||
* REVISIT <AP> 20090528:
|
* REVISIT <AP> 20090528:
|
||||||
* We'll need to present only those site area maps that correspond
|
* We'll need to present only those site area maps that correspond
|
||||||
* to the users particular site.
|
* to the users particular site.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function index() {
|
function index() { $this->all(); }
|
||||||
$this->Map->recursive = 0;
|
function all() { $this->jqGridView('All Maps', 'all'); }
|
||||||
$this->set('maps', $this->paginate());
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* virtuals: jqGridData
|
||||||
|
* - With the application controller handling the jqGridData action,
|
||||||
|
* these virtual functions ensure that the correct data is passed
|
||||||
|
* to jqGrid.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function jqGridDataTables(&$params, &$model) {
|
||||||
|
return array
|
||||||
|
('link' => array('SiteArea' => array('fields' => array('SiteArea.id', 'SiteArea.name')),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
|
||||||
|
$links['Map'] = array('id');
|
||||||
|
return parent::jqGridRecordLinks($params, $model, $records, $links);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
@@ -31,6 +53,7 @@ class MapsController extends AppController {
|
|||||||
$this->redirect(array('action'=>'index'));
|
$this->redirect(array('action'=>'index'));
|
||||||
}
|
}
|
||||||
$this->set('info', $this->mapInfo($id, $requested_width));
|
$this->set('info', $this->mapInfo($id, $requested_width));
|
||||||
|
$this->set('title', "Site Map");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -128,22 +151,6 @@ class MapsController extends AppController {
|
|||||||
return $info;
|
return $info;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Temporary function
|
|
||||||
function unitStatusList() {
|
|
||||||
return
|
|
||||||
array('DELETED' => array(),
|
|
||||||
'DAMAGED' => array(),
|
|
||||||
'COMPANY' => array(),
|
|
||||||
'UNAVAILABLE' => array(),
|
|
||||||
'RESERVED' => array(),
|
|
||||||
'DIRTY' => array(),
|
|
||||||
'VACANT' => array(),
|
|
||||||
'OCCUPIED' => array(),
|
|
||||||
'LATE' => array(),
|
|
||||||
'LOCKED' => array(),
|
|
||||||
'LIENED' => array(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
@@ -153,9 +160,10 @@ class MapsController extends AppController {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
function legend($id = null, $requested_width = 400) {
|
function legend($id = null, $requested_width = 400) {
|
||||||
$status = $this->unitStatusList();
|
$status = $this->Map->Unit->activeStatusEnums();
|
||||||
$cols = 6;
|
//pr($status);
|
||||||
$rows = (int)((count($status) + $cols - 1) / $cols);
|
$rows = 2;
|
||||||
|
$cols = (int)((count($status) + $rows - 1) / $rows);
|
||||||
|
|
||||||
$info = array('units' => array());
|
$info = array('units' => array());
|
||||||
|
|
||||||
@@ -183,7 +191,7 @@ class MapsController extends AppController {
|
|||||||
$item_width *= $screen_adjustment_factor;
|
$item_width *= $screen_adjustment_factor;
|
||||||
$item_depth *= $screen_adjustment_factor;
|
$item_depth *= $screen_adjustment_factor;
|
||||||
|
|
||||||
foreach ($status AS $code => $color) {
|
foreach ($status AS $code => $value) {
|
||||||
$info['units'][] = array('name' => $code,
|
$info['units'][] = array('name' => $code,
|
||||||
'status' => $code,
|
'status' => $code,
|
||||||
'width' => $item_width,
|
'width' => $item_width,
|
||||||
@@ -211,9 +219,13 @@ class MapsController extends AppController {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
function image($info, $legend = false) {
|
function image($info, $legend = false) {
|
||||||
$this->layout = null;
|
$debug = false;
|
||||||
$this->autoLayout = false;
|
|
||||||
Configure::write('debug', '0');
|
if (!$debug) {
|
||||||
|
$this->layout = null;
|
||||||
|
$this->autoLayout = false;
|
||||||
|
Configure::write('debug', '0');
|
||||||
|
}
|
||||||
|
|
||||||
// Define our color palate
|
// Define our color palate
|
||||||
// REVISIT <AP>: 20090513
|
// REVISIT <AP>: 20090513
|
||||||
@@ -254,9 +266,7 @@ class MapsController extends AppController {
|
|||||||
$code['fg'] = $component;
|
$code['fg'] = $component;
|
||||||
}
|
}
|
||||||
|
|
||||||
//pr($info);
|
$this->set(compact('info', 'debug'));
|
||||||
|
|
||||||
$this->set(compact('info'));
|
|
||||||
$this->render('image');
|
$this->render('image');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
110
site/controllers/monetary_sources_controller.php
Normal file
110
site/controllers/monetary_sources_controller.php
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class MonetarySourcesController extends AppController {
|
||||||
|
|
||||||
|
var $sidemenu_links = array();
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* override: sideMenuLinks
|
||||||
|
* - Generates controller specific links for the side menu
|
||||||
|
*/
|
||||||
|
function sideMenuLinks() {
|
||||||
|
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: index / all
|
||||||
|
* - Generate a listing of MonetarySources
|
||||||
|
*/
|
||||||
|
|
||||||
|
function index() { $this->all(); }
|
||||||
|
function all() { $this->jqGridView('All MonetarySources', 'all'); }
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* virtuals: jqGridData
|
||||||
|
* - With the application controller handling the jqGridData action,
|
||||||
|
* these virtual functions ensure that the correct data is passed
|
||||||
|
* to jqGrid.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function jqGridDataTables(&$params, &$model) {
|
||||||
|
return array
|
||||||
|
('contain' => false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
|
||||||
|
$links['MonetarySource'] = array('id');
|
||||||
|
return parent::jqGridRecordLinks($params, $model, $records, $links);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: nsf
|
||||||
|
* - Marks a monetary source as having insufficient funds.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function nsf($id = null) {
|
||||||
|
if (!$id) {
|
||||||
|
$this->Session->setFlash(__('Invalid Item.', true));
|
||||||
|
$this->redirect(array('action'=>'index'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// REVISIT <AP>: 20090713
|
||||||
|
// For testing purposes, must be deleted
|
||||||
|
$stamp = '2009-07-09';
|
||||||
|
|
||||||
|
$this->MonetarySource->nsf($id, $stamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: view
|
||||||
|
* - Displays information about a specific entry
|
||||||
|
*/
|
||||||
|
|
||||||
|
function view($id = null) {
|
||||||
|
if (!$id) {
|
||||||
|
$this->Session->setFlash(__('Invalid Item.', true));
|
||||||
|
$this->redirect(array('controller' => 'accounts', 'action'=>'index'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the MonetarySource and related fields
|
||||||
|
$monetary_source = $this->MonetarySource->find
|
||||||
|
('first', array
|
||||||
|
('contain' => false,
|
||||||
|
));
|
||||||
|
|
||||||
|
// REVISIT <AP>: 20090713
|
||||||
|
// Consider allowing the NSF operation only if the source is used on
|
||||||
|
// a ledger entry that is debited on a "payable" account (perhaps
|
||||||
|
// even restricted to "payable" ASSET accounts), credited on Receipt
|
||||||
|
// (or A/R), and reconciles the credit to an entry that debits on a
|
||||||
|
// "depositable" account.
|
||||||
|
|
||||||
|
// Set up dynamic menu items
|
||||||
|
$this->sidemenu_links[] =
|
||||||
|
array('name' => 'Operations', 'header' => true);
|
||||||
|
|
||||||
|
$this->sidemenu_links[] =
|
||||||
|
array('name' => 'NSF',
|
||||||
|
'url' => array('action' => 'nsf',
|
||||||
|
$id));
|
||||||
|
|
||||||
|
// Prepare to render.
|
||||||
|
$title = "Monetary Source #{$monetary_source['MonetarySource']['id']}";
|
||||||
|
$this->set(compact('monetary_source', 'title'));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
<?php
|
|
||||||
/* SVN FILE: $Id: pages_controller.php 7945 2008-12-19 02:16:01Z gwoo $ */
|
|
||||||
/**
|
|
||||||
* Static content controller.
|
|
||||||
*
|
|
||||||
* This file will render views from views/pages/
|
|
||||||
*
|
|
||||||
* PHP versions 4 and 5
|
|
||||||
*
|
|
||||||
* CakePHP(tm) : Rapid Development Framework (http://www.cakephp.org)
|
|
||||||
* Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
|
|
||||||
*
|
|
||||||
* Licensed under The MIT License
|
|
||||||
* Redistributions of files must retain the above copyright notice.
|
|
||||||
*
|
|
||||||
* @filesource
|
|
||||||
* @copyright Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
|
|
||||||
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
|
|
||||||
* @package cake
|
|
||||||
* @subpackage cake.cake.libs.controller
|
|
||||||
* @since CakePHP(tm) v 0.2.9
|
|
||||||
* @version $Revision: 7945 $
|
|
||||||
* @modifiedby $LastChangedBy: gwoo $
|
|
||||||
* @lastmodified $Date: 2008-12-18 18:16:01 -0800 (Thu, 18 Dec 2008) $
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* Static content controller
|
|
||||||
*
|
|
||||||
* Override this controller by placing a copy in controllers directory of an application
|
|
||||||
*
|
|
||||||
* @package cake
|
|
||||||
* @subpackage cake.cake.libs.controller
|
|
||||||
*/
|
|
||||||
class PagesController extends AppController {
|
|
||||||
/**
|
|
||||||
* Controller name
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
var $name = 'Pages';
|
|
||||||
/**
|
|
||||||
* Default helper
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
var $helpers = array('Html');
|
|
||||||
/**
|
|
||||||
* This controller does not use a model
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
var $uses = array();
|
|
||||||
/**
|
|
||||||
* Displays a view
|
|
||||||
*
|
|
||||||
* @param mixed What page to display
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function display() {
|
|
||||||
$path = func_get_args();
|
|
||||||
|
|
||||||
$count = count($path);
|
|
||||||
if (!$count) {
|
|
||||||
$this->redirect('/');
|
|
||||||
}
|
|
||||||
$page = $subpage = $title = null;
|
|
||||||
|
|
||||||
if (!empty($path[0])) {
|
|
||||||
$page = $path[0];
|
|
||||||
}
|
|
||||||
if (!empty($path[1])) {
|
|
||||||
$subpage = $path[1];
|
|
||||||
}
|
|
||||||
if (!empty($path[$count - 1])) {
|
|
||||||
$title = Inflector::humanize($path[$count - 1]);
|
|
||||||
}
|
|
||||||
$this->set(compact('page', 'subpage', 'title'));
|
|
||||||
$this->render(join('/', $path));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class PaymentsController extends AppController {
|
|
||||||
var $paginate = array('limit' => 100,
|
|
||||||
'group' => 'Payment.id',
|
|
||||||
'order' => array('Payment.id' => 'ASC'));
|
|
||||||
|
|
||||||
var $sidemenu_links =
|
|
||||||
array(array('name' => 'Payments', 'header' => true),
|
|
||||||
array('name' => 'Cleared', 'url' => array('controller' => 'payments', 'action' => 'cleared')),
|
|
||||||
array('name' => 'Unresolved', 'url' => array('controller' => 'payments', 'action' => 'unresolved')),
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* override: sideMenuLinks
|
|
||||||
* - Generates controller specific links for the side menu
|
|
||||||
*/
|
|
||||||
function sideMenuLinks() {
|
|
||||||
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: index
|
|
||||||
* - Lists all payments
|
|
||||||
*/
|
|
||||||
|
|
||||||
function index() {
|
|
||||||
$this->all();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: cleared
|
|
||||||
* - Lists cleared payments
|
|
||||||
*/
|
|
||||||
|
|
||||||
function cleared() {
|
|
||||||
$this->all();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: unresolved
|
|
||||||
* - Lists unresolved payments
|
|
||||||
*/
|
|
||||||
|
|
||||||
function unresolved() {
|
|
||||||
$this->all();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: all
|
|
||||||
* - Lists all payments
|
|
||||||
*/
|
|
||||||
|
|
||||||
function all() {
|
|
||||||
$this->paginate = array_merge
|
|
||||||
($this->paginate,
|
|
||||||
array('link' =>
|
|
||||||
array(// Models
|
|
||||||
'PaymentType',
|
|
||||||
'Receipt',
|
|
||||||
),
|
|
||||||
));
|
|
||||||
|
|
||||||
$title = 'All Payments';
|
|
||||||
$this->set('title', $title); $this->set('heading', $title);
|
|
||||||
$this->set('payments', $this->paginate());
|
|
||||||
$this->render('index');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: view
|
|
||||||
* - Displays information about a specific payment
|
|
||||||
*/
|
|
||||||
|
|
||||||
function view($id = null) {
|
|
||||||
if (!$id) {
|
|
||||||
$this->Session->setFlash(__('Invalid Item.', true));
|
|
||||||
$this->redirect(array('action'=>'index'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->Payment->Behaviors->attach('Containable');
|
|
||||||
$this->Payment->contain
|
|
||||||
(array(// Models
|
|
||||||
'PaymentType',
|
|
||||||
'Receipt',
|
|
||||||
)
|
|
||||||
);
|
|
||||||
$payment = $this->Payment->read(null, $id);
|
|
||||||
//pr($payment);
|
|
||||||
|
|
||||||
/* $this->sidemenu_links[] = */
|
|
||||||
/* array('name' => 'Operations', 'header' => true); */
|
|
||||||
/* $this->sidemenu_links[] = */
|
|
||||||
/* array('name' => 'Move-Out', 'url' => array('controller' => 'payments', 'action' => 'move-out')); */
|
|
||||||
|
|
||||||
$title = 'Payment #' . $payment['Payment']['id'];
|
|
||||||
$this->set(compact('payment', 'title'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,131 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class ReceiptsController extends AppController {
|
|
||||||
var $paginate = array('limit' => 100,
|
|
||||||
'group' => 'Receipt.id',
|
|
||||||
'order' => array('Receipt.stamp' => 'ASC'));
|
|
||||||
|
|
||||||
var $sidemenu_links =
|
|
||||||
array(array('name' => 'Receipts', 'header' => true),
|
|
||||||
array('name' => 'Cleared', 'url' => array('controller' => 'receipts', 'action' => 'cleared')),
|
|
||||||
array('name' => 'Unresolved', 'url' => array('controller' => 'receipts', 'action' => 'unresolved')),
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* override: sideMenuLinks
|
|
||||||
* - Generates controller specific links for the side menu
|
|
||||||
*/
|
|
||||||
function sideMenuLinks() {
|
|
||||||
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: index
|
|
||||||
* - Lists all receipts
|
|
||||||
*/
|
|
||||||
|
|
||||||
function index() {
|
|
||||||
$this->all();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: cleared
|
|
||||||
* - Lists cleared receipts
|
|
||||||
*/
|
|
||||||
|
|
||||||
function cleared() {
|
|
||||||
$this->all();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: unresolved
|
|
||||||
* - Lists unresolved receipts
|
|
||||||
*/
|
|
||||||
|
|
||||||
function unresolved() {
|
|
||||||
$this->all();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: all
|
|
||||||
* - Lists all receipts
|
|
||||||
*/
|
|
||||||
|
|
||||||
function all() {
|
|
||||||
$this->paginate = array_merge
|
|
||||||
($this->paginate,
|
|
||||||
array('link' =>
|
|
||||||
array(// Models
|
|
||||||
'Charge',
|
|
||||||
'Payment'
|
|
||||||
),
|
|
||||||
));
|
|
||||||
|
|
||||||
$title = 'All Receipts';
|
|
||||||
$this->set('title', $title); $this->set('heading', $title);
|
|
||||||
$this->set('receipts', $this->paginate());
|
|
||||||
$this->render('index');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: view
|
|
||||||
* - Displays information about a specific receipt
|
|
||||||
*/
|
|
||||||
|
|
||||||
function view($id = null) {
|
|
||||||
if (!$id) {
|
|
||||||
$this->Session->setFlash(__('Invalid Item.', true));
|
|
||||||
$this->redirect(array('action'=>'index'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->Receipt->Behaviors->attach('Containable');
|
|
||||||
$this->Receipt->contain
|
|
||||||
(array(// Models
|
|
||||||
'Charge' => array(// Models
|
|
||||||
'Lease' => array('fields' => array('number')),
|
|
||||||
'ChargesReceipt',
|
|
||||||
'ChargeType'),
|
|
||||||
'Payment' => array(// Models
|
|
||||||
'PaymentType'),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
$receipt = $this->Receipt->read(null, $id);
|
|
||||||
//pr($receipt);
|
|
||||||
|
|
||||||
$charge_amount = 0;
|
|
||||||
$payment_amount = 0;
|
|
||||||
foreach($receipt['Charge'] AS $charge)
|
|
||||||
$charge_amount += $charge['ChargesReceipt']['amount'];
|
|
||||||
foreach($receipt['Payment'] AS $payment)
|
|
||||||
$payment_amount += $payment['amount'];
|
|
||||||
|
|
||||||
/* $this->sidemenu_links[] = */
|
|
||||||
/* array('name' => 'Operations', 'header' => true); */
|
|
||||||
/* $this->sidemenu_links[] = */
|
|
||||||
/* array('name' => 'Move-Out', 'url' => array('controller' => 'receipts', 'action' => 'move-out')); */
|
|
||||||
|
|
||||||
$title = 'Receipt #' . $receipt['Receipt']['id'];
|
|
||||||
$this->set(compact('receipt', 'title',
|
|
||||||
'charge_amount',
|
|
||||||
'payment_amount'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
166
site/controllers/transactions_controller.php
Normal file
166
site/controllers/transactions_controller.php
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class TransactionsController extends AppController {
|
||||||
|
|
||||||
|
var $components = array('RequestHandler');
|
||||||
|
|
||||||
|
var $sidemenu_links =
|
||||||
|
array(array('name' => 'Transactions', 'header' => true),
|
||||||
|
array('name' => 'All', 'url' => array('controller' => 'transactions', 'action' => 'all')),
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* override: sideMenuLinks
|
||||||
|
* - Generates controller specific links for the side menu
|
||||||
|
*/
|
||||||
|
function sideMenuLinks() {
|
||||||
|
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: index / all
|
||||||
|
* - Generate a listing of transactions
|
||||||
|
*/
|
||||||
|
|
||||||
|
function index() { $this->all(); }
|
||||||
|
function all() { $this->jqGridView('All Transactions', 'all'); }
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* virtuals: jqGridData
|
||||||
|
* - With the application controller handling the jqGridData action,
|
||||||
|
* these virtual functions ensure that the correct data is passed
|
||||||
|
* to jqGrid.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
|
||||||
|
$links['Transaction'] = array('id');
|
||||||
|
return parent::jqGridRecordLinks($params, $model, $records, $links);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: view
|
||||||
|
* - Displays information about a specific transaction
|
||||||
|
*/
|
||||||
|
|
||||||
|
function view($id = null) {
|
||||||
|
if (!$id) {
|
||||||
|
$this->Session->setFlash(__('Invalid Item.', true));
|
||||||
|
$this->redirect(array('action'=>'index'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$transaction = $this->Transaction->find
|
||||||
|
('first',
|
||||||
|
array('contain' =>
|
||||||
|
array(// Models
|
||||||
|
'LedgerEntry' => array('fields' => array('LedgerEntry.id',
|
||||||
|
'LedgerEntry.amount',
|
||||||
|
'LedgerEntry.comment'),
|
||||||
|
//Models
|
||||||
|
|
||||||
|
'DebitLedger' => array
|
||||||
|
('fields' => array('DebitLedger.id', 'DebitLedger.sequence'),
|
||||||
|
'Account' => array
|
||||||
|
('fields' => array('Account.id', 'Account.name')),
|
||||||
|
),
|
||||||
|
|
||||||
|
'CreditLedger' => array
|
||||||
|
('fields' => array('CreditLedger.id', 'CreditLedger.sequence'),
|
||||||
|
'Account' => array
|
||||||
|
('fields' => array('Account.id', 'Account.name')),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'conditions' => array('Transaction.id' => $id),
|
||||||
|
));
|
||||||
|
|
||||||
|
// Figure out the transaction total
|
||||||
|
$total = 0;
|
||||||
|
foreach($transaction['LedgerEntry'] AS $entry)
|
||||||
|
$total += $entry['amount'];
|
||||||
|
|
||||||
|
// OK, prepare to render.
|
||||||
|
$title = 'Transaction #' . $transaction['Transaction']['id'];
|
||||||
|
$this->set(compact('transaction', 'title', 'total'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: postInvoice
|
||||||
|
* - handles the creation of a charge invoice
|
||||||
|
*/
|
||||||
|
|
||||||
|
function postInvoice() {
|
||||||
|
if (!$this->RequestHandler->isPost()) {
|
||||||
|
echo('<H2>THIS IS NOT A POST FOR SOME REASON</H2>');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->Transaction->addInvoice($this->data, null,
|
||||||
|
$this->data['Lease']['id'])) {
|
||||||
|
$this->Session->setFlash("INVOICE FAILED", true);
|
||||||
|
// REVISIT <AP> 20090706:
|
||||||
|
// Until we can work out the session problems,
|
||||||
|
// just die.
|
||||||
|
die("<H1>INVOICE FAILED</H1>");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->layout = null;
|
||||||
|
$this->autoLayout = false;
|
||||||
|
$this->autoRender = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: postReceipt
|
||||||
|
* - handles the creation of a payment receipt
|
||||||
|
*/
|
||||||
|
|
||||||
|
function postReceipt() {
|
||||||
|
if (!$this->RequestHandler->isPost()) {
|
||||||
|
echo('<H2>THIS IS NOT A POST FOR SOME REASON</H2>');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($this->data['LedgerEntry'] AS &$entry) {
|
||||||
|
if (!isset($entry['acct'][$entry['account_id']]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
$entry['MonetarySource'] = $entry['acct'][$entry['account_id']];
|
||||||
|
}
|
||||||
|
|
||||||
|
pr($this->data);
|
||||||
|
if (!$this->Transaction->addReceipt($this->data,
|
||||||
|
$this->data['Customer']['id'],
|
||||||
|
(isset($this->data['Lease']['id'])
|
||||||
|
? $this->data['Lease']['id']
|
||||||
|
: null ))) {
|
||||||
|
$this->Session->setFlash("RECEIPT FAILED", true);
|
||||||
|
// REVISIT <AP> 20090706:
|
||||||
|
// Until we can work out the session problems,
|
||||||
|
// just die.
|
||||||
|
die("<H1>RECEIPT FAILED</H1>");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->layout = null;
|
||||||
|
$this->autoLayout = false;
|
||||||
|
$this->autoRender = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,9 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
class UnitsController extends AppController {
|
class UnitsController extends AppController {
|
||||||
var $paginate = array('limit' => 100,
|
|
||||||
'group' => 'Unit.id',
|
|
||||||
'order' => array('Unit.sort_order' => 'ASC'));
|
|
||||||
|
|
||||||
var $sidemenu_links =
|
var $sidemenu_links =
|
||||||
array(array('name' => 'Units', 'header' => true),
|
array(array('name' => 'Units', 'header' => true),
|
||||||
@@ -28,114 +25,181 @@ class UnitsController extends AppController {
|
|||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
* action: index
|
* action: index / unavailable / vacant / occupied / all
|
||||||
* - Lists all units
|
* - Generate a listing of units
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function index() {
|
function index() { $this->all(); }
|
||||||
$this->all();
|
function unavailable() { $this->jqGridView('Unavailable Units'); }
|
||||||
|
function vacant() { $this->jqGridView('Vacant Units'); }
|
||||||
|
function occupied() { $this->jqGridView('Occupied Units'); }
|
||||||
|
function all() { $this->jqGridView('All Units', 'all'); }
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* virtuals: jqGridData
|
||||||
|
* - With the application controller handling the jqGridData action,
|
||||||
|
* these virtual functions ensure that the correct data is passed
|
||||||
|
* to jqGrid.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function jqGridDataSetup(&$params) {
|
||||||
|
parent::jqGridDataSetup($params);
|
||||||
|
if (!isset($params['action']))
|
||||||
|
$params['action'] = 'all';
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataCountTables(&$params, &$model) {
|
||||||
|
$link = array
|
||||||
|
('link' =>
|
||||||
|
array(// Models
|
||||||
|
'UnitSize' => array('fields' => array('id', 'name')),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($params['action'] === 'occupied')
|
||||||
|
$link['Lease'] = array('fields' => array(),
|
||||||
|
// Models
|
||||||
|
'Contact' => array('fields' => array('display_name'),
|
||||||
|
//'type' => 'LEFT',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $link;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataTables(&$params, &$model) {
|
||||||
|
$link = $this->jqGridDataCountTables($params, $model);
|
||||||
|
$link['link']['CurrentLease']['LedgerEntry'] = array('fields' => array());
|
||||||
|
$link['link']['CurrentLease']['LedgerEntry']['Ledger'] = array('fields' => array());
|
||||||
|
$link['link']['CurrentLease']['LedgerEntry']['Ledger']['Account'] = array('fields' => array());
|
||||||
|
// INNER JOIN would be great, as it would ensure we're only looking
|
||||||
|
// at the ledger entries that we truly want. However, this also
|
||||||
|
// removes from the query any leases that do not yet have a ledger
|
||||||
|
// entry in A/R. A solution would be to INNER JOIN these tables,
|
||||||
|
// and LEFT JOIN it to the rest. Grouping of JOINs, however, is
|
||||||
|
// implemented with the 'joins' tag, and is not available through
|
||||||
|
// the Linkable behavior interface.
|
||||||
|
//$link['link']['CurrentLease']['LedgerEntry']['Ledger']['Account']['type'] = 'INNER';
|
||||||
|
$link['link']['CurrentLease']['LedgerEntry']['Ledger']['Account']['conditions']
|
||||||
|
= array('Account.id' =>
|
||||||
|
$this->Unit->CurrentLease->LedgerEntry->Ledger->Account->accountReceivableAccountID());
|
||||||
|
return $link;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataFields(&$params, &$model) {
|
||||||
|
$db = &$model->getDataSource();
|
||||||
|
$fields = $db->fields($model, $model->alias);
|
||||||
|
$fields[] = ("SUM(IF(Account.id IS NULL, 0," .
|
||||||
|
" IF(LedgerEntry.debit_ledger_id = Account.id," .
|
||||||
|
" 1, -1))" .
|
||||||
|
" * LedgerEntry.amount) AS 'balance'");
|
||||||
|
return $fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataConditions(&$params, &$model) {
|
||||||
|
$conditions = parent::jqGridDataConditions($params, $model);
|
||||||
|
|
||||||
|
if ($params['action'] === 'unavailable') {
|
||||||
|
$conditions[] = $this->Unit->conditionUnavailable();
|
||||||
|
}
|
||||||
|
elseif ($params['action'] === 'vacant') {
|
||||||
|
$conditions[] = $this->Unit->conditionVacant();
|
||||||
|
}
|
||||||
|
elseif ($params['action'] === 'occupied') {
|
||||||
|
$conditions[] = $this->Unit->conditionOccupied();
|
||||||
|
}
|
||||||
|
elseif ($params['action'] === 'unoccupied') {
|
||||||
|
$conditions[] = array('NOT' => array($this->Unit->conditionOccupied()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $conditions;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataOrder(&$params, &$model, $index, $direction) {
|
||||||
|
// Instead of sorting by name, sort by defined order
|
||||||
|
if ($index === 'Unit.name')
|
||||||
|
$index = 'Unit.sort_order';
|
||||||
|
|
||||||
|
$order = array();
|
||||||
|
$order[] = parent::jqGridDataOrder($params, $model, $index, $direction);
|
||||||
|
|
||||||
|
// If sorting by anything other than name (defined order)
|
||||||
|
// add the sort-order as a secondary condition
|
||||||
|
if ($index !== 'Unit.name')
|
||||||
|
$order[] = parent::jqGridDataOrder($params, $model,
|
||||||
|
'Unit.sort_order', $direction);
|
||||||
|
|
||||||
|
return $order;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
|
||||||
|
$links['Unit'] = array('name');
|
||||||
|
$links['UnitSize'] = array('name');
|
||||||
|
return parent::jqGridRecordLinks($params, $model, $records, $links);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
* action: unavailable
|
* action: move_in
|
||||||
* - Lists unavailable units
|
* - Sets up the move-in page for the given unit.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function unavailable() {
|
function move_in($id = null) {
|
||||||
$this->paginate = array_merge
|
$customer = array();
|
||||||
($this->paginate,
|
$unit = array();
|
||||||
array('link' =>
|
|
||||||
array(// Models
|
|
||||||
'UnitSize' => array('fields' => array('name')),
|
|
||||||
),
|
|
||||||
'conditions' => $this->Unit->conditionUnavailable()
|
|
||||||
));
|
|
||||||
|
|
||||||
$title = 'Unavailable Units';
|
if (isset($id)) {
|
||||||
$this->set('title', $title); $this->set('heading', $title);
|
$this->Unit->recursive = -1;
|
||||||
$this->set('units', $this->paginate());
|
$unit = current($this->Unit->read(null, $id));
|
||||||
$this->render('index');
|
}
|
||||||
|
|
||||||
|
$title = 'Unit Move-In';
|
||||||
|
$this->set(compact('customer', 'unit', 'title'));
|
||||||
|
$this->render('/leases/move');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
* action: vacant
|
* action: move_out
|
||||||
* - Lists vacant units
|
* - prepare or execute a move out on a specific lease
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function vacant() {
|
function move_out($id) {
|
||||||
$this->paginate = array_merge
|
|
||||||
($this->paginate,
|
|
||||||
array('link' =>
|
|
||||||
array(// Models
|
|
||||||
'UnitSize' => array('fields' => array('name')),
|
|
||||||
),
|
|
||||||
'conditions' => $this->Unit->conditionVacant()
|
|
||||||
));
|
|
||||||
|
|
||||||
$title = 'Vacant Units';
|
$unit = $this->Unit->find
|
||||||
$this->set('title', $title); $this->set('heading', $title);
|
('first', array
|
||||||
$this->set('units', $this->paginate());
|
('contain' => array
|
||||||
$this->render('index');
|
(// Models
|
||||||
}
|
'CurrentLease' =>
|
||||||
|
array(//'conditions' => array('Lease.moveout_date' => null),
|
||||||
|
// Models
|
||||||
|
'Customer' =>
|
||||||
|
array('fields' => array('id', 'name'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'conditions' => array('Unit.id' => $id),
|
||||||
|
));
|
||||||
|
$this->set('customer', $unit['CurrentLease']['Customer']);
|
||||||
|
$this->set('unit', $unit['Unit']);
|
||||||
|
$this->set('lease', $unit['CurrentLease']);
|
||||||
|
|
||||||
|
$redirect = array('controller' => 'units',
|
||||||
|
'action' => 'view',
|
||||||
|
$id);
|
||||||
|
|
||||||
/**************************************************************************
|
$title = ('Lease #' . $unit['CurrentLease']['number'] . ': ' .
|
||||||
**************************************************************************
|
$unit['Unit']['name'] . ': ' .
|
||||||
**************************************************************************
|
$unit['CurrentLease']['Customer']['name'] . ': Prepare Move-Out');
|
||||||
* action: occupied
|
$this->set(compact('title', 'redirect'));
|
||||||
* - Lists occupied units
|
$this->render('/leases/move');
|
||||||
*/
|
|
||||||
|
|
||||||
function occupied() {
|
|
||||||
$this->paginate = array_merge
|
|
||||||
($this->paginate,
|
|
||||||
array('link' =>
|
|
||||||
array(// Models
|
|
||||||
'UnitSize' => array('fields' => array('name')),
|
|
||||||
'Lease' => array('fields' => array(),
|
|
||||||
|
|
||||||
// Models
|
|
||||||
'Contact' => array('fields' => array('display_name'),
|
|
||||||
//'type' => 'LEFT',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
'conditions' => $this->Unit->conditionOccupied()
|
|
||||||
));
|
|
||||||
|
|
||||||
$title = 'Occupied Units';
|
|
||||||
$this->set('title', $title); $this->set('heading', $title);
|
|
||||||
$this->set('units', $this->paginate());
|
|
||||||
$this->render('index');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: all
|
|
||||||
* - Lists all units
|
|
||||||
*/
|
|
||||||
|
|
||||||
function all() {
|
|
||||||
$this->paginate = array_merge
|
|
||||||
($this->paginate,
|
|
||||||
array('link' =>
|
|
||||||
array(// Models
|
|
||||||
'UnitSize' => array('fields' => array('name')),
|
|
||||||
),
|
|
||||||
));
|
|
||||||
|
|
||||||
$title = 'All Units';
|
|
||||||
$this->set('title', $title); $this->set('heading', $title);
|
|
||||||
$this->set('units', $this->paginate());
|
|
||||||
$this->render('index');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -152,58 +216,60 @@ class UnitsController extends AppController {
|
|||||||
$this->redirect(array('action'=>''));
|
$this->redirect(array('action'=>''));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->Unit->Behaviors->attach('Containable');
|
$unit = $this->Unit->find
|
||||||
$this->Unit->contain
|
('first',
|
||||||
(array(// Models
|
array('contain' =>
|
||||||
'UnitSize',
|
array(// Models
|
||||||
'Lease' =>
|
'UnitSize',
|
||||||
array('order' => 'movein_date',
|
'Lease' => array('Customer'),
|
||||||
'conditions' => array('Lease.lease_date IS NOT NULL',
|
'CurrentLease' => array('Customer')
|
||||||
),
|
),
|
||||||
// Models
|
'conditions' => array('Unit.id' => $id),
|
||||||
'Contact' =>
|
));
|
||||||
array(//'order' => array('sort_order'),
|
|
||||||
'fields' => array('id', 'display_name'),
|
|
||||||
),
|
|
||||||
'Charge' =>
|
|
||||||
array('order' => array('charge_date'),
|
|
||||||
// Models
|
|
||||||
'ChargeType',
|
|
||||||
'Receipt' => array(// Models
|
|
||||||
'Payment'
|
|
||||||
),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
$unit = $this->Unit->read(null, $id);
|
|
||||||
//pr($unit);
|
|
||||||
|
|
||||||
$outstanding_deposit = 0;
|
// Get the balance on each lease.
|
||||||
$outstanding_balance = 0;
|
foreach ($unit['Lease'] AS &$lease) {
|
||||||
foreach($unit['Lease'] AS $lease) {
|
$stats = $this->Unit->Lease->stats($lease['id']);
|
||||||
foreach($lease['Charge'] AS $charge) {
|
$lease['balance'] = $stats['balance'];
|
||||||
$outstanding_balance += $charge['total'];
|
|
||||||
foreach ($charge['Receipt'] AS $receipt) {
|
|
||||||
$outstanding_balance -= $receipt['ChargesReceipt']['amount'];
|
|
||||||
|
|
||||||
/* foreach($receipt['Payment'] AS $payment) */
|
|
||||||
/* $outstanding_balance -= $payment['amount']; */
|
|
||||||
|
|
||||||
// REVISIT <AP> 20090530:
|
|
||||||
// Using hardcoded value for security deposit...
|
|
||||||
// That can't be good!
|
|
||||||
if ($charge['charge_type_id'] == 1)
|
|
||||||
$outstanding_deposit += $receipt['ChargesReceipt']['amount'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->sidemenu_links[] =
|
$outstanding_balance = 0;
|
||||||
array('name' => 'Operations', 'header' => true);
|
$outstanding_deposit = 0;
|
||||||
$this->sidemenu_links[] =
|
if (isset($unit['CurrentLease']['id'])) {
|
||||||
array('name' => 'Move-Out', 'url' => array('controller' => 'units', 'action' => 'move-out'));
|
// Figure out the outstanding balance of the current lease.
|
||||||
|
$stats = $this->Unit->stats($id);
|
||||||
|
$outstanding_balance =
|
||||||
|
$stats['CurrentLease']['balance'];
|
||||||
|
|
||||||
|
// Figure out the total security deposit for the current lease.
|
||||||
|
$deposits = $this->Unit->Lease->findSecurityDeposits($unit['CurrentLease']['id']);
|
||||||
|
$outstanding_deposit = $deposits['summary']['balance'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up dynamic menu items
|
||||||
|
$this->sidemenu_links[] =
|
||||||
|
array('name' => 'Operations', 'header' => true);
|
||||||
|
|
||||||
|
if (isset($unit['CurrentLease']['id']) &&
|
||||||
|
!isset($unit['CurrentLease']['moveout_date'])) {
|
||||||
|
$this->sidemenu_links[] =
|
||||||
|
array('name' => 'Move-Out', 'url' => array('action' => 'move_out',
|
||||||
|
$id));
|
||||||
|
} else {
|
||||||
|
$this->sidemenu_links[] =
|
||||||
|
array('name' => 'Move-In', 'url' => array('action' => 'move_in',
|
||||||
|
$id));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($unit['CurrentLease']['id']) &&
|
||||||
|
!isset($unit['CurrentLease']['close_date'])) {
|
||||||
|
$this->sidemenu_links[] =
|
||||||
|
array('name' => 'Payment', 'url' => array('controller' => 'customers',
|
||||||
|
'action' => 'receipt',
|
||||||
|
$unit['CurrentLease']['customer_id']));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare to render.
|
||||||
$title = 'Unit ' . $unit['Unit']['name'];
|
$title = 'Unit ' . $unit['Unit']['name'];
|
||||||
$this->set(compact('unit', 'title',
|
$this->set(compact('unit', 'title',
|
||||||
'outstanding_balance',
|
'outstanding_balance',
|
||||||
|
|||||||
@@ -8,22 +8,843 @@ class Account extends AppModel {
|
|||||||
'external_name' => array('notempty')
|
'external_name' => array('notempty')
|
||||||
);
|
);
|
||||||
|
|
||||||
//The Associations below have been created with all possible keys, those that are not needed can be removed
|
var $hasOne = array(
|
||||||
var $hasMany = array(
|
'CurrentLedger' => array(
|
||||||
'ChargeType' => array(
|
'className' => 'Ledger',
|
||||||
'className' => 'ChargeType',
|
// REVISIT <AP> 20090702:
|
||||||
'foreignKey' => 'account_id',
|
// I would prefer this statement, which has no
|
||||||
'dependent' => false,
|
// engine specific code. However, it doesn't
|
||||||
'conditions' => '',
|
// work with the Linkable behavior. I need to
|
||||||
'fields' => '',
|
// look into that, just not right now.
|
||||||
'order' => '',
|
//'conditions' => array('CurrentLedger.close_id' => null),
|
||||||
'limit' => '',
|
'conditions' => array('CurrentLedger.close_id IS NULL'),
|
||||||
'offset' => '',
|
),
|
||||||
'exclusive' => '',
|
|
||||||
'finderQuery' => '',
|
|
||||||
'counterQuery' => ''
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
var $hasMany = array(
|
||||||
|
'Ledger',
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: type
|
||||||
|
* - Returns the type of this account
|
||||||
|
*/
|
||||||
|
function type($id) {
|
||||||
|
$this->cacheQueries = true;
|
||||||
|
$account = $this->find('first', array
|
||||||
|
('recursive' => -1,
|
||||||
|
'fields' => array('type'),
|
||||||
|
'conditions' => array(array('Account.id' => $id)),
|
||||||
|
));
|
||||||
|
$this->cacheQueries = false;
|
||||||
|
|
||||||
|
return $account['Account']['type'];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: fundamentalType
|
||||||
|
* - Returns the fundmental type of the account, credit or debit
|
||||||
|
*/
|
||||||
|
function fundamentalType($id_or_type) {
|
||||||
|
if (is_numeric($id_or_type))
|
||||||
|
$type = $this->type($id_or_type);
|
||||||
|
else
|
||||||
|
$type = $id_or_type;
|
||||||
|
|
||||||
|
// Asset and Expense accounts are debit accounts
|
||||||
|
if (in_array(strtoupper($type), array('ASSET', 'EXPENSE')))
|
||||||
|
return 'debit';
|
||||||
|
|
||||||
|
// Otherwise, it's a credit account
|
||||||
|
return 'credit';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: fundamentalOpposite
|
||||||
|
* - Returns the opposite fundmental type of the account, credit or debit
|
||||||
|
*/
|
||||||
|
function fundamentalOpposite($id_or_type) {
|
||||||
|
if (in_array(strtolower($id_or_type), array('credit', 'debit')))
|
||||||
|
$fund = $id_or_type;
|
||||||
|
else
|
||||||
|
$fund = $this->fundamentalType($id_or_type);
|
||||||
|
|
||||||
|
if ($fund == 'debit')
|
||||||
|
return 'credit';
|
||||||
|
|
||||||
|
return 'debit';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: name
|
||||||
|
* - Returns the name of this account
|
||||||
|
*/
|
||||||
|
function name($id) {
|
||||||
|
$this->cacheQueries = true;
|
||||||
|
$account = $this->find('first', array
|
||||||
|
('recursive' => -1,
|
||||||
|
'fields' => array('name'),
|
||||||
|
'conditions' => array(array('Account.id' => $id)),
|
||||||
|
));
|
||||||
|
$this->cacheQueries = false;
|
||||||
|
|
||||||
|
return $account['Account']['name'];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: Account IDs
|
||||||
|
* - Returns the ID of the desired account
|
||||||
|
*/
|
||||||
|
|
||||||
|
function securityDepositAccountID() { return $this->nameToID('Security Deposit'); }
|
||||||
|
function rentAccountID() { return $this->nameToID('Rent'); }
|
||||||
|
function lateChargeAccountID() { return $this->nameToID('Late Charge'); }
|
||||||
|
function nsfAccountID() { return $this->nameToID('NSF'); }
|
||||||
|
function nsfChargeAccountID() { return $this->nameToID('NSF Charge'); }
|
||||||
|
function taxAccountID() { return $this->nameToID('Tax'); }
|
||||||
|
function accountReceivableAccountID() { return $this->nameToID('A/R'); }
|
||||||
|
function cashAccountID() { return $this->nameToID('Cash'); }
|
||||||
|
function checkAccountID() { return $this->nameToID('Check'); }
|
||||||
|
function moneyOrderAccountID() { return $this->nameToID('Money Order'); }
|
||||||
|
function concessionAccountID() { return $this->nameToID('Concession'); }
|
||||||
|
function pettyCashAccountID() { return $this->nameToID('Petty Cash'); }
|
||||||
|
function invoiceAccountID() { return $this->nameToID('Invoice'); }
|
||||||
|
function receiptAccountID() { return $this->nameToID('Receipt'); }
|
||||||
|
function badDebtAccountID() { return $this->nameToID('Bad Debt'); }
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: fundamentalAccounts
|
||||||
|
* - Returns an array of accounts by their fundamental type
|
||||||
|
*/
|
||||||
|
|
||||||
|
function fundamentalAccounts($ftype) {
|
||||||
|
$this->cacheQueries = true;
|
||||||
|
$account = $this->find('all', array
|
||||||
|
('contain' => array('CurrentLedger'),
|
||||||
|
'fields' => array('Account.id', 'Account.type', 'Account.name', 'CurrentLedger.id'),
|
||||||
|
'conditions' => array('Account.type' => strtoupper($ftype))
|
||||||
|
));
|
||||||
|
$this->cacheQueries = false;
|
||||||
|
|
||||||
|
return $account;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: relatedAccounts
|
||||||
|
* - Returns an array of accounts related by similar attributes
|
||||||
|
*/
|
||||||
|
|
||||||
|
function relatedAccounts($attribute, $extra = null) {
|
||||||
|
$this->cacheQueries = true;
|
||||||
|
$account = $this->find('all', array
|
||||||
|
('contain' => array('CurrentLedger'),
|
||||||
|
'fields' => array('Account.id', 'Account.type', 'Account.name', 'CurrentLedger.id'),
|
||||||
|
'conditions' => array('Account.'.$attribute => true),
|
||||||
|
'order' => array('Account.name'),
|
||||||
|
) + (isset($extra) ? $extra : array())
|
||||||
|
);
|
||||||
|
$this->cacheQueries = false;
|
||||||
|
|
||||||
|
return $account;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: chargeAccounts
|
||||||
|
* - Returns an array of accounts suitable for charges
|
||||||
|
*/
|
||||||
|
|
||||||
|
function chargeAccounts() {
|
||||||
|
// Get all accounts that support charges
|
||||||
|
$accounts = $this->relatedAccounts('chargeable', array('order' => 'name'));
|
||||||
|
|
||||||
|
// Rearrange to be of the form (id => name)
|
||||||
|
$charge_accounts = array();
|
||||||
|
foreach ($accounts AS $acct) {
|
||||||
|
$charge_accounts[$acct['Account']['id']] = $acct['Account']['name'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $charge_accounts;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: paymentAccounts
|
||||||
|
* - Returns an array of accounts suitable for payments
|
||||||
|
*/
|
||||||
|
|
||||||
|
function paymentAccounts() {
|
||||||
|
// Get all accounts that support payments
|
||||||
|
$accounts = $this->relatedAccounts('payable', array('order' => 'name'));
|
||||||
|
|
||||||
|
// Rearrange to be of the form (id => name)
|
||||||
|
$payment_accounts = array();
|
||||||
|
foreach ($accounts AS $acct) {
|
||||||
|
$payment_accounts[$acct['Account']['id']] = $acct['Account']['name'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $payment_accounts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: collectableAccounts
|
||||||
|
* - Returns an array of accounts suitable to show income collection
|
||||||
|
*/
|
||||||
|
|
||||||
|
function collectableAccounts() {
|
||||||
|
$accounts = $this->paymentAccounts();
|
||||||
|
|
||||||
|
foreach(array($this->nsfAccountID(),
|
||||||
|
$this->securityDepositAccountID())
|
||||||
|
AS $account_id) {
|
||||||
|
$accounts[$account_id] = $this->name($account_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $accounts;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: currentLedgerID
|
||||||
|
* - Returns the current ledger ID of the account
|
||||||
|
*/
|
||||||
|
function currentLedgerID($id) {
|
||||||
|
$this->cacheQueries = true;
|
||||||
|
$item = $this->find('first', array
|
||||||
|
('contain' => 'CurrentLedger',
|
||||||
|
'conditions' => array('Account.id' => $id),
|
||||||
|
));
|
||||||
|
$this->cacheQueries = false;
|
||||||
|
return $item['CurrentLedger']['id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: ledgers
|
||||||
|
* - Returns an array of ledger ids from the given account
|
||||||
|
*/
|
||||||
|
function ledgers($id, $all = false) {
|
||||||
|
if ($all) {
|
||||||
|
$contain = array('Ledger' => array('fields' => array('Ledger.id')));
|
||||||
|
} else {
|
||||||
|
$contain = array('CurrentLedger' => array('fields' => array('CurrentLedger.id')));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->cacheQueries = true;
|
||||||
|
$account = $this->find('first', array
|
||||||
|
('contain' => $contain,
|
||||||
|
'fields' => array(),
|
||||||
|
'conditions' => array(array('Account.id' => $id)),
|
||||||
|
));
|
||||||
|
$this->cacheQueries = false;
|
||||||
|
|
||||||
|
if ($all) {
|
||||||
|
$ledger_ids = array();
|
||||||
|
foreach ($account['Ledger'] AS $ledger)
|
||||||
|
array_push($ledger_ids, $ledger['id']);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$ledger_ids = array($account['CurrentLedger']['id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pr(array('function' => 'Account::ledgers', */
|
||||||
|
/* 'args' => compact('id', 'all'), */
|
||||||
|
/* 'return' => $ledger_ids)); */
|
||||||
|
|
||||||
|
return $ledger_ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: closeCurrentLedger
|
||||||
|
* - Closes the current account ledger, and opens a new one
|
||||||
|
* with the old balance carried forward.
|
||||||
|
*/
|
||||||
|
function closeCurrentLedger($id = null, $close_id = null) {
|
||||||
|
$contain = array('CurrentLedger' => array('fields' => array('CurrentLedger.id')));
|
||||||
|
|
||||||
|
if (!$close_id) {
|
||||||
|
$close = new Close();
|
||||||
|
$close->create();
|
||||||
|
if (!$close->save(array('stamp' => null), false)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$close_id = $close->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->cacheQueries = true;
|
||||||
|
$account = $this->find('all', array
|
||||||
|
('contain' => $contain,
|
||||||
|
'fields' => array(),
|
||||||
|
'conditions' =>
|
||||||
|
$id ? array(array('Account.id' => $id)) : array()
|
||||||
|
));
|
||||||
|
$this->cacheQueries = false;
|
||||||
|
//pr(compact('id', 'account'));
|
||||||
|
|
||||||
|
foreach ($account AS $acct) {
|
||||||
|
if (!$this->Ledger->closeLedger($acct['CurrentLedger']['id'], $close_id))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: findLedgerEntries
|
||||||
|
* - Returns an array of ledger entries that belong to the given
|
||||||
|
* account, either just from the current ledger, or from all ledgers.
|
||||||
|
*/
|
||||||
|
function findLedgerEntries($id, $all = false, $cond = null, $link = null) {
|
||||||
|
/* pr(array('function' => 'Account::findLedgerEntries', */
|
||||||
|
/* 'args' => compact('id', 'all', 'cond', 'link'), */
|
||||||
|
/* )); */
|
||||||
|
|
||||||
|
$entries = array();
|
||||||
|
foreach ($this->ledgers($id, $all) AS $ledger_id) {
|
||||||
|
$ledger_entries = $this->Ledger->findLedgerEntries
|
||||||
|
($ledger_id, $this->type($id), $cond, $link);
|
||||||
|
$entries = array_merge($entries, $ledger_entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
$stats = $this->stats($id, $all, $cond);
|
||||||
|
$entries = array('Entries' => $entries,
|
||||||
|
'summary' => $stats['Ledger']);
|
||||||
|
|
||||||
|
/* pr(array('function' => 'Account::findLedgerEntries', */
|
||||||
|
/* 'args' => compact('id', 'all', 'cond', 'link'), */
|
||||||
|
/* 'vars' => compact('stats'), */
|
||||||
|
/* 'return' => compact('entries'), */
|
||||||
|
/* )); */
|
||||||
|
|
||||||
|
return $entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: findLedgerEntriesRelatedToAccount
|
||||||
|
* - Returns an array of ledger entries that belong to the given
|
||||||
|
* account, and are related to a specific account, either just from
|
||||||
|
* the current ledger, or from all ledgers.
|
||||||
|
*/
|
||||||
|
function findLedgerEntriesRelatedToAccount($id, $rel_ids, $all = false, $cond = null, $link = null) {
|
||||||
|
/* pr(array('function' => 'Account::findLedgerEntriesRelatedToAccount', */
|
||||||
|
/* 'args' => compact('id', 'rel_ids', 'all', 'cond', 'link'), */
|
||||||
|
/* )); */
|
||||||
|
|
||||||
|
if (!isset($cond))
|
||||||
|
$cond = array();
|
||||||
|
if (!is_array($rel_ids))
|
||||||
|
$rel_ids = array($rel_ids);
|
||||||
|
|
||||||
|
$ledger_ids = array();
|
||||||
|
foreach ($rel_ids AS $rel_id)
|
||||||
|
$ledger_ids = array_merge($ledger_ids, $this->ledgers($rel_id));
|
||||||
|
|
||||||
|
array_push($cond, $this->Ledger->LedgerEntry->conditionEntryAsCreditOrDebit($ledger_ids));
|
||||||
|
$entries = $this->findLedgerEntries($id, $all, $cond, $link);
|
||||||
|
|
||||||
|
/* pr(array('function' => 'Account::findLedgerEntriesRelatedToAccount', */
|
||||||
|
/* 'args' => compact('id', 'relid', 'all', 'cond', 'link'), */
|
||||||
|
/* 'vars' => compact('ledger_ids'), */
|
||||||
|
/* 'return' => compact('entries'), */
|
||||||
|
/* )); */
|
||||||
|
return $entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: findUnreconciledLedgerEntries
|
||||||
|
* - Returns ledger entries that are not yet reconciled
|
||||||
|
* (such as charges not paid).
|
||||||
|
*/
|
||||||
|
|
||||||
|
function findUnreconciledLedgerEntries($id = null, $fundamental_type = null, $cond = null) {
|
||||||
|
if (!isset($cond))
|
||||||
|
$cond = array();
|
||||||
|
$cond[] = array('Account.id' => $id);
|
||||||
|
|
||||||
|
foreach (($fundamental_type
|
||||||
|
? array($fundamental_type)
|
||||||
|
: array('debit', 'credit')) AS $fund) {
|
||||||
|
$ucfund = ucfirst($fund);
|
||||||
|
$unreconciled[$fund]['entry'] = $this->find
|
||||||
|
('all', array
|
||||||
|
('link' => array
|
||||||
|
('Ledger' => array
|
||||||
|
('fields' => array(),
|
||||||
|
"LedgerEntry" => array
|
||||||
|
('class' => "{$ucfund}LedgerEntry",
|
||||||
|
'fields' => array('id', 'customer_id', 'lease_id', 'amount'),
|
||||||
|
"ReconciliationLedgerEntry" => array
|
||||||
|
('class' => "{$ucfund}ReconciliationLedgerEntry",
|
||||||
|
'fields' => array
|
||||||
|
("COALESCE(SUM(Reconciliation.amount),0) AS 'reconciled'",
|
||||||
|
"LedgerEntry.amount - COALESCE(SUM(Reconciliation.amount),0) AS 'balance'",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'group' => ("LedgerEntry.id" .
|
||||||
|
" HAVING LedgerEntry.amount" .
|
||||||
|
" <> COALESCE(SUM(Reconciliation.amount),0)"),
|
||||||
|
'conditions' => $cond,
|
||||||
|
'fields' => array(),
|
||||||
|
));
|
||||||
|
$balance = 0;
|
||||||
|
foreach ($unreconciled[$fund]['entry'] AS &$entry) {
|
||||||
|
$entry = array_merge(array_diff_key($entry["LedgerEntry"], array(0=>true)),
|
||||||
|
$entry[0]);
|
||||||
|
$balance += $entry['balance'];
|
||||||
|
}
|
||||||
|
$unreconciled[$fund]['balance'] = $balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $unreconciled;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: reconcileNewLedgerEntry
|
||||||
|
* - Returns which ledger entries a new credit/debit would
|
||||||
|
* reconcile, and how much.
|
||||||
|
*
|
||||||
|
* - REVISIT <AP> 20090617
|
||||||
|
* This should be subject to different algorithms, such
|
||||||
|
* as apply to oldest charges first, newest first, to fees
|
||||||
|
* before rent, etc. Until we get there, I'll hardcode
|
||||||
|
* whatever algorithm is simplest.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function reconcileNewLedgerEntry($id, $fundamental_type, $amount, $cond = null) {
|
||||||
|
$ofund = $this->fundamentalOpposite($fundamental_type);
|
||||||
|
$unreconciled = array($ofund => array('entry'=>array(), 'balance'=>0));
|
||||||
|
$applied = 0;
|
||||||
|
|
||||||
|
// if there is no money in the entry, it can reconcile nothing
|
||||||
|
// don't bother wasting time sifting ledger entries.
|
||||||
|
if ($amount > 0) {
|
||||||
|
$unreconciled = $this->findUnreconciledLedgerEntries($id, $ofund, $cond);
|
||||||
|
|
||||||
|
foreach ($unreconciled[$ofund]['entry'] AS $i => &$entry) {
|
||||||
|
// Determine if amount is sufficient to cover the entry
|
||||||
|
if ($amount > $entry['balance'])
|
||||||
|
$apply = $entry['balance'];
|
||||||
|
elseif ($amount > 0)
|
||||||
|
$apply = $amount;
|
||||||
|
else {
|
||||||
|
unset($unreconciled[$ofund]['entry'][$i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$entry['applied'] = $apply;
|
||||||
|
$entry['reconciled'] += $apply;
|
||||||
|
$entry['balance'] -= $apply;
|
||||||
|
$applied += $apply;
|
||||||
|
$amount -= $apply;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$unreconciled[$ofund]['unapplied'] = $amount;
|
||||||
|
$unreconciled[$ofund]['applied'] = $applied;
|
||||||
|
$unreconciled[$ofund]['balance'] -= $applied;
|
||||||
|
return $unreconciled;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: postLedgerEntry
|
||||||
|
* -
|
||||||
|
* transaction_data
|
||||||
|
* - transaction_id (optional... if set all else is ignored)
|
||||||
|
* - Transaction
|
||||||
|
* - stamp (optional... otherwise NOW is used)
|
||||||
|
* - comment
|
||||||
|
*
|
||||||
|
* monetary_source_data
|
||||||
|
* - monetary_source_id (optional... if set all else is ignored)
|
||||||
|
* - account_name
|
||||||
|
* - MonetarySource
|
||||||
|
* - name
|
||||||
|
*/
|
||||||
|
|
||||||
|
function postLedgerEntry($transaction_data,
|
||||||
|
$monetary_data,
|
||||||
|
$entry_data,
|
||||||
|
$reconcile = null) {
|
||||||
|
//pr(compact('transaction_data', 'monetary_data', 'entry_data', 'reconcile'));
|
||||||
|
|
||||||
|
// Automatically figure out the customer if we have the lease
|
||||||
|
if (isset($entry_data['lease_id']) && !isset($entry_data['customer_id'])) {
|
||||||
|
$L = new Lease();
|
||||||
|
$L->recursive = -1;
|
||||||
|
$lease = $L->read(null, $entry_data['lease_id']);
|
||||||
|
$entry_data['customer_id'] = $lease['Lease']['customer_id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($entry_data['lease_id']))
|
||||||
|
$entry_data['lease_id'] = null;
|
||||||
|
|
||||||
|
if (!isset($entry_data['customer_id']))
|
||||||
|
$entry_data['customer_id'] = null;
|
||||||
|
|
||||||
|
// Get the Transaction squared away
|
||||||
|
if (isset($transaction_data['transaction_id'])) {
|
||||||
|
$transaction_data
|
||||||
|
= array_intersect_key($transaction_data,
|
||||||
|
array('transaction_id'=>1,
|
||||||
|
'split_transaction_id'=>1));
|
||||||
|
}
|
||||||
|
elseif (isset($transaction_data['Transaction'])) {
|
||||||
|
$transaction_data
|
||||||
|
= array_intersect_key($transaction_data,
|
||||||
|
array('Transaction'=>1,
|
||||||
|
'split_transaction_id'=>1));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$transaction_data = array('Transaction'=>array('stamp' => null));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Get the Monetary Source squared away
|
||||||
|
if (isset($monetary_data)) {
|
||||||
|
if (!isset($monetary_data['monetary_source_id'])) {
|
||||||
|
|
||||||
|
// Convert Account ID to name or vice versa
|
||||||
|
if (isset($monetary_data['account_id'])) {
|
||||||
|
$monetary_data['account_name'] = $this->name($monetary_data['account_id']);
|
||||||
|
} elseif (isset($monetary_data['account_name'])) {
|
||||||
|
$monetary_data['account_id'] = $this->nameToID($monetary_data['account_name']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($monetary_data['account_id'] == $this->cashAccountID()) {
|
||||||
|
// No distinguishing features of Cash, just
|
||||||
|
// use the shared monetary source
|
||||||
|
$monetary_data['monetary_source_id'] =
|
||||||
|
$this->Ledger->LedgerEntry->MonetarySource->nameToID('Cash');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($monetary_data['monetary_source_id'])) {
|
||||||
|
$monetary_data
|
||||||
|
= array_intersect_key($monetary_data,
|
||||||
|
array('monetary_source_id'=>1));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// The monetary source needs to be unique
|
||||||
|
// Create a new one dedicated to this entry
|
||||||
|
// Give it a fancy name based on the check number
|
||||||
|
$monetary_data['MonetarySource']['name'] = $monetary_data['account_name'];
|
||||||
|
if ($monetary_data['account_name'] === $this->name($this->checkAccountID()) ||
|
||||||
|
$monetary_data['account_name'] === $this->name($this->moneyOrderAccountID())) {
|
||||||
|
$monetary_data['MonetarySource']['name'] .=
|
||||||
|
' #' . $monetary_data['MonetarySource']['data1'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$monetary_data
|
||||||
|
= array_intersect_key($monetary_data,
|
||||||
|
array('MonetarySource'=>1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$monetary_data = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure to clean out any unwanted data from the entry
|
||||||
|
$entry_data
|
||||||
|
= array_diff_key($entry_data,
|
||||||
|
array('transaction_id'=>1, 'Transaction'=>1,
|
||||||
|
'monetary_source_id'=>1, 'MonetarySource'=>1));
|
||||||
|
|
||||||
|
// Then add in the transaction and monetary source data
|
||||||
|
//pr(compact('transaction_data', 'monetary_data', 'entry_data'));
|
||||||
|
if (isset($transaction_data))
|
||||||
|
$entry_data += $transaction_data;
|
||||||
|
if (isset($monetary_data))
|
||||||
|
$entry_data += $monetary_data;
|
||||||
|
|
||||||
|
// Set up the debit ledger id
|
||||||
|
if (!isset($entry_data['debit_ledger_id'])) {
|
||||||
|
$entry_data['debit_ledger_id'] =
|
||||||
|
(isset($entry_data['debit_account_id'])
|
||||||
|
? $this->currentLedgerID($entry_data['debit_account_id'])
|
||||||
|
: (isset($entry_data['debit_account_name'])
|
||||||
|
? $this->currentLedgerID($this->nameToID($entry_data['debit_account_name']))
|
||||||
|
: null
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up the credit ledger id
|
||||||
|
if (!isset($entry_data['credit_ledger_id'])) {
|
||||||
|
$entry_data['credit_ledger_id'] =
|
||||||
|
(isset($entry_data['credit_account_id'])
|
||||||
|
? $this->currentLedgerID($entry_data['credit_account_id'])
|
||||||
|
: (isset($entry_data['credit_account_name'])
|
||||||
|
? $this->currentLedgerID($this->nameToID($entry_data['credit_account_name']))
|
||||||
|
: null
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//pr(array('pre-save', compact('entry_data')));
|
||||||
|
// Create it!
|
||||||
|
$new_entry = new LedgerEntry();
|
||||||
|
$new_entry->create();
|
||||||
|
if (!$new_entry->saveAll($entry_data, array('validate'=>false))) {
|
||||||
|
return array('error' => true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// See if the user has entered some sort of non-array
|
||||||
|
// for the reconcile parameter.
|
||||||
|
if (isset($reconcile) && is_bool($reconcile) && $reconcile) {
|
||||||
|
$reconcile = array('debit' => true, 'credit' => true);
|
||||||
|
}
|
||||||
|
elseif (isset($reconcile) && $reconcile == 'invoice') {
|
||||||
|
$reconcile = array('credit' => 'invoice');
|
||||||
|
}
|
||||||
|
elseif (isset($reconcile) && $reconcile == 'receipt') {
|
||||||
|
$reconcile = array('debit' => 'receipt');
|
||||||
|
}
|
||||||
|
elseif (!isset($reconcile) || !is_array($reconcile)) {
|
||||||
|
$reconcile = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reconcile the new entry... assume we'll have success
|
||||||
|
$err = false;
|
||||||
|
foreach (array_intersect_key($reconcile, array('credit'=>1,'debit'=>1))
|
||||||
|
AS $dc_type => $reconcile_set) {
|
||||||
|
if (!isset($reconcile_set) || (is_bool($reconcile_set) && !$reconcile_set))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ($reconcile_set === 'receipt') {
|
||||||
|
$C = new Customer();
|
||||||
|
$reconciled = $C->reconcileNewLedgerEntry($entry_data['customer_id'],
|
||||||
|
$this->fundamentalOpposite($dc_type),
|
||||||
|
$entry_data['amount']);
|
||||||
|
|
||||||
|
/* pr(array("reconcile receipt", */
|
||||||
|
/* compact('reconciled', 'split_transaction', 'transaction_data'))); */
|
||||||
|
$split_transaction = array_intersect_key($transaction_data,
|
||||||
|
array('Transaction'=>1,
|
||||||
|
'split_transaction_id'=>1));
|
||||||
|
|
||||||
|
if (isset($split_transaction['split_transaction_id']))
|
||||||
|
$split_transaction['transaction_id'] = $split_transaction['split_transaction_id'];
|
||||||
|
|
||||||
|
if (is_array($reconciled) && count($reconciled[$dc_type]['entry'])) {
|
||||||
|
foreach ($reconciled[$dc_type]['entry'] AS $rec) {
|
||||||
|
//pr(compact('rec', 'split_transaction'));
|
||||||
|
if (!$rec['applied'])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Create an entry to handle the splitting of the funds ("Payment")
|
||||||
|
// and reconcile against the new cash/check/etc entry created above,
|
||||||
|
// as well as the A/R account.
|
||||||
|
|
||||||
|
// Payment must debit the Receipt ledger, and credit the A/R ledger
|
||||||
|
// debit: Receipt credit: A/R
|
||||||
|
$ids = $this->postLedgerEntry
|
||||||
|
($split_transaction,
|
||||||
|
null,
|
||||||
|
array('debit_ledger_id' => $this->currentLedgerID($this->receiptAccountID()),
|
||||||
|
'credit_ledger_id' => $this->currentLedgerID($this->accountReceivableAccountID()),
|
||||||
|
'amount' => $rec['applied'],
|
||||||
|
'lease_id' => $rec['lease_id'],
|
||||||
|
'customer_id' => $rec['customer_id'],
|
||||||
|
),
|
||||||
|
array('debit' => array(array('LedgerEntry' => array('id' => $new_entry->id,
|
||||||
|
'amount' => $rec['applied']))),
|
||||||
|
'credit' => array(array('LedgerEntry' => array('id' => $rec['id'],
|
||||||
|
'amount' => $rec['applied']))))
|
||||||
|
);
|
||||||
|
// Keep using the same split transaction for all reconciled entries
|
||||||
|
$split_transaction = array_intersect_key($ids, array('transaction_id'=>1));
|
||||||
|
//pr(compact('ids', 'split_transaction'));
|
||||||
|
}
|
||||||
|
|
||||||
|
//pr("end reconciled is array");
|
||||||
|
}
|
||||||
|
|
||||||
|
//pr("end reconcile receipt");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($reconcile_set)) {
|
||||||
|
//pr("reconcile_set is array");
|
||||||
|
foreach ($reconcile_set AS $reconcile_entry) {
|
||||||
|
if (!isset($reconcile_entry['LedgerEntry']['id']))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
$amount = $reconcile_entry['LedgerEntry']['amount'];
|
||||||
|
if (!$amount)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ($dc_type == 'debit') {
|
||||||
|
$debit_ledger_entry_id = $new_entry->id;
|
||||||
|
$credit_ledger_entry_id = $reconcile_entry['LedgerEntry']['id'];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$debit_ledger_entry_id = $reconcile_entry['LedgerEntry']['id'];
|
||||||
|
$credit_ledger_entry_id = $new_entry->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
$R = new Reconciliation();
|
||||||
|
$R->create();
|
||||||
|
if (!$R->save(compact('amount',
|
||||||
|
'debit_ledger_entry_id',
|
||||||
|
'credit_ledger_entry_id'), false))
|
||||||
|
$err = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$new_entry->recursive = -1;
|
||||||
|
$new_entry->read();
|
||||||
|
//pr(array('post-save', $entry->data));
|
||||||
|
|
||||||
|
$ret = array
|
||||||
|
('error' => $err,
|
||||||
|
'id' => $new_entry->data['LedgerEntry']['id'],
|
||||||
|
'transaction_id' => $new_entry->data['LedgerEntry']['transaction_id'],
|
||||||
|
'monetary_source_id' => $new_entry->data['LedgerEntry']['monetary_source_id']);
|
||||||
|
|
||||||
|
if (isset($split_transaction['transaction_id']))
|
||||||
|
$ret['split_transaction_id'] = $split_transaction['transaction_id'];
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: closeAndDeposit
|
||||||
|
* - Closes the current set of ledgers, transferring
|
||||||
|
* their balances to specified ledger.
|
||||||
|
*/
|
||||||
|
function closeAndDeposit($set, $deposit_account_id) {
|
||||||
|
|
||||||
|
$close = new Close();
|
||||||
|
$close->create();
|
||||||
|
if (!$close->save(array('stamp' => null, 'comment' => 'Deposit'), false)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$transaction = array();
|
||||||
|
foreach ($set AS $ledger) {
|
||||||
|
// REVISIT <AP>: 20090710
|
||||||
|
// If the user said to include a ledger in the
|
||||||
|
// set, should we really be excluding it?
|
||||||
|
if ($ledger['total'] == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
$ids = $this->postLedgerEntry
|
||||||
|
($transaction,
|
||||||
|
null,
|
||||||
|
array('debit_account_id' => $deposit_account_id,
|
||||||
|
'credit_ledger_id' => $ledger['id'],
|
||||||
|
'amount' => $ledger['total']),
|
||||||
|
// Reconcile the account for cash/check/etc,
|
||||||
|
// which is the credit side of this entry.
|
||||||
|
array('credit' => $ledger['entries']));
|
||||||
|
//pr(compact('ids'));
|
||||||
|
|
||||||
|
if ($ids['error'])
|
||||||
|
die("closeAndDeposit : postLedgerEntry returned error!");
|
||||||
|
|
||||||
|
$transaction = array_intersect_key($ids, array('transaction_id'=>1));
|
||||||
|
|
||||||
|
$this->Ledger->closeLedger($ledger['id'], $close->id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: stats
|
||||||
|
* - Returns summary data from the requested account.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function stats($id = null, $all = false, $cond = null) {
|
||||||
|
if (!$id)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// All old, closed ledgers MUST balance to 0.
|
||||||
|
// However, the user may want the ENTIRE running totals,
|
||||||
|
// (not just the balance), so we may have to query all
|
||||||
|
// ledgers, as dictated by the $all parameter.
|
||||||
|
|
||||||
|
$account = $this->find('first',
|
||||||
|
array('contain' =>
|
||||||
|
($all
|
||||||
|
? array('Ledger' => array
|
||||||
|
('fields' => array('id')))
|
||||||
|
: array('CurrentLedger' => array
|
||||||
|
('fields' => array('id')))
|
||||||
|
),
|
||||||
|
'conditions' => array
|
||||||
|
(array('Account.id' => $id))
|
||||||
|
));
|
||||||
|
|
||||||
|
$stats = array();
|
||||||
|
if ($all) {
|
||||||
|
foreach ($account['Ledger'] AS $ledger)
|
||||||
|
$this->statsMerge($stats['Ledger'],
|
||||||
|
$this->Ledger->stats($ledger['id'], $cond));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$stats['Ledger'] =
|
||||||
|
$this->Ledger->stats($account['CurrentLedger']['id'], $cond);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $stats;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
@@ -29,6 +29,50 @@
|
|||||||
* @version 1.0;
|
* @version 1.0;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* NOTE TO <AP> 20090615:
|
||||||
|
* This structure should be linkable (it was my test case).
|
||||||
|
|
||||||
|
$entry = $this->LedgerEntry->find
|
||||||
|
('first',
|
||||||
|
array('link' => array('DebitLedger' =>
|
||||||
|
array(
|
||||||
|
'fields' => array('id'),
|
||||||
|
'alias' => 'MyDebitLedger',
|
||||||
|
'Account' =>
|
||||||
|
array(
|
||||||
|
'fields' => array('id'),
|
||||||
|
'alias' => 'MyDebitAccount'),
|
||||||
|
),
|
||||||
|
|
||||||
|
'MyCreditLedger' =>
|
||||||
|
array(
|
||||||
|
'fields' => array('id'),
|
||||||
|
'class' => 'CreditLedger',
|
||||||
|
'MyCreditAccount' =>
|
||||||
|
array(
|
||||||
|
'fields' => array('id'),
|
||||||
|
'class' => 'Account'),
|
||||||
|
),
|
||||||
|
|
||||||
|
'MyOtherLedger' =>
|
||||||
|
array(
|
||||||
|
'fields' => array('id'),
|
||||||
|
'class' => 'Ledger',
|
||||||
|
'alias' => 'AliasToMyOtherLedger',
|
||||||
|
'Account' =>
|
||||||
|
array(
|
||||||
|
'fields' => array('id'),
|
||||||
|
'alias' => 'AliasToMyOtherAccount'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
'conditions' => array('LedgerEntry.id' => $id),
|
||||||
|
));
|
||||||
|
**********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
class LinkableBehavior extends ModelBehavior {
|
class LinkableBehavior extends ModelBehavior {
|
||||||
|
|
||||||
protected $_key = 'link';
|
protected $_key = 'link';
|
||||||
@@ -36,15 +80,65 @@ class LinkableBehavior extends ModelBehavior {
|
|||||||
protected $_options = array(
|
protected $_options = array(
|
||||||
'type' => true, 'table' => true, 'alias' => true, 'joins' => true,
|
'type' => true, 'table' => true, 'alias' => true, 'joins' => true,
|
||||||
'conditions' => true, 'fields' => true, 'reference' => true,
|
'conditions' => true, 'fields' => true, 'reference' => true,
|
||||||
'class' => true, 'defaults' => true
|
'class' => true, 'defaults' => true, 'linkalias' => true,
|
||||||
);
|
);
|
||||||
|
|
||||||
protected $_defaults = array('type' => 'LEFT');
|
protected $_defaults = array('type' => 'LEFT');
|
||||||
|
|
||||||
|
function pr($lev, $mixed) {
|
||||||
|
if ($lev >= 5)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pr($mixed);
|
||||||
|
return;
|
||||||
|
|
||||||
|
$trace = debug_backtrace(false);
|
||||||
|
//array_shift($trace);
|
||||||
|
$calls = array();
|
||||||
|
foreach ($trace AS $call) {
|
||||||
|
$call = array_intersect_key($call,
|
||||||
|
array('file'=>1,
|
||||||
|
'line'=>1,
|
||||||
|
//'class'=>1,
|
||||||
|
'function'=>1,
|
||||||
|
));
|
||||||
|
$calls[] = implode("; ", $call);
|
||||||
|
}
|
||||||
|
pr(array('debug' => $mixed, 'stack' => $calls));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is a function for made recursive str_replaces in an array
|
||||||
|
* NOTE: The palacement of this function is terrible, but I don't
|
||||||
|
* know if I really want to go down this path or not.
|
||||||
|
*/
|
||||||
|
function recursive_array_replace($find, $replace, &$data) {
|
||||||
|
if (!isset($data))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (is_array($data)) {
|
||||||
|
foreach ($data as $key => $value) {
|
||||||
|
if (is_array($value)) {
|
||||||
|
$this->recursive_array_replace($find, $replace, $data[$key]);
|
||||||
|
} else {
|
||||||
|
$data[$key] = str_replace($find, $replace, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$data = str_replace($find, $replace, $data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function beforeFind(&$Model, $query) {
|
public function beforeFind(&$Model, $query) {
|
||||||
/* pr("Linkable::beforeFind() begin"); pr($query); */
|
$this->pr(10,
|
||||||
|
array('function' => 'Linkable::beforeFind',
|
||||||
|
'args' => array('Model->alias' => '$Model->alias') + compact('query'),
|
||||||
|
));
|
||||||
if (isset($query[$this->_key])) {
|
if (isset($query[$this->_key])) {
|
||||||
$optionsDefaults = $this->_defaults + array('reference' => $Model->alias, $this->_key => array());
|
$optionsDefaults = $this->_defaults + array('reference' =>
|
||||||
|
array('class' => $Model->alias,
|
||||||
|
'alias' => $Model->alias),
|
||||||
|
$this->_key => array());
|
||||||
$optionsKeys = $this->_options + array($this->_key => true);
|
$optionsKeys = $this->_options + array($this->_key => true);
|
||||||
if (!isset($query['fields']) || $query['fields'] === true) {
|
if (!isset($query['fields']) || $query['fields'] === true) {
|
||||||
//$query['fields'] = array_keys($Model->_schema);
|
//$query['fields'] = array_keys($Model->_schema);
|
||||||
@@ -63,6 +157,10 @@ class LinkableBehavior extends ModelBehavior {
|
|||||||
unset($iterator['defaults']);
|
unset($iterator['defaults']);
|
||||||
}
|
}
|
||||||
$iterations = Set::normalize($iterator);
|
$iterations = Set::normalize($iterator);
|
||||||
|
$this->pr(25,
|
||||||
|
array('checkpoint' => 'Iterations',
|
||||||
|
compact('iterations'),
|
||||||
|
));
|
||||||
foreach ($iterations as $alias => $options) {
|
foreach ($iterations as $alias => $options) {
|
||||||
if (is_null($options)) {
|
if (is_null($options)) {
|
||||||
$options = array();
|
$options = array();
|
||||||
@@ -72,122 +170,237 @@ class LinkableBehavior extends ModelBehavior {
|
|||||||
throw new InvalidArgumentException(sprintf('%s::%s must receive aliased links', get_class($this), __FUNCTION__));
|
throw new InvalidArgumentException(sprintf('%s::%s must receive aliased links', get_class($this), __FUNCTION__));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($options['table']) && empty($options['class'])) {
|
if (empty($options['class']))
|
||||||
$options['class'] = $options['alias'];
|
$options['class'] = $alias;
|
||||||
} elseif (!empty($options['table']) && empty($options['class'])) {
|
|
||||||
$options['class'] = Inflector::classify($options['table']);
|
if (!isset($options['conditions']))
|
||||||
}
|
$options['conditions'] = array();
|
||||||
$_Model =& ClassRegistry::init($options['class']); // the incoming model to be linked in query
|
elseif (!is_array($options['conditions']))
|
||||||
$Reference =& ClassRegistry::init($options['reference']); // the already in query model that links to $_Model
|
$options['conditions'] = array($options['conditions']);
|
||||||
/* pr("_Model: $options[class] : $_Model->name ($_Model->alias)"); */
|
|
||||||
/* pr("Reference: $options[reference] : $Reference->name ($Reference->alias)"); */
|
$this->pr(20,
|
||||||
|
array('checkpoint' => 'Begin Model Work',
|
||||||
|
compact('alias', 'options'),
|
||||||
|
));
|
||||||
|
|
||||||
|
$modelClass = $options['class'];
|
||||||
|
$modelAlias = $options['alias'];
|
||||||
|
$referenceClass = $options['reference']['class'];
|
||||||
|
$referenceAlias = $options['reference']['alias'];
|
||||||
|
|
||||||
|
$_Model =& ClassRegistry::init($modelClass); // the incoming model to be linked in query
|
||||||
|
$Reference =& ClassRegistry::init($referenceClass); // the already in query model that links to $_Model
|
||||||
|
$this->pr(12,
|
||||||
|
array('checkpoint' => 'Aliases Established',
|
||||||
|
'Model' => ($modelAlias .' : '. $modelClass .
|
||||||
|
' ('. $_Model->alias .' : '. $_Model->name .')'),
|
||||||
|
'Reference' => ($referenceAlias .' : '. $referenceClass .
|
||||||
|
' ('. $Reference->alias .' : '. $Reference->name .')'),
|
||||||
|
));
|
||||||
|
|
||||||
$db =& $_Model->getDataSource();
|
$db =& $_Model->getDataSource();
|
||||||
$associations = $_Model->getAssociated();
|
|
||||||
if (isset($associations[$Reference->alias])) {
|
$associatedThroughReference = 0;
|
||||||
|
$association = null;
|
||||||
|
|
||||||
|
// Figure out how these two models are related, creating
|
||||||
|
// a relationship if one doesn't otherwise already exists.
|
||||||
|
if (($associations = $Reference->getAssociated()) &&
|
||||||
|
isset($associations[$_Model->alias])) {
|
||||||
|
$this->pr(12, array('checkpoint' => "Reference defines association to _Model"));
|
||||||
|
$associatedThroughReference = 1;
|
||||||
|
$type = $associations[$_Model->alias];
|
||||||
|
$association = $Reference->{$type}[$_Model->alias];
|
||||||
|
}
|
||||||
|
elseif (($associations = $_Model->getAssociated()) &&
|
||||||
|
isset($associations[$Reference->alias])) {
|
||||||
|
$this->pr(12, array('checkpoint' => "_Model defines association to Reference"));
|
||||||
$type = $associations[$Reference->alias];
|
$type = $associations[$Reference->alias];
|
||||||
$association = $_Model->{$type}[$Reference->alias];
|
$association = $_Model->{$type}[$Reference->alias];
|
||||||
} else {
|
}
|
||||||
$_Model->bind($Reference->alias);
|
else {
|
||||||
|
// No relationship... make our best effort to create one.
|
||||||
|
$this->pr(12, array('checkpoint' => "No assocation between _Model and Reference"));
|
||||||
$type = 'belongsTo';
|
$type = 'belongsTo';
|
||||||
|
$_Model->bind($Reference->alias);
|
||||||
|
// Grab the association now, since we'll unbind in a moment.
|
||||||
$association = $_Model->{$type}[$Reference->alias];
|
$association = $_Model->{$type}[$Reference->alias];
|
||||||
$_Model->unbindModel(array('belongsTo' => array($Reference->alias)));
|
$_Model->unbindModel(array('belongsTo' => array($Reference->alias)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($options['conditions'])) {
|
// Determine which model holds the foreign key
|
||||||
if ($type === 'belongsTo') {
|
if (($type === 'hasMany' || $type === 'hasOne') ^ $associatedThroughReference) {
|
||||||
$modelKey = $_Model->escapeField($association['foreignKey']);
|
$primaryAlias = $referenceAlias;
|
||||||
$referenceKey = $Reference->escapeField($Reference->primaryKey);
|
$foreignAlias = $modelAlias;
|
||||||
$options['conditions'] = "{$referenceKey} = {$modelKey}";
|
$primaryModel = $Reference;
|
||||||
} elseif ($type === 'hasAndBelongsToMany') {
|
$foreignModel = $_Model;
|
||||||
if (isset($association['with']))
|
} else {
|
||||||
$Link =& $_Model->{$association['with']};
|
$primaryAlias = $modelAlias;
|
||||||
else
|
$foreignAlias = $referenceAlias;
|
||||||
$Link =& $_Model->{Inflector::classify($association['joinTable'])};
|
$primaryModel = $_Model;
|
||||||
|
$foreignModel = $Reference;
|
||||||
$linkAlias = $Link->alias;
|
|
||||||
//$linkAlias = $Link->alias . $options['alias'];
|
|
||||||
|
|
||||||
// Get the foreign key fields (for the link table) directly from
|
|
||||||
// the defined model associations, if they exists. This is the
|
|
||||||
// users direct specification, and therefore definitive if present.
|
|
||||||
$modelLink = $Link->escapeField($association['foreignKey'], $linkAlias);
|
|
||||||
$referenceLink = $Link->escapeField($association['associationForeignKey'], $linkAlias);
|
|
||||||
|
|
||||||
// If we haven't figured out the foreign keys, see if there is a
|
|
||||||
// model for the link table, and if it has the appropriate
|
|
||||||
// associations with the two tables we're trying to join.
|
|
||||||
if (empty($modelLink) && isset($Link->belongsTo[$_Model->alias]))
|
|
||||||
$modelLink = $Link->escapeField($Link->belongsTo[$_Model->alias]['foreignKey'], $linkAlias);
|
|
||||||
if (empty($referenceLink) && isset($Link->belongsTo[$Reference->alias]))
|
|
||||||
$referenceLink = $Link->escapeField($Link->belongsTo[$Reference->alias]['foreignKey'], $linkAlias);
|
|
||||||
|
|
||||||
// We're running quite thin here. None of the models spell
|
|
||||||
// out the appropriate linkages. We'll have to SWAG it.
|
|
||||||
if (empty($modelLink))
|
|
||||||
$modelLink = $Link->escapeField(Inflector::underscore($_Model->alias) . '_id', $linkAlias);
|
|
||||||
if (empty($referenceLink))
|
|
||||||
$referenceLink = $Link->escapeField(Inflector::underscore($Reference->alias) . '_id', $linkAlias);
|
|
||||||
|
|
||||||
// Get the primary key from the tables we're joining.
|
|
||||||
$referenceKey = $Reference->escapeField();
|
|
||||||
$modelKey = $_Model->escapeField();
|
|
||||||
|
|
||||||
// Join the linkage table to our model. We'll use an inner join,
|
|
||||||
// as the whole purpose of the linkage table is to make this
|
|
||||||
// connection. As we are embedding this join, the INNER will not
|
|
||||||
// cause any problem with the overall query, should the user not
|
|
||||||
// be concerned with whether or not the join has any results.
|
|
||||||
// They control that with the 'type' parameter which will be at
|
|
||||||
// the top level join.
|
|
||||||
$options['joins'][] = array('type' => 'INNER',
|
|
||||||
'alias' => $options['alias'],
|
|
||||||
'conditions' => "{$modelKey} = {$modelLink}",
|
|
||||||
'table' => $db->fullTableName($_Model, true));
|
|
||||||
|
|
||||||
// The user may have specified conditions directly in the model
|
|
||||||
// for this join. Make sure to adhere to those conditions.
|
|
||||||
if (isset($association['conditions']) && is_array($association['conditions']))
|
|
||||||
$options['conditions'] = $association['conditions'];
|
|
||||||
elseif (!empty($association['conditions']))
|
|
||||||
$options['conditions'] = array($association['conditions']);
|
|
||||||
|
|
||||||
// Now for the top level join. This will be added into the list
|
|
||||||
// of joins down below, outside of the HABTM specific code.
|
|
||||||
$options['alias'] = $linkAlias;
|
|
||||||
$options['table'] = $Link->getDataSource()->fullTableName($Link);
|
|
||||||
$options['conditions'][] = "{$referenceLink} = {$referenceKey}";
|
|
||||||
} else {
|
|
||||||
$referenceKey = $Reference->escapeField($association['foreignKey']);
|
|
||||||
$modelKey = $_Model->escapeField($_Model->primaryKey);
|
|
||||||
$options['conditions'] = "{$modelKey} = {$referenceKey}";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($associatedThroughReference)
|
||||||
|
$associationAlias = $referenceAlias;
|
||||||
|
else
|
||||||
|
$associationAlias = $modelAlias;
|
||||||
|
|
||||||
|
$this->recursive_array_replace("%{MODEL_ALIAS}",
|
||||||
|
$associationAlias,
|
||||||
|
$association['conditions']);
|
||||||
|
|
||||||
|
$this->pr(15,
|
||||||
|
array('checkpoint' => 'Models Established - Check Associations',
|
||||||
|
'primaryModel' => $primaryAlias .' : '. $primaryModel->name,
|
||||||
|
'foreignModel' => $foreignAlias .' : '. $foreignModel->name,
|
||||||
|
compact('type', 'association'),
|
||||||
|
));
|
||||||
|
|
||||||
|
if ($type === 'hasAndBelongsToMany') {
|
||||||
|
if (isset($association['with']))
|
||||||
|
$linkClass = $association['with'];
|
||||||
|
else
|
||||||
|
$linkClass = Inflector::classify($association['joinTable']);
|
||||||
|
|
||||||
|
$Link =& $_Model->{$linkClass};
|
||||||
|
|
||||||
|
if (isset($options['linkalias']))
|
||||||
|
$linkAlias = $options['linkalias'];
|
||||||
|
else
|
||||||
|
$linkAlias = $Link->alias;
|
||||||
|
|
||||||
|
$this->pr(17,
|
||||||
|
array('checkpoint' => 'Linking HABTM',
|
||||||
|
compact('linkClass', 'linkAlias'),
|
||||||
|
));
|
||||||
|
|
||||||
|
// Get the foreign key fields (for the link table) directly from
|
||||||
|
// the defined model associations, if they exists. This is the
|
||||||
|
// users direct specification, and therefore definitive if present.
|
||||||
|
$modelLink = $Link->escapeField($association['foreignKey'], $linkAlias);
|
||||||
|
$referenceLink = $Link->escapeField($association['associationForeignKey'], $linkAlias);
|
||||||
|
|
||||||
|
// If we haven't figured out the foreign keys, see if there is a
|
||||||
|
// model for the link table, and if it has the appropriate
|
||||||
|
// associations with the two tables we're trying to join.
|
||||||
|
if (empty($modelLink) && isset($Link->belongsTo[$_Model->alias]))
|
||||||
|
$modelLink = $Link->escapeField($Link->belongsTo[$_Model->alias]['foreignKey'], $linkAlias);
|
||||||
|
if (empty($referenceLink) && isset($Link->belongsTo[$Reference->alias]))
|
||||||
|
$referenceLink = $Link->escapeField($Link->belongsTo[$Reference->alias]['foreignKey'], $linkAlias);
|
||||||
|
|
||||||
|
// We're running quite thin here. None of the models spell
|
||||||
|
// out the appropriate linkages. We'll have to SWAG it.
|
||||||
|
if (empty($modelLink))
|
||||||
|
$modelLink = $Link->escapeField(Inflector::underscore($_Model->alias) . '_id', $linkAlias);
|
||||||
|
if (empty($referenceLink))
|
||||||
|
$referenceLink = $Link->escapeField(Inflector::underscore($Reference->alias) . '_id', $linkAlias);
|
||||||
|
|
||||||
|
// Get the primary key from the tables we're joining.
|
||||||
|
$referenceKey = $Reference->escapeField(null, $referenceAlias);
|
||||||
|
$modelKey = $_Model->escapeField(null, $modelAlias);
|
||||||
|
|
||||||
|
// Join the linkage table to our model. We'll use an inner join,
|
||||||
|
// as the whole purpose of the linkage table is to make this
|
||||||
|
// connection. As we are embedding this join, the INNER will not
|
||||||
|
// cause any problem with the overall query, should the user not
|
||||||
|
// be concerned with whether or not the join has any results.
|
||||||
|
// They control that with the 'type' parameter which will be at
|
||||||
|
// the top level join.
|
||||||
|
$options['joins'][] = array('type' => 'INNER',
|
||||||
|
'alias' => $modelAlias,
|
||||||
|
'conditions' => "{$modelKey} = {$modelLink}",
|
||||||
|
'table' => $db->fullTableName($_Model, true));
|
||||||
|
|
||||||
|
// Now for the top level join. This will be added into the list
|
||||||
|
// of joins down below, outside of the HABTM specific code.
|
||||||
|
$options['class'] = $linkClass;
|
||||||
|
$options['alias'] = $linkAlias;
|
||||||
|
$options['table'] = $Link->getDataSource()->fullTableName($Link);
|
||||||
|
$options['conditions'][] = "{$referenceLink} = {$referenceKey}";
|
||||||
|
}
|
||||||
|
elseif (isset($association['foreignKey']) && $association['foreignKey']) {
|
||||||
|
$foreignKey = $primaryModel->escapeField($association['foreignKey'], $primaryAlias);
|
||||||
|
$primaryKey = $foreignModel->escapeField($foreignModel->primaryKey, $foreignAlias);
|
||||||
|
|
||||||
|
$this->pr(17,
|
||||||
|
array('checkpoint' => 'Linking due to foreignKey',
|
||||||
|
compact('foreignKey', 'primaryKey'),
|
||||||
|
));
|
||||||
|
|
||||||
|
// Only differentiating to help show the logical flow.
|
||||||
|
// Either way works and this test can be tossed out
|
||||||
|
if (($type === 'hasMany' || $type === 'hasOne') ^ $associatedThroughReference)
|
||||||
|
$options['conditions'][] = "{$primaryKey} = {$foreignKey}";
|
||||||
|
else
|
||||||
|
$options['conditions'][] = "{$foreignKey} = {$primaryKey}";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$this->pr(17,
|
||||||
|
array('checkpoint' => 'Linking with no logic (expecting user defined)',
|
||||||
|
));
|
||||||
|
|
||||||
|
// No Foreign Key... nothing we can do.
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->pr(19,
|
||||||
|
array('checkpoint' => 'Conditions',
|
||||||
|
array('options[conditions]' => $options['conditions'],
|
||||||
|
'association[conditions]' => $association['conditions'],
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
// The user may have specified conditions directly in the model
|
||||||
|
// for this join. Make sure to adhere to those conditions.
|
||||||
|
if (isset($association['conditions']) && is_array($association['conditions']))
|
||||||
|
$options['conditions'] = array_merge($options['conditions'], $association['conditions']);
|
||||||
|
elseif (!empty($association['conditions']))
|
||||||
|
$options['conditions'][] = $association['conditions'];
|
||||||
|
|
||||||
|
$this->pr(19,
|
||||||
|
array('checkpoint' => 'Conditions2',
|
||||||
|
array('options[conditions]' => $options['conditions'],
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
if (empty($options['table'])) {
|
if (empty($options['table'])) {
|
||||||
$options['table'] = $db->fullTableName($_Model, true);
|
$options['table'] = $db->fullTableName($_Model, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isset($options['fields']) || !is_array($options['fields']))
|
if (!isset($options['fields']) || !is_array($options['fields']))
|
||||||
$options['fields'] = $db->fields($_Model);
|
$options['fields'] = $db->fields($_Model, $modelAlias);
|
||||||
elseif (!empty($options['fields']))
|
elseif (!empty($options['fields']))
|
||||||
$options['fields'] = $db->fields($_Model, null, $options['fields']);
|
$options['fields'] = $db->fields($_Model, $modelAlias, $options['fields']);
|
||||||
|
|
||||||
$query['fields'] = array_merge($query['fields'], $options['fields'],
|
$query['fields'] = array_merge($query['fields'], $options['fields'],
|
||||||
(empty($association['fields'])
|
(empty($association['fields'])
|
||||||
? array() : $db->fields($_Model, null, $association['fields'])));
|
? array() : $db->fields($_Model, $modelAlias, $association['fields'])));
|
||||||
|
|
||||||
|
|
||||||
$options[$this->_key] = am($options[$this->_key], array_diff_key($options, $optionsKeys));
|
$options[$this->_key] = am($options[$this->_key], array_diff_key($options, $optionsKeys));
|
||||||
$options = array_intersect_key($options, $optionsKeys);
|
$options = array_intersect_key($options, $optionsKeys);
|
||||||
if (!empty($options[$this->_key])) {
|
if (!empty($options[$this->_key])) {
|
||||||
$iterators[] = $options[$this->_key] + array('defaults' => array_merge($defaults, array('reference' => $options['class'])));
|
$iterators[] = $options[$this->_key] +
|
||||||
|
array('defaults' =>
|
||||||
|
array_merge($defaults,
|
||||||
|
array('reference' =>
|
||||||
|
array('class' => $modelClass,
|
||||||
|
'alias' => $modelAlias))));
|
||||||
}
|
}
|
||||||
$query['joins'][] = array_intersect_key($options, array('type' => true, 'alias' => true, 'table' => true, 'joins' => true, 'conditions' => true));
|
$query['joins'][] = array_intersect_key($options, array('type' => true, 'alias' => true, 'table' => true, 'joins' => true, 'conditions' => true));
|
||||||
|
|
||||||
|
$this->pr(19,
|
||||||
|
array('checkpoint' => 'Model Join Complete',
|
||||||
|
compact('options', 'modelClass', 'modelAlias', 'query'),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
++$cont;
|
++$cont;
|
||||||
$notDone = isset($iterators[$cont]);
|
$notDone = isset($iterators[$cont]);
|
||||||
} while ($notDone);
|
} while ($notDone);
|
||||||
}
|
}
|
||||||
/* pr("Linkable::beforeFind() end"); pr($query); */
|
$this->pr(20,
|
||||||
|
array('function' => 'Linkable::beforeFind',
|
||||||
|
'return' => compact('query'),
|
||||||
|
));
|
||||||
return $query;
|
return $query;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
<?php
|
|
||||||
class Charge extends AppModel {
|
|
||||||
|
|
||||||
var $name = 'Charge';
|
|
||||||
var $validate = array(
|
|
||||||
'id' => array('numeric'),
|
|
||||||
'charge_type_id' => array('numeric'),
|
|
||||||
'lease_id' => array('numeric'),
|
|
||||||
'charge_date' => array('date'),
|
|
||||||
'charge_to_date' => array('date'),
|
|
||||||
'due_date' => array('date'),
|
|
||||||
'amount' => array('money'),
|
|
||||||
'tax' => array('money'),
|
|
||||||
'total' => array('money')
|
|
||||||
);
|
|
||||||
|
|
||||||
var $belongsTo = array(
|
|
||||||
'ChargeType' => array(
|
|
||||||
'className' => 'ChargeType',
|
|
||||||
'foreignKey' => 'charge_type_id',
|
|
||||||
'conditions' => '',
|
|
||||||
'fields' => '',
|
|
||||||
'order' => ''
|
|
||||||
),
|
|
||||||
'Lease' => array(
|
|
||||||
'className' => 'Lease',
|
|
||||||
'foreignKey' => 'lease_id',
|
|
||||||
'conditions' => '',
|
|
||||||
'fields' => '',
|
|
||||||
'order' => ''
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
var $hasAndBelongsToMany = array(
|
|
||||||
'Receipt' => array(
|
|
||||||
'className' => 'Receipt',
|
|
||||||
'joinTable' => 'charges_receipts',
|
|
||||||
'foreignKey' => 'charge_id',
|
|
||||||
'associationForeignKey' => 'receipt_id',
|
|
||||||
'unique' => true,
|
|
||||||
'conditions' => '',
|
|
||||||
'fields' => '',
|
|
||||||
'order' => '',
|
|
||||||
'limit' => '',
|
|
||||||
'offset' => '',
|
|
||||||
'finderQuery' => '',
|
|
||||||
'deleteQuery' => '',
|
|
||||||
'insertQuery' => ''
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
<?php
|
|
||||||
class ChargeType extends AppModel {
|
|
||||||
|
|
||||||
var $name = 'ChargeType';
|
|
||||||
var $validate = array(
|
|
||||||
'id' => array('numeric'),
|
|
||||||
'name' => array('notempty'),
|
|
||||||
'account_id' => array('numeric')
|
|
||||||
);
|
|
||||||
|
|
||||||
//The Associations below have been created with all possible keys, those that are not needed can be removed
|
|
||||||
/* var $belongsTo = array( */
|
|
||||||
/* 'Account' => array( */
|
|
||||||
/* 'className' => 'Account', */
|
|
||||||
/* 'foreignKey' => 'account_id', */
|
|
||||||
/* 'conditions' => '', */
|
|
||||||
/* 'fields' => '', */
|
|
||||||
/* 'order' => '' */
|
|
||||||
/* ) */
|
|
||||||
/* ); */
|
|
||||||
|
|
||||||
var $hasMany = array(
|
|
||||||
'Charge' => array(
|
|
||||||
'className' => 'Charge',
|
|
||||||
'foreignKey' => 'charge_type_id',
|
|
||||||
'dependent' => false,
|
|
||||||
'conditions' => '',
|
|
||||||
'fields' => '',
|
|
||||||
'order' => '',
|
|
||||||
'limit' => '',
|
|
||||||
'offset' => '',
|
|
||||||
'exclusive' => '',
|
|
||||||
'finderQuery' => '',
|
|
||||||
'counterQuery' => ''
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
12
site/models/close.php
Normal file
12
site/models/close.php
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
class Close extends AppModel {
|
||||||
|
|
||||||
|
var $belongsTo = array(
|
||||||
|
);
|
||||||
|
|
||||||
|
var $hasMany = array(
|
||||||
|
'Ledger',
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
class Contact extends AppModel {
|
class Contact extends AppModel {
|
||||||
|
|
||||||
var $name = 'Contact';
|
var $displayField = 'display_name';
|
||||||
|
|
||||||
var $validate = array(
|
var $validate = array(
|
||||||
'id' => array('numeric'),
|
'id' => array('numeric'),
|
||||||
'display_name' => array('notempty'),
|
'display_name' => array('notempty'),
|
||||||
@@ -9,68 +10,127 @@ class Contact extends AppModel {
|
|||||||
'id_exp' => array('date')
|
'id_exp' => array('date')
|
||||||
);
|
);
|
||||||
|
|
||||||
|
var $hasMany = array(
|
||||||
|
'ContactsMethod',
|
||||||
|
'ContactsCustomer',
|
||||||
|
);
|
||||||
|
|
||||||
var $hasAndBelongsToMany = array(
|
var $hasAndBelongsToMany = array(
|
||||||
'Lease' => array(
|
'Customer',
|
||||||
'className' => 'Lease',
|
|
||||||
'joinTable' => 'contacts_leases',
|
|
||||||
'foreignKey' => 'contact_id',
|
|
||||||
'associationForeignKey' => 'lease_id',
|
|
||||||
'unique' => true,
|
|
||||||
'conditions' => '',
|
|
||||||
'fields' => '',
|
|
||||||
'order' => '',
|
|
||||||
'limit' => '',
|
|
||||||
'offset' => '',
|
|
||||||
'finderQuery' => '',
|
|
||||||
'deleteQuery' => '',
|
|
||||||
'insertQuery' => ''
|
|
||||||
),
|
|
||||||
'ContactAddress' => array(
|
'ContactAddress' => array(
|
||||||
'className' => 'ContactAddress',
|
|
||||||
'joinTable' => 'contacts_methods',
|
'joinTable' => 'contacts_methods',
|
||||||
'foreignKey' => 'contact_id',
|
|
||||||
'associationForeignKey' => 'method_id',
|
'associationForeignKey' => 'method_id',
|
||||||
'unique' => true,
|
'unique' => true,
|
||||||
'conditions' => "method = 'POST'",
|
'conditions' => "method = 'ADDRESS'",
|
||||||
'fields' => '',
|
|
||||||
'order' => '',
|
|
||||||
'limit' => '',
|
|
||||||
'offset' => '',
|
|
||||||
'finderQuery' => '',
|
|
||||||
'deleteQuery' => '',
|
|
||||||
'insertQuery' => ''
|
|
||||||
),
|
),
|
||||||
'ContactPhone' => array(
|
'ContactPhone' => array(
|
||||||
'className' => 'ContactPhone',
|
|
||||||
'joinTable' => 'contacts_methods',
|
'joinTable' => 'contacts_methods',
|
||||||
'foreignKey' => 'contact_id',
|
|
||||||
'associationForeignKey' => 'method_id',
|
'associationForeignKey' => 'method_id',
|
||||||
'unique' => true,
|
'unique' => true,
|
||||||
'conditions' => "method = 'PHONE'",
|
'conditions' => "method = 'PHONE'",
|
||||||
'fields' => '',
|
|
||||||
'order' => '',
|
|
||||||
'limit' => '',
|
|
||||||
'offset' => '',
|
|
||||||
'finderQuery' => '',
|
|
||||||
'deleteQuery' => '',
|
|
||||||
'insertQuery' => ''
|
|
||||||
),
|
),
|
||||||
'ContactEmail' => array(
|
'ContactEmail' => array(
|
||||||
'className' => 'ContactEmail',
|
|
||||||
'joinTable' => 'contacts_methods',
|
'joinTable' => 'contacts_methods',
|
||||||
'foreignKey' => 'contact_id',
|
|
||||||
'associationForeignKey' => 'method_id',
|
'associationForeignKey' => 'method_id',
|
||||||
'unique' => true,
|
'unique' => true,
|
||||||
'conditions' => "method = 'EMAIL'",
|
'conditions' => "method = 'EMAIL'",
|
||||||
'fields' => '',
|
|
||||||
'order' => '',
|
|
||||||
'limit' => '',
|
|
||||||
'offset' => '',
|
|
||||||
'finderQuery' => '',
|
|
||||||
'deleteQuery' => '',
|
|
||||||
'insertQuery' => ''
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: saveContact
|
||||||
|
* - Saves the contact and related data
|
||||||
|
*/
|
||||||
|
|
||||||
|
function saveContact($id, $data) {
|
||||||
|
|
||||||
|
// Establish a display name if not already given
|
||||||
|
if (!$data['Contact']['display_name'])
|
||||||
|
$data['Contact']['display_name'] =
|
||||||
|
(($data['Contact']['first_name'] &&
|
||||||
|
$data['Contact']['last_name'])
|
||||||
|
? $data['Contact']['last_name'] . ', ' . $data['Contact']['first_name']
|
||||||
|
: ($data['Contact']['first_name']
|
||||||
|
? $data['Contact']['first_name']
|
||||||
|
: $data['Contact']['last_name']));
|
||||||
|
|
||||||
|
// Save the contact data
|
||||||
|
$this->create();
|
||||||
|
if ($id)
|
||||||
|
$this->id = $id;
|
||||||
|
if (!$this->save($data, false)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$id = $this->id;
|
||||||
|
|
||||||
|
// Remove all associated ContactMethods, as it ensures
|
||||||
|
// any entries deleted by the user actually get deleted
|
||||||
|
// in the system. We'll recreate the needed ones anyway.
|
||||||
|
// REVISIT <AP>: 20090706
|
||||||
|
// Appears that $this->save() is already doing the
|
||||||
|
// delete. I would have thought this would only happen
|
||||||
|
// on a saveAll??
|
||||||
|
/* $this->ContactsMethod->deleteAll */
|
||||||
|
/* (array('contact_id' => $id), false); */
|
||||||
|
|
||||||
|
// At this point, since we've saved data to contact,
|
||||||
|
// we'll proceed forward as much as possible, even
|
||||||
|
// if we encounter an error. For now, we'll assume
|
||||||
|
// the operation will succeed.
|
||||||
|
$ret = true;
|
||||||
|
|
||||||
|
// Iterate each type of contact method, adding them into
|
||||||
|
// the database as needed and associating with this contact.
|
||||||
|
foreach (array('phone', 'address', 'email') AS $type) {
|
||||||
|
$class = 'Contact' . ucfirst($type);
|
||||||
|
$enum = strtoupper($type);
|
||||||
|
|
||||||
|
// Nothing to do if this contact method isn't used
|
||||||
|
if (!isset($data[$class]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Go through each entry of this contact method
|
||||||
|
foreach ($data[$class] AS &$item) {
|
||||||
|
|
||||||
|
// If the user has entered all new data, we need to
|
||||||
|
// save that as a brand new entry.
|
||||||
|
if (!isset($item['id'])) {
|
||||||
|
$I = new $class();
|
||||||
|
$I->create();
|
||||||
|
if (!$I->save($item, false)) {
|
||||||
|
$ret = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$item['id'] = $I->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the ContactsMethod to reflect the appropriate IDs
|
||||||
|
$item['ContactsMethod']['contact_id'] = $id;
|
||||||
|
$item['ContactsMethod']['method_id'] = $item['id'];
|
||||||
|
$item['ContactsMethod']['method'] = $enum;
|
||||||
|
|
||||||
|
// Save the relationship between contact and phone/email/address
|
||||||
|
$CM = new ContactsMethod();
|
||||||
|
if (!$CM->save($item['ContactsMethod'], false)) {
|
||||||
|
$ret = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the result
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function contactList() {
|
||||||
|
return $this->find('list',
|
||||||
|
array('order' =>
|
||||||
|
//array('last_name', 'first_name', 'middle_name'),
|
||||||
|
array('display_name'),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
@@ -7,6 +7,13 @@ class ContactAddress extends AppModel {
|
|||||||
'postcode' => array('postal')
|
'postcode' => array('postal')
|
||||||
);
|
);
|
||||||
|
|
||||||
|
var $hasMany = array(
|
||||||
|
'ContactsMethod' => array(
|
||||||
|
'foreignKey' => 'method_id',
|
||||||
|
'conditions' => "method = 'ADDRESS'",
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
var $hasAndBelongsToMany = array(
|
var $hasAndBelongsToMany = array(
|
||||||
'Contact' => array(
|
'Contact' => array(
|
||||||
'className' => 'Contact',
|
'className' => 'Contact',
|
||||||
@@ -14,15 +21,26 @@ class ContactAddress extends AppModel {
|
|||||||
'foreignKey' => 'method_id',
|
'foreignKey' => 'method_id',
|
||||||
'associationForeignKey' => 'contact_id',
|
'associationForeignKey' => 'contact_id',
|
||||||
'unique' => true,
|
'unique' => true,
|
||||||
'conditions' => "method = 'POST'",
|
'conditions' => "method = 'ADDRESS'",
|
||||||
'fields' => '',
|
|
||||||
'order' => '',
|
|
||||||
'limit' => '',
|
|
||||||
'offset' => '',
|
|
||||||
'finderQuery' => '',
|
|
||||||
'deleteQuery' => '',
|
|
||||||
'insertQuery' => ''
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
function addressList() {
|
||||||
|
$results = $this->find('all',
|
||||||
|
array('contain' => false,
|
||||||
|
'fields' => array('id', 'address', 'city', 'state', 'postcode'),
|
||||||
|
'order' => array('state', 'city', 'postcode', 'address')));
|
||||||
|
|
||||||
|
$list = array();
|
||||||
|
foreach ($results as $key => $val) {
|
||||||
|
$list[$val['ContactAddress']['id']]
|
||||||
|
= preg_replace("/\n/", ", ", $val['ContactAddress']['address'])
|
||||||
|
. ', ' . $val['ContactAddress']['city']
|
||||||
|
. ', ' . $val['ContactAddress']['state']
|
||||||
|
. ' ' . $val['ContactAddress']['postcode']
|
||||||
|
;
|
||||||
|
}
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
class ContactEmail extends AppModel {
|
class ContactEmail extends AppModel {
|
||||||
|
|
||||||
var $name = 'ContactEmail';
|
var $name = 'ContactEmail';
|
||||||
|
var $displayField = 'email';
|
||||||
var $validate = array(
|
var $validate = array(
|
||||||
'id' => array('numeric'),
|
'id' => array('numeric'),
|
||||||
'email' => array('email')
|
'email' => array('email')
|
||||||
@@ -15,15 +16,12 @@ class ContactEmail extends AppModel {
|
|||||||
'associationForeignKey' => 'contact_id',
|
'associationForeignKey' => 'contact_id',
|
||||||
'unique' => true,
|
'unique' => true,
|
||||||
'conditions' => "method = 'EMAIL'",
|
'conditions' => "method = 'EMAIL'",
|
||||||
'fields' => '',
|
|
||||||
'order' => '',
|
|
||||||
'limit' => '',
|
|
||||||
'offset' => '',
|
|
||||||
'finderQuery' => '',
|
|
||||||
'deleteQuery' => '',
|
|
||||||
'insertQuery' => ''
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
function emailList() {
|
||||||
|
return $this->find('list');
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class ContactPhone extends AppModel {
|
class ContactPhone extends AppModel {
|
||||||
|
|
||||||
var $name = 'ContactPhone';
|
|
||||||
var $validate = array(
|
var $validate = array(
|
||||||
'id' => array('numeric'),
|
'id' => array('numeric'),
|
||||||
//'type' => array('inlist'),
|
//'type' => array('inlist'),
|
||||||
@@ -9,6 +8,13 @@ class ContactPhone extends AppModel {
|
|||||||
'ext' => array('numeric')
|
'ext' => array('numeric')
|
||||||
);
|
);
|
||||||
|
|
||||||
|
var $hasMany = array(
|
||||||
|
'ContactsMethod' => array(
|
||||||
|
'foreignKey' => 'method_id',
|
||||||
|
'conditions' => "method = 'PHONE'",
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
var $hasAndBelongsToMany = array(
|
var $hasAndBelongsToMany = array(
|
||||||
'Contact' => array(
|
'Contact' => array(
|
||||||
'className' => 'Contact',
|
'className' => 'Contact',
|
||||||
@@ -17,15 +23,24 @@ class ContactPhone extends AppModel {
|
|||||||
'associationForeignKey' => 'contact_id',
|
'associationForeignKey' => 'contact_id',
|
||||||
'unique' => true,
|
'unique' => true,
|
||||||
'conditions' => "method = 'PHONE'",
|
'conditions' => "method = 'PHONE'",
|
||||||
'fields' => '',
|
|
||||||
'order' => '',
|
|
||||||
'limit' => '',
|
|
||||||
'offset' => '',
|
|
||||||
'finderQuery' => '',
|
|
||||||
'deleteQuery' => '',
|
|
||||||
'insertQuery' => ''
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
function phoneList() {
|
||||||
|
$results = $this->find('all',
|
||||||
|
array('contain' => false,
|
||||||
|
'fields' => array('id', 'phone', 'ext'),
|
||||||
|
'order' => array('phone', 'ext')));
|
||||||
|
|
||||||
|
App::Import('Helper', 'Format');
|
||||||
|
$list = array();
|
||||||
|
foreach ($results as $key => $val) {
|
||||||
|
$list[$val['ContactPhone']['id']]
|
||||||
|
= FormatHelper::phone($val['ContactPhone']['phone'],
|
||||||
|
$val['ContactPhone']['ext']);
|
||||||
|
}
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
11
site/models/contacts_customer.php
Normal file
11
site/models/contacts_customer.php
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
class ContactsCustomer extends AppModel {
|
||||||
|
var $primaryKey = false;
|
||||||
|
|
||||||
|
var $belongsTo = array(
|
||||||
|
'Contact',
|
||||||
|
'Customer',
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
25
site/models/contacts_method.php
Normal file
25
site/models/contacts_method.php
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
class ContactsMethod extends AppModel {
|
||||||
|
var $primaryKey = false;
|
||||||
|
|
||||||
|
var $belongsTo = array(
|
||||||
|
'Contact',
|
||||||
|
'ContactAddress' => array(
|
||||||
|
'foreignKey' => 'method_id',
|
||||||
|
'conditions' => "method = 'ADDRESS'",
|
||||||
|
//'unique' => true,
|
||||||
|
),
|
||||||
|
'ContactPhone' => array(
|
||||||
|
'foreignKey' => 'method_id',
|
||||||
|
'conditions' => "method = 'PHONE'",
|
||||||
|
//'unique' => true,
|
||||||
|
),
|
||||||
|
'ContactEmail' => array(
|
||||||
|
'foreignKey' => 'method_id',
|
||||||
|
'conditions' => "method = 'EMAIL'",
|
||||||
|
//'unique' => true,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
285
site/models/customer.php
Normal file
285
site/models/customer.php
Normal file
@@ -0,0 +1,285 @@
|
|||||||
|
<?php
|
||||||
|
class Customer extends AppModel {
|
||||||
|
|
||||||
|
var $name = 'Customer';
|
||||||
|
var $validate = array(
|
||||||
|
'id' => array('numeric'),
|
||||||
|
'name' => array('notempty'),
|
||||||
|
);
|
||||||
|
|
||||||
|
var $belongsTo = array(
|
||||||
|
'PrimaryContact' => array(
|
||||||
|
'className' => 'Contact',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
var $hasMany = array(
|
||||||
|
'CurrentLease' => array(
|
||||||
|
'className' => 'Lease',
|
||||||
|
'conditions' => 'CurrentLease.close_date IS NULL',
|
||||||
|
),
|
||||||
|
'Lease',
|
||||||
|
'LedgerEntry',
|
||||||
|
'ContactsCustomer',
|
||||||
|
);
|
||||||
|
|
||||||
|
var $hasAndBelongsToMany = array(
|
||||||
|
'Contact',
|
||||||
|
'Transaction' => array(
|
||||||
|
'joinTable' => 'ledger_entries',
|
||||||
|
'foreignKey' => 'customer_id',
|
||||||
|
'associationForeignKey' => 'transaction_id',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: accountId
|
||||||
|
* - Returns the account ID for the given customer
|
||||||
|
*/
|
||||||
|
function accountId($id) {
|
||||||
|
$this->cacheQueries = true;
|
||||||
|
$customer = $this->find('first',
|
||||||
|
array('contain' => false,
|
||||||
|
'fields' => array('account_id'),
|
||||||
|
'conditions' => array(array('Customer.id' => $id))));
|
||||||
|
$this->cacheQueries = false;
|
||||||
|
|
||||||
|
return $customer['Customer']['account_id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: leaseIds
|
||||||
|
* - Returns the lease IDs for the given customer
|
||||||
|
*/
|
||||||
|
function leaseIds($id) {
|
||||||
|
$this->cacheQueries = true;
|
||||||
|
$customer = $this->find('first',
|
||||||
|
array('contain' =>
|
||||||
|
array('Lease' => array('fields' => array('id'))),
|
||||||
|
'fields' => array(),
|
||||||
|
'conditions' => array(array('Customer.id' => $id))));
|
||||||
|
$this->cacheQueries = false;
|
||||||
|
|
||||||
|
$ids = array();
|
||||||
|
foreach ($customer['Lease'] AS $lease)
|
||||||
|
$ids[] = $lease['id'];
|
||||||
|
|
||||||
|
return $ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: findSecurityDeposits
|
||||||
|
* - Returns an array of security deposit entries
|
||||||
|
*/
|
||||||
|
function findSecurityDeposits($id, $link = null) {
|
||||||
|
/* pr(array('function' => 'Customer::findSecurityDeposits', */
|
||||||
|
/* 'args' => compact('id', 'link'), */
|
||||||
|
/* )); */
|
||||||
|
|
||||||
|
$A = new Account();
|
||||||
|
$entries = $A->findLedgerEntries
|
||||||
|
($A->securityDepositAccountID(),
|
||||||
|
true, array('LedgerEntry.customer_id' => $id), $link);
|
||||||
|
|
||||||
|
/* pr(array('function' => 'Customer::findSecurityDeposits', */
|
||||||
|
/* 'args' => compact('id', 'link'), */
|
||||||
|
/* 'vars' => compact('customer'), */
|
||||||
|
/* 'return' => compact('entries'), */
|
||||||
|
/* )); */
|
||||||
|
|
||||||
|
return $entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: findUnreconciledLedgerEntries
|
||||||
|
* - Returns ledger entries that are not yet reconciled
|
||||||
|
* (such as charges not paid).
|
||||||
|
*/
|
||||||
|
|
||||||
|
function findUnreconciledLedgerEntries($id = null, $fundamental_type = null) {
|
||||||
|
$A = new Account();
|
||||||
|
$unreconciled = $A->findUnreconciledLedgerEntries
|
||||||
|
($A->accountReceivableAccountID(),
|
||||||
|
$fundamental_type,
|
||||||
|
array('LedgerEntry.customer_id' => $id));
|
||||||
|
|
||||||
|
return $unreconciled;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: reconcileNewLedgerEntry
|
||||||
|
* - Returns which ledger entries a new credit/debit would
|
||||||
|
* reconcile, and how much.
|
||||||
|
*
|
||||||
|
* - REVISIT <AP> 20090617
|
||||||
|
* This should be subject to different algorithms, such
|
||||||
|
* as apply to oldest charges first, newest first, to fees
|
||||||
|
* before rent, etc. Until we get there, I'll hardcode
|
||||||
|
* whatever algorithm is simplest.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function reconcileNewLedgerEntry($id, $fundamental_type, $amount) {
|
||||||
|
$A = new Account();
|
||||||
|
$reconciled = $A->reconcileNewLedgerEntry
|
||||||
|
($A->accountReceivableAccountID(),
|
||||||
|
$fundamental_type,
|
||||||
|
$amount,
|
||||||
|
array('LedgerEntry.customer_id' => $id));
|
||||||
|
|
||||||
|
return $reconciled;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: details
|
||||||
|
* - Returns detail information for the customer
|
||||||
|
*/
|
||||||
|
|
||||||
|
function details($id = null) {
|
||||||
|
// Query the DB for need information.
|
||||||
|
$customer = $this->find
|
||||||
|
('first', array
|
||||||
|
('contain' => array
|
||||||
|
(// Models
|
||||||
|
'Contact' =>
|
||||||
|
array('order' => array('Contact.display_name'),
|
||||||
|
// Models
|
||||||
|
'ContactPhone',
|
||||||
|
'ContactEmail',
|
||||||
|
'ContactAddress',
|
||||||
|
),
|
||||||
|
'Lease' =>
|
||||||
|
array('Unit' =>
|
||||||
|
array('order' => array('sort_order'),
|
||||||
|
'fields' => array('id', 'name'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
'conditions' => array('Customer.id' => $id),
|
||||||
|
));
|
||||||
|
|
||||||
|
// Figure out the outstanding balance for this customer
|
||||||
|
$customer['stats'] = $this->stats($id);
|
||||||
|
|
||||||
|
// Figure out the total security deposit for the current lease.
|
||||||
|
$customer['deposits'] = $this->findSecurityDeposits($id);
|
||||||
|
|
||||||
|
return $customer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: saveCustomer
|
||||||
|
* - Saves the customer and related data
|
||||||
|
*/
|
||||||
|
|
||||||
|
function saveCustomer($id, $data, $primary_contact_entry) {
|
||||||
|
|
||||||
|
// Go through each contact, and create new ones as needed
|
||||||
|
foreach ($data['Contact'] AS &$contact) {
|
||||||
|
if (isset($contact['id']))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
$I = new Contact();
|
||||||
|
$I->create();
|
||||||
|
if (!$I->save($contact, false)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$contact['id'] = $I->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the primary contact ID based on caller selection
|
||||||
|
$data['Customer']['primary_contact_id']
|
||||||
|
= $data['Contact'][$primary_contact_entry]['id'];
|
||||||
|
|
||||||
|
// Provide a default customer name if not specified
|
||||||
|
if (!$data['Customer']['name']) {
|
||||||
|
$this->Contact->recursive = -1;
|
||||||
|
$pcontact = $this->Contact->read(null, $data['Customer']['primary_contact_id']);
|
||||||
|
$data['Customer']['name'] = $pcontact['Contact']['display_name'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the customer data
|
||||||
|
$this->create();
|
||||||
|
if ($id)
|
||||||
|
$this->id = $id;
|
||||||
|
if (!$this->save($data, false)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$id = $this->id;
|
||||||
|
|
||||||
|
// Remove all associated Customer Contacts, as it ensures
|
||||||
|
// any entries deleted by the user actually get deleted
|
||||||
|
// in the system. We'll recreate the needed ones anyway.
|
||||||
|
// REVISIT <AP>: 20090706
|
||||||
|
// Appears that $this->save() is already doing the
|
||||||
|
// delete. I would have thought this would only happen
|
||||||
|
// on a saveAll??
|
||||||
|
/* $this->ContactsCustomer->deleteAll */
|
||||||
|
/* (array('customer_id' => $id), false); */
|
||||||
|
|
||||||
|
// At this point, since we've saved data to customer,
|
||||||
|
// we'll proceed forward as much as possible, even
|
||||||
|
// if we encounter an error. For now, we'll assume
|
||||||
|
// the operation will succeed.
|
||||||
|
$ret = true;
|
||||||
|
|
||||||
|
// Go through each entry of this customer method
|
||||||
|
foreach ($data['Contact'] AS &$contact) {
|
||||||
|
// Update the ContactsCustomer to reflect the appropriate IDs
|
||||||
|
$contact['ContactsCustomer']['customer_id'] = $id;
|
||||||
|
$contact['ContactsCustomer']['contact_id'] = $contact['id'];
|
||||||
|
|
||||||
|
// Save the relationship between customer and contact
|
||||||
|
$CM = new ContactsCustomer();
|
||||||
|
if (!$CM->save($contact['ContactsCustomer'], false)) {
|
||||||
|
$ret = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the result
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: stats
|
||||||
|
* - Returns summary data from the requested customer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function stats($id = null) {
|
||||||
|
if (!$id)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
$A = new Account();
|
||||||
|
$stats = $A->stats($A->accountReceivableAccountID(), true,
|
||||||
|
array('LedgerEntry.customer_id' => $id));
|
||||||
|
|
||||||
|
// Pull to the top level and return
|
||||||
|
$stats = $stats['Ledger'];
|
||||||
|
return $stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -9,77 +9,498 @@ class Lease extends AppModel {
|
|||||||
'unit_id' => array('numeric'),
|
'unit_id' => array('numeric'),
|
||||||
'late_schedule_id' => array('numeric'),
|
'late_schedule_id' => array('numeric'),
|
||||||
'lease_date' => array('date'),
|
'lease_date' => array('date'),
|
||||||
'movein_planed_date' => array('date'),
|
'movein_planned_date' => array('date'),
|
||||||
'movein_date' => array('date'),
|
'movein_date' => array('date'),
|
||||||
'moveout_date' => array('date'),
|
'moveout_date' => array('date'),
|
||||||
'moveout_planed_date' => array('date'),
|
'moveout_planned_date' => array('date'),
|
||||||
'notice_given_date' => array('date'),
|
'notice_given_date' => array('date'),
|
||||||
'notice_received_date' => array('date'),
|
'notice_received_date' => array('date'),
|
||||||
'close_date' => array('date'),
|
'close_date' => array('date'),
|
||||||
'deposit' => array('money'),
|
'deposit' => array('money'),
|
||||||
'amount' => array('money'),
|
'rent' => array('money'),
|
||||||
'next_amount' => array('money'),
|
'next_rent' => array('money'),
|
||||||
'next_amount_date' => array('date')
|
'next_rent_date' => array('date')
|
||||||
);
|
);
|
||||||
|
|
||||||
//The Associations below have been created with all possible keys, those that are not needed can be removed
|
|
||||||
var $belongsTo = array(
|
var $belongsTo = array(
|
||||||
'LeaseType' => array(
|
'LeaseType',
|
||||||
'className' => 'LeaseType',
|
'Unit',
|
||||||
'foreignKey' => 'lease_type_id',
|
'Customer',
|
||||||
'conditions' => '',
|
'LateSchedule',
|
||||||
'fields' => '',
|
|
||||||
'order' => ''
|
|
||||||
),
|
|
||||||
'Unit' => array(
|
|
||||||
'className' => 'Unit',
|
|
||||||
'foreignKey' => 'unit_id',
|
|
||||||
'conditions' => '',
|
|
||||||
'fields' => '',
|
|
||||||
'order' => ''
|
|
||||||
),
|
|
||||||
'LateSchedule' => array(
|
|
||||||
'className' => 'LateSchedule',
|
|
||||||
'foreignKey' => 'late_schedule_id',
|
|
||||||
'conditions' => '',
|
|
||||||
'fields' => '',
|
|
||||||
'order' => ''
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
var $hasMany = array(
|
var $hasMany = array(
|
||||||
'Charge' => array(
|
'LedgerEntry',
|
||||||
'className' => 'Charge',
|
|
||||||
'foreignKey' => 'lease_id',
|
|
||||||
'dependent' => false,
|
|
||||||
'conditions' => '',
|
|
||||||
'fields' => '',
|
|
||||||
'order' => '',
|
|
||||||
'limit' => '',
|
|
||||||
'offset' => '',
|
|
||||||
'exclusive' => '',
|
|
||||||
'finderQuery' => '',
|
|
||||||
'counterQuery' => ''
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
var $hasAndBelongsToMany = array(
|
|
||||||
'Contact' => array(
|
/**************************************************************************
|
||||||
'className' => 'Contact',
|
**************************************************************************
|
||||||
'joinTable' => 'contacts_leases',
|
**************************************************************************
|
||||||
'foreignKey' => 'lease_id',
|
* function: accountId
|
||||||
'associationForeignKey' => 'contact_id',
|
* - Returns the accountId of the given lease
|
||||||
'unique' => true,
|
*/
|
||||||
'conditions' => '',
|
function accountId($id) {
|
||||||
'fields' => '',
|
$A = new Account();
|
||||||
'order' => '',
|
return $A->invoiceAccountID();
|
||||||
'limit' => '',
|
}
|
||||||
'offset' => '',
|
|
||||||
'finderQuery' => '',
|
|
||||||
'deleteQuery' => '',
|
/**************************************************************************
|
||||||
'insertQuery' => ''
|
**************************************************************************
|
||||||
)
|
**************************************************************************
|
||||||
);
|
* function: findAccountEntries
|
||||||
|
* - Returns an array of ledger entries from the account of the given
|
||||||
|
* lease.
|
||||||
|
*/
|
||||||
|
function findAccountEntries($id, $all = false, $cond = null, $link = null) {
|
||||||
|
/* pr(array('function' => 'Lease::findAccountEntries', */
|
||||||
|
/* 'args' => compact('id', 'all', 'cond', 'link'), */
|
||||||
|
/* )); */
|
||||||
|
|
||||||
|
if (!isset($cond))
|
||||||
|
$cond = array();
|
||||||
|
$cond[] = array('LedgerEntry.lease_id' => $id);
|
||||||
|
|
||||||
|
$A = new Account();
|
||||||
|
$entries = $A->findLedgerEntries($this->accountId($id),
|
||||||
|
$all, $cond, $link);
|
||||||
|
|
||||||
|
/* pr(array('function' => 'Lease::findAccountEntries', */
|
||||||
|
/* 'args' => compact('id', 'all', 'cond', 'link'), */
|
||||||
|
/* 'vars' => compact('lease'), */
|
||||||
|
/* 'return' => compact('entries'), */
|
||||||
|
/* )); */
|
||||||
|
return $entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: findSecurityDeposits
|
||||||
|
* - Returns an array of security deposit entries
|
||||||
|
*/
|
||||||
|
function findSecurityDeposits($id, $link = null) {
|
||||||
|
/* pr(array('function' => 'Lease::findSecurityDeposits', */
|
||||||
|
/* 'args' => compact('id', 'link'), */
|
||||||
|
/* )); */
|
||||||
|
|
||||||
|
$A = new Account();
|
||||||
|
$entries = $A->findLedgerEntries
|
||||||
|
($A->securityDepositAccountID(),
|
||||||
|
true, array('LedgerEntry.lease_id' => $id), $link);
|
||||||
|
|
||||||
|
/* pr(array('function' => 'Lease::findSecurityDeposits', */
|
||||||
|
/* 'args' => compact('id', 'link'), */
|
||||||
|
/* 'vars' => compact('lease'), */
|
||||||
|
/* 'return' => compact('entries'), */
|
||||||
|
/* )); */
|
||||||
|
return $entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: findUnreconciledLedgerEntries
|
||||||
|
* - Returns ledger entries that are not yet reconciled
|
||||||
|
* (such as charges not paid).
|
||||||
|
*/
|
||||||
|
|
||||||
|
function findUnreconciledLedgerEntries($id = null, $fundamental_type = null) {
|
||||||
|
$A = new Account();
|
||||||
|
return $A->findUnreconciledLedgerEntries
|
||||||
|
($this->accountId($id), $fundamental_type, array('LedgerEntry.lease_id' => $id));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: reconcileNewLedgerEntry
|
||||||
|
* - Returns which ledger entries a new credit/debit would
|
||||||
|
* reconcile, and how much.
|
||||||
|
*
|
||||||
|
* - REVISIT <AP> 20090617
|
||||||
|
* This should be subject to different algorithms, such
|
||||||
|
* as apply to oldest charges first, newest first, to fees
|
||||||
|
* before rent, etc. Until we get there, I'll hardcode
|
||||||
|
* whatever algorithm is simplest.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function reconcileNewLedgerEntry($id, $fundamental_type, $amount) {
|
||||||
|
$A = new Account();
|
||||||
|
return $A->reconcileNewLedgerEntry
|
||||||
|
($this->accountId($id), $fundamental_type, $amount, array('LedgerEntry.lease_id' => $id));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: rentLastCharges
|
||||||
|
* - Returns a list of rent charges from this lease that
|
||||||
|
* do not have sequential followup charges. Under normal
|
||||||
|
* circumstances, there would only be one entry, which is
|
||||||
|
* the most recent rent charge. However, it's possible
|
||||||
|
* that there are several, indicating a problem with lease.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function rentLastCharges($id) {
|
||||||
|
$A = new Account();
|
||||||
|
$entries = $this->find
|
||||||
|
('all',
|
||||||
|
array('link' =>
|
||||||
|
array(// Models
|
||||||
|
'LedgerEntry' => array
|
||||||
|
('Ledger' => array
|
||||||
|
('fields' => array(),
|
||||||
|
'Account' => array
|
||||||
|
('fields' => array(),
|
||||||
|
'Ledger' => array
|
||||||
|
('alias' => 'Lx',
|
||||||
|
'fields' => array(),
|
||||||
|
'LedgerEntry' => array
|
||||||
|
('alias' => 'LEx',
|
||||||
|
'fields' => array(),
|
||||||
|
'conditions' => array
|
||||||
|
('LEx.effective_date = DATE_ADD(LedgerEntry.through_date, INTERVAL 1 day)',
|
||||||
|
'LEx.lease_id = LedgerEntry.lease_id',
|
||||||
|
)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
),
|
||||||
|
//'fields' => array('id', 'amount', 'effective_date', 'through_date'),
|
||||||
|
'fields' => array(),
|
||||||
|
'conditions' => array(array('Lease.id' => $id),
|
||||||
|
array('Account.id' => $A->rentAccountID()),
|
||||||
|
array('LEx.id' => null),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return $entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: rentChargeGaps
|
||||||
|
* - Checks for gaps in rent charges
|
||||||
|
*/
|
||||||
|
|
||||||
|
function rentChargeGaps($id) {
|
||||||
|
$entries = $this->rentLastCharges($id);
|
||||||
|
if ($entries && count($entries) > 1)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: rentChargeThrough
|
||||||
|
* - Determines the date that rent has been charged through
|
||||||
|
* Returns one of:
|
||||||
|
* null: There are gaps in the charges
|
||||||
|
* false: There are not yet any charges
|
||||||
|
* date: The date rent has been charged through
|
||||||
|
*/
|
||||||
|
|
||||||
|
function rentChargeThrough($id) {
|
||||||
|
$entries = $this->rentLastCharges($id);
|
||||||
|
if (!$entries)
|
||||||
|
return false;
|
||||||
|
if (count($entries) != 1)
|
||||||
|
return null;
|
||||||
|
return $entries[0]['LedgerEntry']['through_date'];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: rentPaidThrough
|
||||||
|
* - Determines the date of the first unpaid rent
|
||||||
|
*/
|
||||||
|
|
||||||
|
function rentPaidThrough($id) {
|
||||||
|
|
||||||
|
// Income / Receipt / Money
|
||||||
|
// debit: A/R credit: Income <-- this entry
|
||||||
|
// debit: Receipt credit: A/R <-- ReceiptLedgerEntry, below
|
||||||
|
// debit: Money credit: Receipt <-- MoneyLedgerEntry, below
|
||||||
|
|
||||||
|
$query = array
|
||||||
|
('link' => array
|
||||||
|
(
|
||||||
|
'CreditLedger' =>
|
||||||
|
array('fields' => array(),
|
||||||
|
'Account' =>
|
||||||
|
array('fields' => array(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// We're searching for the Receipt<->A/R entries,
|
||||||
|
// which are debits on the A/R account. Find the
|
||||||
|
// reconciling entries to that A/R debit.
|
||||||
|
'DebitReconciliationLedgerEntry' =>
|
||||||
|
array('alias' => 'ReceiptLedgerEntry',
|
||||||
|
'fields' => array(),
|
||||||
|
|
||||||
|
// Finally, the Money (Cash/Check/etc) Entry is the one
|
||||||
|
// which reconciles our ReceiptLedgerEntry debit
|
||||||
|
'DebitReconciliationLedgerEntry' =>
|
||||||
|
array('alias' => 'MoneyLedgerEntry',
|
||||||
|
'linkalias' => 'MoneyLedgerEntryR',
|
||||||
|
'fields' => array('SUM(COALESCE(MoneyLedgerEntryR.amount,0)) AS paid'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
'fields' => array('LedgerEntry.amount',
|
||||||
|
'DATE_SUB(LedgerEntry.effective_date, INTERVAL 1 DAY) AS paid_through',
|
||||||
|
),
|
||||||
|
|
||||||
|
'group' => 'LedgerEntry.id HAVING paid <> LedgerEntry.amount',
|
||||||
|
|
||||||
|
'conditions' => array(array('LedgerEntry.lease_id' => $id),
|
||||||
|
array('Account.id' => $this->LedgerEntry->Ledger->Account->rentAccountID()),
|
||||||
|
),
|
||||||
|
'order' => array('LedgerEntry.effective_date',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
$rent = $this->LedgerEntry->find('first', $query);
|
||||||
|
if ($rent)
|
||||||
|
return $rent[0]['paid_through'];
|
||||||
|
|
||||||
|
$query['fields'] = 'LedgerEntry.through_date';
|
||||||
|
$query['order'] = 'LedgerEntry.through_date DESC';
|
||||||
|
$query['group'] = 'LedgerEntry.id';
|
||||||
|
$rent = $this->LedgerEntry->find('first', $query);
|
||||||
|
if ($rent)
|
||||||
|
return $rent['LedgerEntry']['through_date'];
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: moveIn
|
||||||
|
* - Moves the specified customer into the specified lease
|
||||||
|
*/
|
||||||
|
|
||||||
|
function moveIn($customer_id, $unit_id,
|
||||||
|
$deposit = null, $rent = null,
|
||||||
|
$stamp = null, $comment = null) {
|
||||||
|
|
||||||
|
$lt = $this->LeaseType->find('first',
|
||||||
|
array('conditions' =>
|
||||||
|
array('code' => 'SL')));
|
||||||
|
|
||||||
|
// Use NOW if not given a movein date
|
||||||
|
if (!isset($stamp))
|
||||||
|
$stamp = date('Y-m-d G:i:s');
|
||||||
|
|
||||||
|
if (!$comment)
|
||||||
|
$comment = null;
|
||||||
|
|
||||||
|
if (!isset($deposit) || !isset($rent)) {
|
||||||
|
$rates = $this->Unit->find
|
||||||
|
('first',
|
||||||
|
array('contain' =>
|
||||||
|
array('UnitSize' =>
|
||||||
|
array('deposit', 'rent'),
|
||||||
|
),
|
||||||
|
'fields' => array('deposit', 'rent'),
|
||||||
|
'conditions' => array('Unit.id' => $unit_id),
|
||||||
|
));
|
||||||
|
|
||||||
|
$deposit =
|
||||||
|
(isset($deposit)
|
||||||
|
? $deposit
|
||||||
|
: (isset($rates['Unit']['deposit'])
|
||||||
|
? $rates['Unit']['deposit']
|
||||||
|
: (isset($rates['UnitSize']['deposit'])
|
||||||
|
? $rates['UnitSize']['deposit']
|
||||||
|
: 0)));
|
||||||
|
|
||||||
|
$rent =
|
||||||
|
(isset($rent)
|
||||||
|
? $rent
|
||||||
|
: (isset($rates['Unit']['rent'])
|
||||||
|
? $rates['Unit']['rent']
|
||||||
|
: (isset($rates['UnitSize']['rent'])
|
||||||
|
? $rates['UnitSize']['rent']
|
||||||
|
: 0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Save this new lease.
|
||||||
|
$this->create();
|
||||||
|
if (!$this->save(array('lease_type_id' => $lt['LeaseType']['id'],
|
||||||
|
'unit_id' => $unit_id,
|
||||||
|
'customer_id' => $customer_id,
|
||||||
|
'lease_date' => $stamp,
|
||||||
|
'movein_date' => $stamp,
|
||||||
|
'deposit' => $deposit,
|
||||||
|
'rent' => $rent,
|
||||||
|
'comment' => $comment), false)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the lease number to be the same as the lease ID
|
||||||
|
$this->id;
|
||||||
|
$this->saveField('number', $this->id);
|
||||||
|
|
||||||
|
// Update the unit status
|
||||||
|
$this->Unit->updateStatus($unit_id, 'OCCUPIED');
|
||||||
|
|
||||||
|
// REVISIT <AP>: 20090702
|
||||||
|
// We need to assess the security deposit charge,
|
||||||
|
// and probably rent as well. Rent, however, will
|
||||||
|
// require user parameters to indicate whether it
|
||||||
|
// was waived, pro-rated, etc.
|
||||||
|
|
||||||
|
// Return the new lease ID
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: moveOut
|
||||||
|
* - Moves the customer out of the specified lease
|
||||||
|
*/
|
||||||
|
|
||||||
|
function moveOut($id, $status = 'VACANT',
|
||||||
|
$stamp = null, $close = false) {
|
||||||
|
// Use NOW if not given a moveout date
|
||||||
|
if (!isset($stamp))
|
||||||
|
$stamp = date('Y-m-d G:i:s');
|
||||||
|
|
||||||
|
// Reset the data
|
||||||
|
$this->create();
|
||||||
|
$this->id = $id;
|
||||||
|
|
||||||
|
// Set the customer move-out date
|
||||||
|
$this->data['Lease']['moveout_date'] = $stamp;
|
||||||
|
|
||||||
|
// Save it!
|
||||||
|
$this->save($this->data, false);
|
||||||
|
|
||||||
|
// Close the lease, if so requested
|
||||||
|
if ($close)
|
||||||
|
$this->close($id, $stamp);
|
||||||
|
|
||||||
|
// Finally, update the unit status
|
||||||
|
$this->recursive = -1;
|
||||||
|
$this->read();
|
||||||
|
$this->Unit->updateStatus($this->data['Lease']['unit_id'], $status);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: close
|
||||||
|
* - Closes the lease to further action
|
||||||
|
*/
|
||||||
|
|
||||||
|
function close($id, $stamp = null) {
|
||||||
|
if (!$this->closeable($id))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Reset the data
|
||||||
|
$this->create();
|
||||||
|
$this->id = $id;
|
||||||
|
|
||||||
|
// Use NOW if not given a moveout date
|
||||||
|
if (!isset($stamp))
|
||||||
|
$stamp = date('Y-m-d G:i:s');
|
||||||
|
|
||||||
|
// Set the close date
|
||||||
|
$this->data['Lease']['close_date'] = $stamp;
|
||||||
|
|
||||||
|
// Save it!
|
||||||
|
$this->save($this->data, false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: closeable
|
||||||
|
* - Indicates whether or not the lease can be closed
|
||||||
|
*/
|
||||||
|
|
||||||
|
function closeable($id) {
|
||||||
|
$this->recursive = -1;
|
||||||
|
$this->read(null, $id);
|
||||||
|
|
||||||
|
// We can't close a lease that's still in use
|
||||||
|
if (!isset($this->data['Lease']['moveout_date']))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// We can't close a lease that's already closed
|
||||||
|
if (isset($this->data['Lease']['close_date']))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
$deposits = $this->findSecurityDeposits($id);
|
||||||
|
$stats = $this->stats($id);
|
||||||
|
|
||||||
|
// A lease can only be closed if there are no outstanding
|
||||||
|
// security deposits, and if the account balance is zero.
|
||||||
|
if ($deposits['summary']['balance'] != 0 || $stats['balance'] != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Apparently this lease meets all the criteria!
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: addCharge
|
||||||
|
* - Adds an additional charge to the lease
|
||||||
|
*/
|
||||||
|
|
||||||
|
function addCharge($id, $charge) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: stats
|
||||||
|
* - Returns summary data from the requested lease.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function stats($id = null) {
|
||||||
|
if (!$id)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
$A = new Account();
|
||||||
|
$stats = $A->stats($A->accountReceivableAccountID(), true,
|
||||||
|
array('LedgerEntry.lease_id' => $id));
|
||||||
|
|
||||||
|
// Pull to the top level and return
|
||||||
|
$stats = $stats['Ledger'];
|
||||||
|
return $stats;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
@@ -7,21 +7,8 @@ class LeaseType extends AppModel {
|
|||||||
'name' => array('notempty')
|
'name' => array('notempty')
|
||||||
);
|
);
|
||||||
|
|
||||||
//The Associations below have been created with all possible keys, those that are not needed can be removed
|
|
||||||
var $hasMany = array(
|
var $hasMany = array(
|
||||||
'Lease' => array(
|
'Lease',
|
||||||
'className' => 'Lease',
|
|
||||||
'foreignKey' => 'lease_type_id',
|
|
||||||
'dependent' => false,
|
|
||||||
'conditions' => '',
|
|
||||||
'fields' => '',
|
|
||||||
'order' => '',
|
|
||||||
'limit' => '',
|
|
||||||
'offset' => '',
|
|
||||||
'exclusive' => '',
|
|
||||||
'finderQuery' => '',
|
|
||||||
'counterQuery' => ''
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
250
site/models/ledger.php
Normal file
250
site/models/ledger.php
Normal file
@@ -0,0 +1,250 @@
|
|||||||
|
<?php
|
||||||
|
class Ledger extends AppModel {
|
||||||
|
|
||||||
|
var $name = 'Ledger';
|
||||||
|
var $validate = array(
|
||||||
|
'id' => array('numeric'),
|
||||||
|
'name' => array('notempty'),
|
||||||
|
);
|
||||||
|
|
||||||
|
var $belongsTo = array(
|
||||||
|
'Account',
|
||||||
|
'PriorLedger' => array('className' => 'Ledger'),
|
||||||
|
'Close',
|
||||||
|
);
|
||||||
|
|
||||||
|
var $hasMany = array(
|
||||||
|
'LedgerEntry' => array(
|
||||||
|
'foreignKey' => false,
|
||||||
|
|
||||||
|
// conditions will be used when JOINing tables
|
||||||
|
// (such as find with LinkableBehavior)
|
||||||
|
'conditions' => array('OR' =>
|
||||||
|
array('LedgerEntry.debit_ledger_id = %{MODEL_ALIAS}.id',
|
||||||
|
'LedgerEntry.credit_ledger_id = %{MODEL_ALIAS}.id')),
|
||||||
|
|
||||||
|
// finderQuery will be used when tables are put
|
||||||
|
// together across several querys, not with JOIN.
|
||||||
|
// (such as find with ContainableBehavior)
|
||||||
|
'finderQuery' => 'SELECT `LedgerEntry`.*
|
||||||
|
FROM pmgr_ledger_entries AS `LedgerEntry`
|
||||||
|
WHERE LedgerEntry.debit_ledger_id = ({$__cakeID__$})
|
||||||
|
OR LedgerEntry.credit_ledger_id = ({$__cakeID__$})',
|
||||||
|
|
||||||
|
'counterQuery' => ''
|
||||||
|
),
|
||||||
|
'DebitLedgerEntry' => array(
|
||||||
|
'className' => 'LedgerEntry',
|
||||||
|
'foreignKey' => 'debit_ledger_id',
|
||||||
|
'dependent' => false,
|
||||||
|
),
|
||||||
|
'CreditLedgerEntry' => array(
|
||||||
|
'className' => 'LedgerEntry',
|
||||||
|
'foreignKey' => 'credit_ledger_id',
|
||||||
|
'dependent' => false,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: accountID
|
||||||
|
* - Returns the account ID for the given ledger
|
||||||
|
*/
|
||||||
|
function accountID($id) {
|
||||||
|
$this->cacheQueries = true;
|
||||||
|
$item = $this->find('first', array
|
||||||
|
('contain' => 'Account.id',
|
||||||
|
'conditions' => array('Ledger.id' => $id),
|
||||||
|
));
|
||||||
|
$this->cacheQueries = false;
|
||||||
|
return $item['Account']['id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: currentLedgerID
|
||||||
|
* - Returns the current ledger ID of the account for the given ledger.
|
||||||
|
*/
|
||||||
|
function currentLedgerID($id) {
|
||||||
|
return $this->Account->currentLedgerID($this->accountID($id));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: closeLedger
|
||||||
|
* - Closes the current ledger, and returns a fresh one
|
||||||
|
*/
|
||||||
|
function closeLedger($id, $close_id) {
|
||||||
|
$this->recursive = -1;
|
||||||
|
|
||||||
|
$stamp = date('Y-m-d G:i:s');
|
||||||
|
$this->id = $id;
|
||||||
|
$this->read();
|
||||||
|
$this->data['Ledger']['close_id'] = $close_id;
|
||||||
|
$this->save($this->data, false);
|
||||||
|
|
||||||
|
$stats = $this->stats($id);
|
||||||
|
|
||||||
|
$this->read();
|
||||||
|
$this->data['Ledger']['id'] = null;
|
||||||
|
$this->data['Ledger']['close_id'] = null;
|
||||||
|
$this->data['Ledger']['prior_ledger_id'] = $id;
|
||||||
|
$this->data['Ledger']['comment'] = null;
|
||||||
|
++$this->data['Ledger']['sequence'];
|
||||||
|
$this->id = null;
|
||||||
|
$this->save($this->data, false);
|
||||||
|
//pr($this->data);
|
||||||
|
|
||||||
|
if ($stats['balance'] == 0)
|
||||||
|
return $this->id;
|
||||||
|
|
||||||
|
$this->read();
|
||||||
|
$ftype = $this->Account->fundamentalType($this->data['Ledger']['account_id']);
|
||||||
|
$otype = $this->Account->fundamentalOpposite($ftype);
|
||||||
|
|
||||||
|
// Create a transaction for balance transfer
|
||||||
|
$transaction = new Transaction();
|
||||||
|
$transaction->create();
|
||||||
|
if (!$transaction->save(array(), false)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create an entry to carry the balance forward
|
||||||
|
$carry_entry_data = array
|
||||||
|
($ftype.'_ledger_id' => $this->id,
|
||||||
|
$otype.'_ledger_id' => $id,
|
||||||
|
'transaction_id' => $transaction->id,
|
||||||
|
'amount' => $stats['balance'],
|
||||||
|
'comment' => "Ledger Balance Forward",
|
||||||
|
);
|
||||||
|
|
||||||
|
$carry_entry = new LedgerEntry();
|
||||||
|
$carry_entry->create();
|
||||||
|
if (!$carry_entry->save($carry_entry_data, false)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: findLedgerEntries
|
||||||
|
* - Returns an array of ledger entries that belong to a given
|
||||||
|
* ledger. There is extra work done... see the LedgerEntry model.
|
||||||
|
*/
|
||||||
|
function findLedgerEntries($id, $account_type = null, $cond = null, $link = null) {
|
||||||
|
/* pr(array('function' => 'Ledger::findLedgerEntries', */
|
||||||
|
/* 'args' => compact('id', 'account_type', 'cond', 'link'), */
|
||||||
|
/* )); */
|
||||||
|
|
||||||
|
if (!isset($account_type)) {
|
||||||
|
$ledger = $this->find('first', array
|
||||||
|
('contain' => array
|
||||||
|
('Account' => array
|
||||||
|
('fields' => array('type'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'fields' => array(),
|
||||||
|
'conditions' => array(array('Ledger.id' => $id)),
|
||||||
|
));
|
||||||
|
$account_type = $ledger['Account']['type'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the requested entries are limited by date, we must calculate
|
||||||
|
// a balance forward, or the resulting balance will be thrown off.
|
||||||
|
//
|
||||||
|
// REVISIT <AP>: This obviously is more general than date.
|
||||||
|
// As such, it will not work (or, only work if the
|
||||||
|
// condition only manages to exclude the first parts
|
||||||
|
// of the ledger, nothing in the middle or at the
|
||||||
|
// end. For now, I'll just create an 'other' entry,
|
||||||
|
// not necessarily a balance forward.
|
||||||
|
|
||||||
|
$bf = array();
|
||||||
|
if (0 && isset($cond)) {
|
||||||
|
//$date = '<NOT IMPLEMENTED>';
|
||||||
|
$stats = $this->stats($id, array('NOT' => array($cond)));
|
||||||
|
$bf = array(array(array('debit' => $stats['debits'],
|
||||||
|
'credit' => $stats['credits'],
|
||||||
|
'balance' => $stats['balance']),
|
||||||
|
|
||||||
|
'LedgerEntry' => array('id' => null,
|
||||||
|
//'comment' => "Balance Forward from $date"),
|
||||||
|
'comment' => "-- SUMMARY OF EXCLUDED ENTRIES --"),
|
||||||
|
|
||||||
|
'Transaction' => array('id' => null,
|
||||||
|
//'stamp' => $date,
|
||||||
|
'stamp' => null,
|
||||||
|
'comment' => null),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
$entries = $this->LedgerEntry->findInLedgerContext($id, $account_type, $cond, $link);
|
||||||
|
/* pr(array('function' => 'Ledger::findLedgerEntries', */
|
||||||
|
/* 'args' => compact('id', 'account_type', 'cond', 'link'), */
|
||||||
|
/* 'vars' => compact('ledger'), */
|
||||||
|
/* 'return' => compact('entries'), */
|
||||||
|
/* )); */
|
||||||
|
return $entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: stats
|
||||||
|
* - Returns summary data from the requested ledger.
|
||||||
|
*/
|
||||||
|
function stats($id, $cond = null) {
|
||||||
|
if (!isset($cond))
|
||||||
|
$cond = array();
|
||||||
|
$cond[] = array('Ledger.id' => $id);
|
||||||
|
|
||||||
|
$stats = $this->find
|
||||||
|
('first', array
|
||||||
|
('link' =>
|
||||||
|
array(// Models
|
||||||
|
'Account' => array('fields' => array()),
|
||||||
|
//'LedgerEntry' => array('fields' => array()),
|
||||||
|
'LedgerEntry' =>
|
||||||
|
array('fields' => array(),
|
||||||
|
'Transaction' => array('fields' => array('stamp')),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'fields' =>
|
||||||
|
array("SUM(IF(LedgerEntry.debit_ledger_id = Ledger.id,
|
||||||
|
LedgerEntry.amount, NULL)) AS debits",
|
||||||
|
"SUM(IF(LedgerEntry.credit_ledger_id = Ledger.id,
|
||||||
|
LedgerEntry.amount, NULL)) AS credits",
|
||||||
|
"SUM(IF(Account.type IN ('ASSET', 'EXPENSE'),
|
||||||
|
IF(LedgerEntry.debit_ledger_id = Ledger.id, 1, -1),
|
||||||
|
IF(LedgerEntry.credit_ledger_id = Ledger.id, 1, -1)
|
||||||
|
) * IF(LedgerEntry.amount, LedgerEntry.amount, 0)
|
||||||
|
) AS balance",
|
||||||
|
"COUNT(LedgerEntry.id) AS entries"),
|
||||||
|
'conditions' => $cond,
|
||||||
|
'group' => 'Ledger.id',
|
||||||
|
));
|
||||||
|
|
||||||
|
// The fields are all tucked into the [0] index,
|
||||||
|
// and the rest of the array is useless (empty).
|
||||||
|
$stats = $stats[0];
|
||||||
|
|
||||||
|
// Make sure we have a non-null balance
|
||||||
|
if (!isset($stats['balance']))
|
||||||
|
$stats['balance'] = 0;
|
||||||
|
|
||||||
|
return $stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
525
site/models/ledger_entry.php
Normal file
525
site/models/ledger_entry.php
Normal file
@@ -0,0 +1,525 @@
|
|||||||
|
<?php
|
||||||
|
class LedgerEntry extends AppModel {
|
||||||
|
|
||||||
|
var $name = 'LedgerEntry';
|
||||||
|
var $validate = array(
|
||||||
|
'id' => array('numeric'),
|
||||||
|
'transaction_id' => array('numeric'),
|
||||||
|
'amount' => array('money')
|
||||||
|
);
|
||||||
|
|
||||||
|
var $hasMany = array(
|
||||||
|
'DebitReconciliation' => array(
|
||||||
|
'className' => 'Reconciliation',
|
||||||
|
'foreignKey' => 'debit_ledger_entry_id',
|
||||||
|
),
|
||||||
|
'CreditReconciliation' => array(
|
||||||
|
'className' => 'Reconciliation',
|
||||||
|
'foreignKey' => 'credit_ledger_entry_id',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
var $belongsTo = array(
|
||||||
|
'MonetarySource',
|
||||||
|
'Transaction',
|
||||||
|
'Customer',
|
||||||
|
'Lease',
|
||||||
|
|
||||||
|
'DebitLedger' => array(
|
||||||
|
'className' => 'Ledger',
|
||||||
|
'foreignKey' => 'debit_ledger_id',
|
||||||
|
),
|
||||||
|
'CreditLedger' => array(
|
||||||
|
'className' => 'Ledger',
|
||||||
|
'foreignKey' => 'credit_ledger_id',
|
||||||
|
),
|
||||||
|
|
||||||
|
'Ledger' => array(
|
||||||
|
'foreignKey' => false,
|
||||||
|
// conditions will be used when JOINing tables
|
||||||
|
// (such as find with LinkableBehavior)
|
||||||
|
'conditions' => array('OR' =>
|
||||||
|
array('%{MODEL_ALIAS}.debit_ledger_id = Ledger.id',
|
||||||
|
'%{MODEL_ALIAS}.credit_ledger_id = Ledger.id')),
|
||||||
|
|
||||||
|
// finderQuery will be used when tables are put
|
||||||
|
// together across several querys, not with JOIN.
|
||||||
|
// (such as find with ContainableBehavior)
|
||||||
|
'finderQuery' => 'NOT-IMPLEMENTED',
|
||||||
|
|
||||||
|
'counterQuery' => ''
|
||||||
|
),
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
var $hasAndBelongsToMany = array(
|
||||||
|
'DebitReconciliationLedgerEntry' => array(
|
||||||
|
'className' => 'LedgerEntry',
|
||||||
|
'joinTable' => 'reconciliations',
|
||||||
|
'foreignKey' => 'credit_ledger_entry_id',
|
||||||
|
'associationForeignKey' => 'debit_ledger_entry_id',
|
||||||
|
),
|
||||||
|
// STUPID CakePHP bug screws up when using Containable
|
||||||
|
// and CLASS contains CLASS. This extra HABTM give the
|
||||||
|
// option of multiple depths on one CLASS, since there
|
||||||
|
// isn't an alias specification for Containable.
|
||||||
|
'DebitReconciliationLedgerEntry2' => array(
|
||||||
|
'className' => 'LedgerEntry',
|
||||||
|
'joinTable' => 'reconciliations',
|
||||||
|
'foreignKey' => 'credit_ledger_entry_id',
|
||||||
|
'associationForeignKey' => 'debit_ledger_entry_id',
|
||||||
|
),
|
||||||
|
'CreditReconciliationLedgerEntry' => array(
|
||||||
|
'className' => 'LedgerEntry',
|
||||||
|
'joinTable' => 'reconciliations',
|
||||||
|
'foreignKey' => 'debit_ledger_entry_id',
|
||||||
|
'associationForeignKey' => 'credit_ledger_entry_id',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: conditionEntryAsCreditOrDebit
|
||||||
|
* - returns the condition necessary to match a set of
|
||||||
|
* Ledgers to all related LedgerEntries
|
||||||
|
*/
|
||||||
|
function conditionEntryAsCreditOrDebit($ledger_ids) {
|
||||||
|
return array('OR' =>
|
||||||
|
array(array('debit_ledger_id' => $ledger_ids),
|
||||||
|
array('credit_ledger_id' => $ledger_ids)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: ledgerContext query helpers
|
||||||
|
* - Returns parameters necessary to generate a query which
|
||||||
|
* puts ledger entries into the context of a ledger. Since
|
||||||
|
* debit/credit depends on the account type, it is required
|
||||||
|
* as an argument for each function to avoid having to
|
||||||
|
* query the ledger/account to find it out.
|
||||||
|
*/
|
||||||
|
function ledgerContextFields($ledger_id = null, $account_type = null) {
|
||||||
|
$fields = array('id', 'effective_date', 'through_date',
|
||||||
|
'lease_id', 'customer_id', 'comment', 'amount');
|
||||||
|
|
||||||
|
if (isset($ledger_id)) {
|
||||||
|
$fields[] = ("IF(LedgerEntry.debit_ledger_id = $ledger_id," .
|
||||||
|
" LedgerEntry.amount, NULL) AS debit");
|
||||||
|
$fields[] = ("IF(LedgerEntry.credit_ledger_id = $ledger_id," .
|
||||||
|
" LedgerEntry.amount, NULL) AS credit");
|
||||||
|
|
||||||
|
if (isset($account_type)) {
|
||||||
|
if (in_array($account_type, array('ASSET', 'EXPENSE')))
|
||||||
|
$ledger_type = 'debit';
|
||||||
|
else
|
||||||
|
$ledger_type = 'credit';
|
||||||
|
|
||||||
|
$fields[] = ("(IF(LedgerEntry.{$ledger_type}_ledger_id = $ledger_id," .
|
||||||
|
" 1, -1) * LedgerEntry.amount) AS balance");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
function ledgerContextFields2($ledger_id = null, $account_id = null, $account_type = null) {
|
||||||
|
$fields = array('id', 'effective_date', 'through_date', 'comment', 'amount');
|
||||||
|
|
||||||
|
if (isset($ledger_id)) {
|
||||||
|
$fields[] = ("IF(LedgerEntry.debit_ledger_id = $ledger_id," .
|
||||||
|
" SUM(LedgerEntry.amount), NULL) AS debit");
|
||||||
|
$fields[] = ("IF(LedgerEntry.credit_ledger_id = $ledger_id," .
|
||||||
|
" SUM(LedgerEntry.amount), NULL) AS credit");
|
||||||
|
|
||||||
|
if (isset($account_id) || isset($account_type)) {
|
||||||
|
$Account = new Account();
|
||||||
|
$account_ftype = $Account->fundamentalType($account_id ? $account_id : $account_type);
|
||||||
|
$fields[] = ("(IF(LedgerEntry.{$account_ftype}_ledger_id = $ledger_id," .
|
||||||
|
" 1, -1) * SUM(LedgerEntry.amount)) AS balance");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif (isset($account_id)) {
|
||||||
|
$fields[] = ("IF(DebitLedger.account_id = $account_id," .
|
||||||
|
" SUM(LedgerEntry.amount), NULL) AS debit");
|
||||||
|
$fields[] = ("IF(CreditLedger.account_id = $account_id," .
|
||||||
|
" SUM(LedgerEntry.amount), NULL) AS credit");
|
||||||
|
|
||||||
|
$Account = new Account();
|
||||||
|
$account_ftype = ucfirst($Account->fundamentalType($account_id));
|
||||||
|
$fields[] = ("(IF({$account_ftype}Ledger.account_id = $account_id," .
|
||||||
|
" 1, -1) * SUM(LedgerEntry.amount)) AS balance");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function ledgerContextConditions($ledger_id, $account_type) {
|
||||||
|
if (isset($ledger_id)) {
|
||||||
|
return array
|
||||||
|
('OR' =>
|
||||||
|
array(array('LedgerEntry.debit_ledger_id' => $ledger_id),
|
||||||
|
array('LedgerEntry.credit_ledger_id' => $ledger_id)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: findInLedgerContext
|
||||||
|
* - Returns an array of ledger entries that belong to a given ledger.
|
||||||
|
* There is extra logic to also figure out whether the ledger_entry
|
||||||
|
* amount is either a credit, or a debit, depending on how it was
|
||||||
|
* written into the ledger, as well as whether the amount increases or
|
||||||
|
* decreases the balance depending on the particular account type of
|
||||||
|
* the ledger.
|
||||||
|
*/
|
||||||
|
function findInLedgerContext($ledger_id, $account_type, $cond = null, $link = null) {
|
||||||
|
if (!isset($link))
|
||||||
|
$link = array('Transaction');
|
||||||
|
|
||||||
|
if (!isset($cond))
|
||||||
|
$cond = array();
|
||||||
|
|
||||||
|
$fields = $this->ledgerContextFields($ledger_id, $account_type);
|
||||||
|
$cond[] = $this->ledgerContextConditions($ledger_id, $account_type);
|
||||||
|
$order = array('Transaction.stamp');
|
||||||
|
|
||||||
|
$entries = $this->find
|
||||||
|
('all',
|
||||||
|
array('link' => $link,
|
||||||
|
'fields' => $fields,
|
||||||
|
'conditions' => $cond,
|
||||||
|
'order' => $order,
|
||||||
|
));
|
||||||
|
|
||||||
|
return $entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: findReconciledLedgerEntries
|
||||||
|
* - Returns ledger entries that are reconciled to the given entry.
|
||||||
|
* (such as payments towards a charge).
|
||||||
|
*/
|
||||||
|
|
||||||
|
function findReconciledLedgerEntries($id = null, $fundamental_type = null) {
|
||||||
|
foreach (($fundamental_type
|
||||||
|
? array($fundamental_type)
|
||||||
|
: array('debit', 'credit')) AS $fund) {
|
||||||
|
$ucfund = ucfirst($fund);
|
||||||
|
$reconciled[$fund]['entry'] = $this->find
|
||||||
|
('all', array
|
||||||
|
('link' => array
|
||||||
|
("ReconciliationLedgerEntry" => array
|
||||||
|
('class' => "{$ucfund}ReconciliationLedgerEntry",
|
||||||
|
'fields' => array
|
||||||
|
('id',
|
||||||
|
"COALESCE(SUM(Reconciliation.amount),0) AS 'reconciled'",
|
||||||
|
"LedgerEntry.amount - COALESCE(SUM(Reconciliation.amount),0) AS 'balance'",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'group' => ("ReconciliationLedgerEntry.id"),
|
||||||
|
'conditions' => array('LedgerEntry.id' => $id),
|
||||||
|
'fields' => array(),
|
||||||
|
));
|
||||||
|
//pr($reconciled);
|
||||||
|
$balance = 0;
|
||||||
|
foreach ($reconciled[$fund]['entry'] AS &$entry) {
|
||||||
|
$entry = array_merge($entry["ReconciliationLedgerEntry"], $entry[0]);
|
||||||
|
$balance += $entry['balance'];
|
||||||
|
}
|
||||||
|
$reconciled[$fund]['balance'] = $balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $reconciled;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: reverse
|
||||||
|
* - Reverses the ledger entry
|
||||||
|
*/
|
||||||
|
|
||||||
|
function reverse1($id, $amount = null, $transaction_id = null, $rec_id = null) {
|
||||||
|
/* pr(array('LedgerEntry::reverse', */
|
||||||
|
/* compact('id', 'amount', 'transaction_id', 'rec_id'))); */
|
||||||
|
|
||||||
|
// Get the LedgerEntry and related fields
|
||||||
|
$entry = $this->find
|
||||||
|
('first',
|
||||||
|
array('contain' => array('MonetarySource.id',
|
||||||
|
'Transaction.id',
|
||||||
|
'DebitLedger.id',
|
||||||
|
'DebitLedger.account_id',
|
||||||
|
'CreditLedger.id',
|
||||||
|
'CreditLedger.account_id',
|
||||||
|
'DebitReconciliationLedgerEntry'
|
||||||
|
/* => */
|
||||||
|
/* array('DebitLedger.id', */
|
||||||
|
/* 'DebitLedger.account_id', */
|
||||||
|
/* 'CreditLedger.id', */
|
||||||
|
/* 'CreditLedger.account_id', */
|
||||||
|
/* ) */
|
||||||
|
,
|
||||||
|
'CreditReconciliationLedgerEntry'
|
||||||
|
/* => */
|
||||||
|
/* array('DebitLedger.id', */
|
||||||
|
/* 'DebitLedger.account_id', */
|
||||||
|
/* 'CreditLedger.id', */
|
||||||
|
/* 'CreditLedger.account_id', */
|
||||||
|
/* ) */
|
||||||
|
,
|
||||||
|
'Customer.id',
|
||||||
|
'Lease.id',
|
||||||
|
),
|
||||||
|
|
||||||
|
'fields' => array('LedgerEntry.*'),
|
||||||
|
|
||||||
|
'conditions' => array(array('LedgerEntry.id' => $id),
|
||||||
|
/* array('NOT' => */
|
||||||
|
/* array('OR' => */
|
||||||
|
/* array(array('DebitReconciliationLedgerEntry.id' => $rec_id), */
|
||||||
|
/* array('CreditReconciliationLedgerEntry.id' => $rec_id), */
|
||||||
|
/* ), */
|
||||||
|
/* ), */
|
||||||
|
/* ), */
|
||||||
|
),
|
||||||
|
));
|
||||||
|
//pr($entry);
|
||||||
|
|
||||||
|
if (!isset($amount))
|
||||||
|
$amount = $entry['LedgerEntry']['amount'];
|
||||||
|
|
||||||
|
$A = new Account();
|
||||||
|
|
||||||
|
$ids = $this->Ledger->Account->postLedgerEntry
|
||||||
|
(array('transaction_id' => $transaction_id),
|
||||||
|
null,
|
||||||
|
array('debit_ledger_id' => $A->currentLedgerID($entry['CreditLedger']['account_id']),
|
||||||
|
'credit_ledger_id' => $A->currentLedgerID($entry['DebitLedger']['account_id']),
|
||||||
|
'effective_date' => $entry['LedgerEntry']['effective_date'],
|
||||||
|
//'effective_date' => $entry['LedgerEntry']['effective_date'],
|
||||||
|
'amount' => $amount,
|
||||||
|
'lease_id' => $entry['Lease']['id'],
|
||||||
|
'customer_id' => $entry['Customer']['id'],
|
||||||
|
'comment' => "Reversal of Ledger Entry #{$id}",
|
||||||
|
),
|
||||||
|
array('debit' => array(array('LedgerEntry' => array('id' => $entry['LedgerEntry']['id'],
|
||||||
|
'amount' => $amount,
|
||||||
|
))),
|
||||||
|
'credit' => array(array('LedgerEntry' => array('id' => $entry['LedgerEntry']['id'],
|
||||||
|
'amount' => $amount,
|
||||||
|
))),
|
||||||
|
));
|
||||||
|
|
||||||
|
if ($ids['error'])
|
||||||
|
return null;
|
||||||
|
|
||||||
|
$tid = $ids['transaction_id'];
|
||||||
|
|
||||||
|
pr(compact('entry'));
|
||||||
|
|
||||||
|
foreach (array('Debit', 'Credit') AS $dc_type) {
|
||||||
|
foreach ($entry[$dc_type . 'ReconciliationLedgerEntry'] AS $RLE) {
|
||||||
|
pr(array('checkpoint' => "Reverse $dc_type LE",
|
||||||
|
compact('id', 'rec_id', 'RLE')));
|
||||||
|
if ($RLE['id'] == $rec_id) {
|
||||||
|
pr(array('checkpoint' => "Skipping Reverse $dc_type LE, due to rec_id",
|
||||||
|
compact('id', 'RLE')));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->reverse($RLE['id'], $RLE['Reconciliation']['amount'], $tid, $id))
|
||||||
|
$ids['error'] = true;
|
||||||
|
|
||||||
|
/* $rids = $this->Ledger->Account->postLedgerEntry */
|
||||||
|
/* (array('transaction_id' => $tid), */
|
||||||
|
/* null, */
|
||||||
|
/* array('debit_ledger_id' => $A->currentLedgerID($RLE['CreditLedger']['account_id']), */
|
||||||
|
/* 'credit_ledger_id' => $A->currentLedgerID($RLE['DebitLedger']['account_id']), */
|
||||||
|
/* 'effective_date' => $RLE['effective_date'], */
|
||||||
|
/* //'effective_date' => $RLE['effective_date'], */
|
||||||
|
/* 'amount' => $RLE['Reconciliation']['amount'], */
|
||||||
|
/* 'lease_id' => $entry['Lease']['id'], */
|
||||||
|
/* 'customer_id' => $entry['Customer']['id'], */
|
||||||
|
/* 'comment' => "Reversal of Ledger Entry #{$RLE['id']}", */
|
||||||
|
/* ), */
|
||||||
|
/* array('debit' => array(array('LedgerEntry' => array('id' => $RLE['id'], */
|
||||||
|
/* 'amount' => $RLE['Reconciliation']['amount'], */
|
||||||
|
/* ))), */
|
||||||
|
/* 'credit' => array(array('LedgerEntry' => array('id' => $RLE['id'], */
|
||||||
|
/* 'amount' => $RLE['Reconciliation']['amount'], */
|
||||||
|
/* ))), */
|
||||||
|
/* )); */
|
||||||
|
|
||||||
|
/* if ($rids['error']) */
|
||||||
|
/* $ids['error'] = true; */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($ids['error'])
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return $ids['id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: reverse
|
||||||
|
* - Reverses the charges
|
||||||
|
*
|
||||||
|
* SAMPLE MOVE IN w/ PRE PAYMENT
|
||||||
|
* DEPOSIT RENT A/R RECEIPT CHECK PETTY BANK
|
||||||
|
* ------- ------- ------- ------- ------- ------- -------
|
||||||
|
* |25 | 25| | | | |
|
||||||
|
* | |20 20| | | | |
|
||||||
|
* | |20 20| | | | |
|
||||||
|
* | |20 20| | | | |
|
||||||
|
* | | |25 25| | | |
|
||||||
|
* | | |20 20| | | |
|
||||||
|
* | | |20 20| | | |
|
||||||
|
* | | |20 20| | | |
|
||||||
|
* | | | |85 85| | |
|
||||||
|
* | | | | |85 | 85|
|
||||||
|
|
||||||
|
* MOVE OUT and REFUND FINAL MONTH
|
||||||
|
* DEPOSIT RENT C/P RECEIPT CHECK PETTY BANK
|
||||||
|
* ------- ------- ------- ------- ------- ------- -------
|
||||||
|
* 25| | |25 | | | | t20 e20a
|
||||||
|
* | 20| |20 | | | | t20 e20b
|
||||||
|
|
||||||
|
* -ONE REFUND CHECK-
|
||||||
|
* | | 25| |25 | | | t30 e30a
|
||||||
|
* | | 20| |20 | | | t30 e30b
|
||||||
|
* | | | 45| | | |45 t40 e40
|
||||||
|
* -OR MULTIPLE-
|
||||||
|
* | | 15| |15 | | | t50a e50a
|
||||||
|
* | | | 15| | |15 | t60a e60a
|
||||||
|
* | | 30| |30 | | | t50b e50b
|
||||||
|
* | | | 30| | | |30 t60b e60b
|
||||||
|
* | | | | | | |
|
||||||
|
|
||||||
|
|
||||||
|
OPTION 1
|
||||||
|
* |-25 | -25| | | | |
|
||||||
|
* | |-20 -20| | | | |
|
||||||
|
* | | |-25 -25| | | |
|
||||||
|
* | | |-20 -20| | | |
|
||||||
|
|
||||||
|
OPTION 2
|
||||||
|
* |-25 | | -25| | | |
|
||||||
|
* | |-20 | -20| | | |
|
||||||
|
* | | | |-15 | -15| |
|
||||||
|
* | | | |-30 | | -30|
|
||||||
|
* | | | | | | |
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
function reverse($ledger_entries, $stamp = null) {
|
||||||
|
pr(array('LedgerEntry::reverse',
|
||||||
|
compact('ledger_entries', 'stamp')));
|
||||||
|
|
||||||
|
// If the user only wants to reverse one ID, we'll allow it
|
||||||
|
if (!is_array($ledger_entries))
|
||||||
|
$ledger_entries = $this->find
|
||||||
|
('all', array
|
||||||
|
('contain' => false,
|
||||||
|
'conditions' => array('LedgerEntry.id' => $ledger_entries)));
|
||||||
|
|
||||||
|
$A = new Account();
|
||||||
|
|
||||||
|
$ar_account_id = $A->accountReceivableAccountID();
|
||||||
|
$receipt_account_id = $A->receiptAccountID();
|
||||||
|
|
||||||
|
$transaction_id = null;
|
||||||
|
foreach ($ledger_entries AS $entry) {
|
||||||
|
$entry = $entry['LedgerEntry'];
|
||||||
|
$amount = -1*$entry['amount'];
|
||||||
|
|
||||||
|
if (isset($entry['credit_account_id']))
|
||||||
|
$refund_account_id = $entry['credit_account_id'];
|
||||||
|
elseif (isset($entry['CreditLedger']['Account']['id']))
|
||||||
|
$refund_account_id = $entry['CreditLedger']['Account']['id'];
|
||||||
|
elseif (isset($entry['credit_ledger_id']))
|
||||||
|
$refund_account_id = $this->Ledger->accountID($entry['credit_ledger_id']);
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// post new refund in the income account
|
||||||
|
$ids = $A->postLedgerEntry
|
||||||
|
(array('transaction_id' => $transaction_id),
|
||||||
|
null,
|
||||||
|
array('debit_ledger_id' => $A->currentLedgerID($ar_account_id),
|
||||||
|
'credit_ledger_id' => $A->currentLedgerID($refund_account_id),
|
||||||
|
'effective_date' => $entry['effective_date'],
|
||||||
|
'through_date' => $entry['through_date'],
|
||||||
|
'amount' => $amount,
|
||||||
|
'lease_id' => $entry['lease_id'],
|
||||||
|
'customer_id' => $entry['customer_id'],
|
||||||
|
'comment' => "Refund; Entry #{$entry['id']}",
|
||||||
|
),
|
||||||
|
array('debit' => array
|
||||||
|
(array('LedgerEntry' =>
|
||||||
|
array('id' => $entry['id'],
|
||||||
|
'amount' => $amount))),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($ids['error'])
|
||||||
|
return null;
|
||||||
|
$transaction_id = $ids['transaction_id'];
|
||||||
|
|
||||||
|
pr(array('checkpoint' => 'Posted Refund Ledger Entry',
|
||||||
|
compact('ids', 'amount', 'refund_account_id', 'ar_account_id')));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: stats
|
||||||
|
* - Returns summary data from the requested ledger entry
|
||||||
|
*/
|
||||||
|
function stats($id) {
|
||||||
|
|
||||||
|
$query = array
|
||||||
|
(
|
||||||
|
'fields' => array("SUM(Reconciliation.amount) AS 'reconciled'"),
|
||||||
|
|
||||||
|
'conditions' => array(isset($cond) ? $cond : array(),
|
||||||
|
array('LedgerEntry.id' => $id)),
|
||||||
|
|
||||||
|
'group' => 'LedgerEntry.id',
|
||||||
|
);
|
||||||
|
|
||||||
|
// Get the applied amounts on the debit side
|
||||||
|
$query['link'] =
|
||||||
|
array('DebitReconciliationLedgerEntry' => array('alias' => 'DRLE', 'DRLETransaction' => array('class' => 'Transaction')));
|
||||||
|
$tmpstats = $this->find('first', $query);
|
||||||
|
$stats['debit_amount_reconciled'] = $tmpstats[0]['reconciled'];
|
||||||
|
|
||||||
|
// Get the applied amounts on the credit side
|
||||||
|
$query['link'] =
|
||||||
|
array('CreditReconciliationLedgerEntry' => array('alias' => 'CRLE', 'CRLETransaction' => array('class' => 'Transaction')));
|
||||||
|
$tmpstats = $this->find('first', $query);
|
||||||
|
$stats['credit_amount_reconciled'] = $tmpstats[0]['reconciled'];
|
||||||
|
|
||||||
|
return $stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -11,33 +11,12 @@ class Map extends AppModel {
|
|||||||
'depth' => array('numeric')
|
'depth' => array('numeric')
|
||||||
);
|
);
|
||||||
|
|
||||||
//The Associations below have been created with all possible keys, those that are not needed can be removed
|
|
||||||
var $belongsTo = array(
|
var $belongsTo = array(
|
||||||
'SiteArea' => array(
|
'SiteArea',
|
||||||
'className' => 'SiteArea',
|
|
||||||
'foreignKey' => 'site_area_id',
|
|
||||||
'conditions' => '',
|
|
||||||
'fields' => '',
|
|
||||||
'order' => ''
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
var $hasAndBelongsToMany = array(
|
var $hasAndBelongsToMany = array(
|
||||||
'Unit' => array(
|
'Unit',
|
||||||
'className' => 'Unit',
|
|
||||||
'joinTable' => 'maps_units',
|
|
||||||
'foreignKey' => 'map_id',
|
|
||||||
'associationForeignKey' => 'unit_id',
|
|
||||||
'unique' => true,
|
|
||||||
'conditions' => '',
|
|
||||||
'fields' => '',
|
|
||||||
'order' => '',
|
|
||||||
'limit' => '',
|
|
||||||
'offset' => '',
|
|
||||||
'finderQuery' => '',
|
|
||||||
'deleteQuery' => '',
|
|
||||||
'insertQuery' => ''
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
268
site/models/monetary_source.php
Normal file
268
site/models/monetary_source.php
Normal file
@@ -0,0 +1,268 @@
|
|||||||
|
<?php
|
||||||
|
class MonetarySource extends AppModel {
|
||||||
|
|
||||||
|
var $name = 'MonetarySource';
|
||||||
|
var $validate = array(
|
||||||
|
'id' => array('numeric'),
|
||||||
|
'name' => array('notempty'),
|
||||||
|
'tillable' => array('boolean')
|
||||||
|
);
|
||||||
|
|
||||||
|
var $belongsTo = array(
|
||||||
|
);
|
||||||
|
|
||||||
|
var $hasMany = array(
|
||||||
|
'LedgerEntry',
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: nsf
|
||||||
|
* - Flags the ledger entry as having insufficient funds
|
||||||
|
* - NOTE: nsf only works if given the monetary source id
|
||||||
|
* to transaction e3, below
|
||||||
|
* - NOTE: In order to show that the rent formerly considered
|
||||||
|
* "collected" is now recognized in reverse, we must
|
||||||
|
* credit A/R with a negative amount in order to
|
||||||
|
* reconcile it against the Rent<->A/R ledger entry.
|
||||||
|
*
|
||||||
|
* FEE RENT A/R RECEIPT CHECK NSF BANK
|
||||||
|
* ------- ------- ------- ------- ------- ------- -------
|
||||||
|
* | |30 30| | | | | t1 e1a : R e2/e7a :
|
||||||
|
* | |20 20| | | | | t1 e1b : R e2/e7b :
|
||||||
|
* | | | | | | |
|
||||||
|
* | | |30 30| | | | t2 e2a : R e3 : R e1a
|
||||||
|
* | | |20 20| | | | t2 e2b : R e3 : R e1b
|
||||||
|
* | | | |50 50| | | t2 e3 : R e4 : R e2
|
||||||
|
* | | | | | | |
|
||||||
|
* | | | | |50 | 50| t3 e4 : : R e3
|
||||||
|
* | | | | | | |
|
||||||
|
* | | | | | |-50 -50| t4 e5 : : R e6
|
||||||
|
* | | | |-50 | -50| | t5 e6 : R e5 : R e7a/e7b
|
||||||
|
* | | |-30 -30| | | | t6 e7a : R e6 : R e1a
|
||||||
|
* | | |-20 -20| | | | t6 e7b : R e6 : R e1b
|
||||||
|
* |35 | 35| | | | | t6 e8
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function nsf($id, $stamp = null) {
|
||||||
|
pr(array('MonetarySource::nsf',
|
||||||
|
compact('id')));
|
||||||
|
|
||||||
|
$A = new Account();
|
||||||
|
|
||||||
|
// Get the LedgerEntries that use this monetary source
|
||||||
|
$source = $this->find
|
||||||
|
('first',
|
||||||
|
array('contain' =>
|
||||||
|
array(/* e3 */
|
||||||
|
'LedgerEntry' =>
|
||||||
|
array('Transaction.id',
|
||||||
|
'MonetarySource.id',
|
||||||
|
'Customer.id',
|
||||||
|
'Lease.id',
|
||||||
|
|
||||||
|
/* e3 debit */
|
||||||
|
'DebitLedger' => /* e.g. CHECK Ledger */
|
||||||
|
array('fields' => array(),
|
||||||
|
|
||||||
|
'Account' => /* e.g. CHECK Account */
|
||||||
|
array('fields' => array('id', 'name'),
|
||||||
|
'conditions' =>
|
||||||
|
array('Account.payable' => 1,
|
||||||
|
'Account.type' => 'ASSET'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
/* e3 credit */
|
||||||
|
'CreditLedger' => /* i.e. RECEIPT Ledger */
|
||||||
|
array('fields' => array('id'),
|
||||||
|
'Account' => /* i.e. RECEIPT Account */
|
||||||
|
array('fields' => array('id', 'name'),
|
||||||
|
'conditions' =>
|
||||||
|
array('Account.id' => $A->receiptAccountID()),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
/* e2 */
|
||||||
|
'DebitReconciliationLedgerEntry' =>
|
||||||
|
array(/* e2 credit */
|
||||||
|
'CreditLedger' => /* i.e. A/R Ledger */
|
||||||
|
array('fields' => array(),
|
||||||
|
|
||||||
|
'Account' => /* i.e. A/R Account */
|
||||||
|
array('fields' => array(),
|
||||||
|
'conditions' =>
|
||||||
|
array('Account.id' => $A->accountReceivableAccountID()),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
/* e1 */
|
||||||
|
// STUPID CakePHP bug screws up CLASS contains CLASS.
|
||||||
|
// Use the same class, but with different name.
|
||||||
|
'DebitReconciliationLedgerEntry2',
|
||||||
|
),
|
||||||
|
|
||||||
|
/* e4 */
|
||||||
|
'CreditReconciliationLedgerEntry' =>
|
||||||
|
array(/* e4 debit */
|
||||||
|
'DebitLedger' => /* e.g. BANK Ledger */
|
||||||
|
array('fields' => array('id'),
|
||||||
|
'Account' => /* e.g. BANK Account */
|
||||||
|
array('fields' => array('id', 'name'),
|
||||||
|
'conditions' =>
|
||||||
|
array('Account.depositable' => 1),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
'conditions' => array(array('MonetarySource.id' => $id)),
|
||||||
|
));
|
||||||
|
pr($source);
|
||||||
|
|
||||||
|
$nsf_account_id = $A->nsfAccountID();
|
||||||
|
$nsf_fee_account_id = $A->nsfChargeAccountID();
|
||||||
|
$ar_account_id = $A->accountReceivableAccountID();
|
||||||
|
$receipt_account_id = $A->receiptAccountID();
|
||||||
|
|
||||||
|
$t4_id = null;
|
||||||
|
$t5_id = null;
|
||||||
|
foreach ($source['LedgerEntry'] AS $e3) {
|
||||||
|
// We expect only a single e4 entry
|
||||||
|
$e4 = $e3['CreditReconciliationLedgerEntry'];
|
||||||
|
if (count($e4) < 1)
|
||||||
|
continue;
|
||||||
|
if (count($e4) > 1)
|
||||||
|
die('Too many e4 entries');
|
||||||
|
|
||||||
|
// Pullup e4 from the single member array
|
||||||
|
$e4 = $e4[0];
|
||||||
|
|
||||||
|
// e3 amount
|
||||||
|
$amount = -$e3['amount'];
|
||||||
|
|
||||||
|
// e4 account
|
||||||
|
$bank_account_id = $e4['DebitLedger']['account_id'];
|
||||||
|
|
||||||
|
// post new e5
|
||||||
|
$e5_ids = $A->postLedgerEntry
|
||||||
|
(array('transaction_id' => $t4_id),
|
||||||
|
null,
|
||||||
|
array('debit_ledger_id' => $A->currentLedgerID($bank_account_id),
|
||||||
|
'credit_ledger_id' => $A->currentLedgerID($nsf_account_id),
|
||||||
|
'effective_date' => $stamp,
|
||||||
|
'amount' => $amount,
|
||||||
|
'lease_id' => $e3['lease_id'],
|
||||||
|
'customer_id' => $e3['customer_id'],
|
||||||
|
'comment' => "NSF Bank Reversal; Monetary Source #{$id}",
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($e5_ids['error'])
|
||||||
|
return null;
|
||||||
|
$t4_id = $e5_ids['transaction_id'];
|
||||||
|
|
||||||
|
pr(array('checkpoint' => 'Posted Ledger Entry e5',
|
||||||
|
compact('e5_ids', 'amount')));
|
||||||
|
|
||||||
|
// post new e6... this will be our crossover point
|
||||||
|
// from typical positive entries to negative entries.
|
||||||
|
// Therefore, no reconciliation on this account.
|
||||||
|
$e6_ids = $A->postLedgerEntry
|
||||||
|
(array('transaction_id' => $t5_id),
|
||||||
|
array('monetary_source_id' => $e3['monetary_source_id']),
|
||||||
|
array('debit_ledger_id' => $A->currentLedgerID($nsf_account_id),
|
||||||
|
'credit_ledger_id' => $A->currentLedgerID($receipt_account_id),
|
||||||
|
'effective_date' => $stamp,
|
||||||
|
'amount' => $amount,
|
||||||
|
'lease_id' => $e3['lease_id'],
|
||||||
|
'customer_id' => $e3['customer_id'],
|
||||||
|
'comment' => "NSF tracker; Monetary Source #{$id}",
|
||||||
|
),
|
||||||
|
array('debit' => array
|
||||||
|
(array('LedgerEntry' =>
|
||||||
|
array('id' => $e5_ids['id'],
|
||||||
|
'amount' => $amount))),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($e6_ids['error'])
|
||||||
|
return null;
|
||||||
|
$t5_id = $e6_ids['transaction_id'];
|
||||||
|
|
||||||
|
pr(array('checkpoint' => 'Posted Ledger Entry e6',
|
||||||
|
compact('e6_ids', 'amount')));
|
||||||
|
|
||||||
|
$t6_id = null;
|
||||||
|
foreach ($e3['DebitReconciliationLedgerEntry'] AS $e2) {
|
||||||
|
foreach ($e2['DebitReconciliationLedgerEntry2'] AS $e1) {
|
||||||
|
$amount = -1*$e1['Reconciliation']['amount'];
|
||||||
|
|
||||||
|
// post new e7
|
||||||
|
$e7_ids = $A->postLedgerEntry
|
||||||
|
(array('transaction_id' => $t6_id),
|
||||||
|
null,
|
||||||
|
array('debit_ledger_id' => $A->currentLedgerID($receipt_account_id),
|
||||||
|
'credit_ledger_id' => $A->currentLedgerID($ar_account_id),
|
||||||
|
'effective_date' => $stamp,
|
||||||
|
'amount' => $amount,
|
||||||
|
'lease_id' => $e1['lease_id'],
|
||||||
|
'customer_id' => $e1['customer_id'],
|
||||||
|
'comment' => "NSF Receipt; Monetary Source #{$id}",
|
||||||
|
),
|
||||||
|
array('debit' => array
|
||||||
|
(array('LedgerEntry' =>
|
||||||
|
array('id' => $e6_ids['id'],
|
||||||
|
'amount' => $amount))),
|
||||||
|
|
||||||
|
'credit' => array
|
||||||
|
(array('LedgerEntry' =>
|
||||||
|
array('id' => $e1['id'],
|
||||||
|
'amount' => $amount))),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($e7_ids['error'])
|
||||||
|
return null;
|
||||||
|
$t6_id = $e7_ids['transaction_id'];
|
||||||
|
|
||||||
|
pr(array('checkpoint' => 'Posted Ledger Entry e7',
|
||||||
|
compact('e7_ids', 'amount')));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cheat for now
|
||||||
|
$customer_id = $source['LedgerEntry'][0]['customer_id'];
|
||||||
|
$lease_id = null;
|
||||||
|
|
||||||
|
// post new e8
|
||||||
|
$e8_ids = $A->postLedgerEntry
|
||||||
|
(array('transaction_id' => $t6_id),
|
||||||
|
null,
|
||||||
|
array('debit_ledger_id' => $A->currentLedgerID($ar_account_id),
|
||||||
|
'credit_ledger_id' => $A->currentLedgerID($nsf_fee_account_id),
|
||||||
|
'effective_date' => $stamp,
|
||||||
|
'amount' => 35,
|
||||||
|
'lease_id' => $lease_id,
|
||||||
|
'customer_id' => $customer_id,
|
||||||
|
'comment' => "NSF Fee; Monetary Source #{$id}",
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($e8_ids['error'])
|
||||||
|
return null;
|
||||||
|
|
||||||
|
pr(array('checkpoint' => 'Posted Ledger Entry e8',
|
||||||
|
compact('e8_ids')));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
<?php
|
|
||||||
class Payment extends AppModel {
|
|
||||||
|
|
||||||
var $name = 'Payment';
|
|
||||||
var $validate = array(
|
|
||||||
'id' => array('numeric'),
|
|
||||||
'receipt_id' => array('numeric'),
|
|
||||||
'payment_type_id' => array('numeric'),
|
|
||||||
'amount' => array('money')
|
|
||||||
);
|
|
||||||
|
|
||||||
//The Associations below have been created with all possible keys, those that are not needed can be removed
|
|
||||||
var $belongsTo = array(
|
|
||||||
'Receipt' => array(
|
|
||||||
'className' => 'Receipt',
|
|
||||||
'foreignKey' => 'receipt_id',
|
|
||||||
'conditions' => '',
|
|
||||||
'fields' => '',
|
|
||||||
'order' => ''
|
|
||||||
),
|
|
||||||
'PaymentType' => array(
|
|
||||||
'className' => 'PaymentType',
|
|
||||||
'foreignKey' => 'payment_type_id',
|
|
||||||
'conditions' => '',
|
|
||||||
'fields' => '',
|
|
||||||
'order' => ''
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
<?php
|
|
||||||
class PaymentType extends AppModel {
|
|
||||||
|
|
||||||
var $name = 'PaymentType';
|
|
||||||
var $validate = array(
|
|
||||||
'id' => array('numeric'),
|
|
||||||
'name' => array('notempty'),
|
|
||||||
'tillable' => array('boolean')
|
|
||||||
);
|
|
||||||
|
|
||||||
//The Associations below have been created with all possible keys, those that are not needed can be removed
|
|
||||||
var $hasMany = array(
|
|
||||||
'Payment' => array(
|
|
||||||
'className' => 'Payment',
|
|
||||||
'foreignKey' => 'payment_type_id',
|
|
||||||
'dependent' => false,
|
|
||||||
'conditions' => '',
|
|
||||||
'fields' => '',
|
|
||||||
'order' => '',
|
|
||||||
'limit' => '',
|
|
||||||
'offset' => '',
|
|
||||||
'exclusive' => '',
|
|
||||||
'finderQuery' => '',
|
|
||||||
'counterQuery' => ''
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
<?php
|
|
||||||
class Receipt extends AppModel {
|
|
||||||
|
|
||||||
var $name = 'Receipt';
|
|
||||||
var $validate = array(
|
|
||||||
'id' => array('numeric'),
|
|
||||||
'stamp' => array('time')
|
|
||||||
);
|
|
||||||
|
|
||||||
//The Associations below have been created with all possible keys, those that are not needed can be removed
|
|
||||||
var $hasMany = array(
|
|
||||||
'Payment' => array(
|
|
||||||
'className' => 'Payment',
|
|
||||||
'foreignKey' => 'receipt_id',
|
|
||||||
'dependent' => false,
|
|
||||||
'conditions' => '',
|
|
||||||
'fields' => '',
|
|
||||||
'order' => '',
|
|
||||||
'limit' => '',
|
|
||||||
'offset' => '',
|
|
||||||
'exclusive' => '',
|
|
||||||
'finderQuery' => '',
|
|
||||||
'counterQuery' => ''
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
var $hasAndBelongsToMany = array(
|
|
||||||
'Charge' => array(
|
|
||||||
'className' => 'Charge',
|
|
||||||
'joinTable' => 'charges_receipts',
|
|
||||||
'foreignKey' => 'receipt_id',
|
|
||||||
'associationForeignKey' => 'charge_id',
|
|
||||||
'unique' => true,
|
|
||||||
'conditions' => '',
|
|
||||||
'fields' => '',
|
|
||||||
'order' => '',
|
|
||||||
'limit' => '',
|
|
||||||
'offset' => '',
|
|
||||||
'finderQuery' => '',
|
|
||||||
'deleteQuery' => '',
|
|
||||||
'insertQuery' => ''
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
15
site/models/reconciliation.php
Normal file
15
site/models/reconciliation.php
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
class Reconciliation extends AppModel {
|
||||||
|
|
||||||
|
var $belongsTo = array(
|
||||||
|
'DebitLedgerEntry' => array(
|
||||||
|
'className' => 'LedgerEntry',
|
||||||
|
//'foreignKey' => 'credit_ledger_entry_id',
|
||||||
|
),
|
||||||
|
'CreditLedgerEntry' => array(
|
||||||
|
'className' => 'LedgerEntry',
|
||||||
|
//'foreignKey' => 'credit_ledger_entry_id',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -7,34 +7,9 @@ class Site extends AppModel {
|
|||||||
'name' => array('notempty')
|
'name' => array('notempty')
|
||||||
);
|
);
|
||||||
|
|
||||||
//The Associations below have been created with all possible keys, those that are not needed can be removed
|
|
||||||
var $hasMany = array(
|
var $hasMany = array(
|
||||||
'SiteArea' => array(
|
'SiteArea',
|
||||||
'className' => 'SiteArea',
|
'SiteOption',
|
||||||
'foreignKey' => 'site_id',
|
|
||||||
'dependent' => false,
|
|
||||||
'conditions' => '',
|
|
||||||
'fields' => '',
|
|
||||||
'order' => '',
|
|
||||||
'limit' => '',
|
|
||||||
'offset' => '',
|
|
||||||
'exclusive' => '',
|
|
||||||
'finderQuery' => '',
|
|
||||||
'counterQuery' => ''
|
|
||||||
),
|
|
||||||
'SiteOption' => array(
|
|
||||||
'className' => 'SiteOption',
|
|
||||||
'foreignKey' => 'site_id',
|
|
||||||
'dependent' => false,
|
|
||||||
'conditions' => '',
|
|
||||||
'fields' => '',
|
|
||||||
'order' => '',
|
|
||||||
'limit' => '',
|
|
||||||
'offset' => '',
|
|
||||||
'exclusive' => '',
|
|
||||||
'finderQuery' => '',
|
|
||||||
'counterQuery' => ''
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,26 +8,12 @@ class SiteArea extends AppModel {
|
|||||||
'name' => array('notempty')
|
'name' => array('notempty')
|
||||||
);
|
);
|
||||||
|
|
||||||
//The Associations below have been created with all possible keys, those that are not needed can be removed
|
|
||||||
var $belongsTo = array(
|
var $belongsTo = array(
|
||||||
'Site' => array(
|
'Site',
|
||||||
'className' => 'Site',
|
|
||||||
'foreignKey' => 'site_id',
|
|
||||||
'conditions' => '',
|
|
||||||
'fields' => '',
|
|
||||||
'order' => ''
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
var $hasOne = array(
|
var $hasOne = array(
|
||||||
'Map' => array(
|
'Map',
|
||||||
'className' => 'Map',
|
|
||||||
'foreignKey' => 'site_area_id',
|
|
||||||
'dependent' => false,
|
|
||||||
'conditions' => '',
|
|
||||||
'fields' => '',
|
|
||||||
'order' => ''
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
108
site/models/transaction.php
Normal file
108
site/models/transaction.php
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
<?php
|
||||||
|
class Transaction extends AppModel {
|
||||||
|
|
||||||
|
var $name = 'Transaction';
|
||||||
|
|
||||||
|
var $validate = array(
|
||||||
|
'stamp' => array('date')
|
||||||
|
);
|
||||||
|
|
||||||
|
var $belongsTo = array(
|
||||||
|
);
|
||||||
|
|
||||||
|
var $hasMany = array(
|
||||||
|
'LedgerEntry',
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: addInvoice
|
||||||
|
* - Adds a new invoice transaction
|
||||||
|
*/
|
||||||
|
|
||||||
|
function addInvoice($data, $customer_id, $lease_id = null) {
|
||||||
|
// Create some models for convenience
|
||||||
|
$A = new Account();
|
||||||
|
|
||||||
|
//pr(compact('data', 'customer_id', 'lease_id'));
|
||||||
|
|
||||||
|
// Assume this will succeed
|
||||||
|
$ret = true;
|
||||||
|
|
||||||
|
// Determine the total charges on the invoice
|
||||||
|
$grand_total = 0;
|
||||||
|
foreach ($data['LedgerEntry'] AS $entry)
|
||||||
|
$grand_total += $entry['amount'];
|
||||||
|
|
||||||
|
// Go through the entered charges
|
||||||
|
$invoice_transaction = array_intersect_key($data, array('Transaction'=>1, 'transaction_id'=>1));
|
||||||
|
foreach ($data['LedgerEntry'] AS $entry) {
|
||||||
|
//pr(compact('entry'));
|
||||||
|
// Create the receipt entry, and reconcile the credit side
|
||||||
|
// of the double-entry (which should be A/R) as a payment.
|
||||||
|
$ids = $this->LedgerEntry->Ledger->Account->postLedgerEntry
|
||||||
|
($invoice_transaction,
|
||||||
|
array_intersect_key($entry, array('MonetarySource'=>1))
|
||||||
|
+ array_intersect_key($entry, array('account_id'=>1)),
|
||||||
|
array('debit_ledger_id' => $A->currentLedgerID($A->accountReceivableAccountID()),
|
||||||
|
'credit_ledger_id' => $A->currentLedgerID($entry['account_id']),
|
||||||
|
'customer_id' => $customer_id,
|
||||||
|
'lease_id' => $lease_id)
|
||||||
|
+ $entry
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($ids['error'])
|
||||||
|
$ret = false;
|
||||||
|
|
||||||
|
$invoice_transaction = array_intersect_key($ids, array('transaction_id'=>1));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: addReceipt
|
||||||
|
* - Adds a new receipt transaction
|
||||||
|
*/
|
||||||
|
|
||||||
|
function addReceipt($data, $customer_id, $lease_id = null) {
|
||||||
|
// Create some models for convenience
|
||||||
|
$A = new Account();
|
||||||
|
|
||||||
|
// Assume this will succeed
|
||||||
|
$ret = true;
|
||||||
|
|
||||||
|
// Go through the entered payments
|
||||||
|
$receipt_transaction = array_intersect_key($data, array('Transaction'=>1, 'transaction_id'=>1));
|
||||||
|
foreach ($data['LedgerEntry'] AS $entry) {
|
||||||
|
// Create the receipt entry, and reconcile the credit side
|
||||||
|
// of the double-entry (which should be A/R) as a payment.
|
||||||
|
$ids = $this->LedgerEntry->Ledger->Account->postLedgerEntry
|
||||||
|
($receipt_transaction,
|
||||||
|
array_intersect_key($entry, array('MonetarySource'=>1))
|
||||||
|
+ array_intersect_key($entry, array('account_id'=>1)),
|
||||||
|
array('debit_ledger_id' => $A->currentLedgerID($entry['account_id']),
|
||||||
|
'credit_ledger_id' => $A->currentLedgerID($A->receiptAccountID()),
|
||||||
|
'customer_id' => $customer_id,
|
||||||
|
'lease_id' => $lease_id)
|
||||||
|
+ $entry,
|
||||||
|
'receipt');
|
||||||
|
|
||||||
|
if ($ids['error'])
|
||||||
|
$ret = false;
|
||||||
|
|
||||||
|
$receipt_transaction = array_intersect_key($ids,
|
||||||
|
array('transaction_id'=>1,
|
||||||
|
'split_transaction_id'=>1));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -13,67 +13,107 @@ class Unit extends AppModel {
|
|||||||
);
|
);
|
||||||
|
|
||||||
var $belongsTo = array(
|
var $belongsTo = array(
|
||||||
'UnitSize' => array(
|
'UnitSize',
|
||||||
'className' => 'UnitSize',
|
);
|
||||||
'foreignKey' => 'unit_size_id',
|
|
||||||
'conditions' => '',
|
var $hasOne = array(
|
||||||
'fields' => '',
|
'CurrentLease' => array(
|
||||||
'order' => ''
|
'className' => 'Lease',
|
||||||
|
'conditions' => 'CurrentLease.moveout_date IS NULL',
|
||||||
),
|
),
|
||||||
/* 'Map' => array( */
|
|
||||||
/* 'className' => 'MapsUnit', */
|
|
||||||
/* 'foreignKey' => 'unit_id', */
|
|
||||||
/* 'conditions' => '', */
|
|
||||||
/* 'fields' => '', */
|
|
||||||
/* 'order' => '' */
|
|
||||||
/* ) */
|
|
||||||
);
|
);
|
||||||
|
|
||||||
var $hasMany = array(
|
var $hasMany = array(
|
||||||
'Lease' => array(
|
'Lease',
|
||||||
'className' => 'Lease',
|
|
||||||
'foreignKey' => 'unit_id',
|
|
||||||
'dependent' => false,
|
|
||||||
'conditions' => '',
|
|
||||||
'fields' => '',
|
|
||||||
'order' => '',
|
|
||||||
'limit' => '',
|
|
||||||
'offset' => '',
|
|
||||||
'exclusive' => '',
|
|
||||||
'finderQuery' => '',
|
|
||||||
'counterQuery' => ''
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
function statusEnums() {
|
/**************************************************************************
|
||||||
static $status_enums;
|
**************************************************************************
|
||||||
if (!isset($status_enums))
|
**************************************************************************
|
||||||
$status_enums = $this->getEnumValues('status');
|
* helpers: status enumerations
|
||||||
return $status_enums;
|
*/
|
||||||
}
|
|
||||||
|
|
||||||
function statusValue($enum) {
|
function statusEnums() {
|
||||||
$enums = $this->statusEnums();
|
static $status_enums;
|
||||||
return $enums[$enum];
|
if (!isset($status_enums))
|
||||||
}
|
$status_enums = $this->getEnumValues('status');
|
||||||
|
return $status_enums;
|
||||||
|
}
|
||||||
|
|
||||||
function occupiedEnumValue() {
|
function activeStatusEnums() {
|
||||||
return statusValue('OCCUPIED');
|
return array_diff_key($this->statusEnums(), array(''=>1, 'DELETED'=>1));
|
||||||
}
|
}
|
||||||
|
|
||||||
function conditionOccupied() {
|
function statusValue($enum) {
|
||||||
return ('Unit.status >= ' . $this->statusValue('OCCUPIED'));
|
$enums = $this->statusEnums();
|
||||||
}
|
return $enums[$enum];
|
||||||
|
}
|
||||||
|
|
||||||
function conditionVacant() {
|
function occupiedEnumValue() {
|
||||||
return ('Unit.status BETWEEN ' .
|
return statusValue('OCCUPIED');
|
||||||
($this->statusValue('UNAVAILABLE')+1) .
|
}
|
||||||
' AND ' .
|
|
||||||
($this->statusValue('OCCUPIED')-1));
|
|
||||||
}
|
|
||||||
|
|
||||||
function conditionUnavailable() {
|
function conditionOccupied() {
|
||||||
return ('Unit.status <= ' . $this->statusValue('UNAVAILABLE'));
|
return ('Unit.status >= ' . $this->statusValue('OCCUPIED'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function conditionVacant() {
|
||||||
|
return ('Unit.status BETWEEN ' .
|
||||||
|
($this->statusValue('UNAVAILABLE')+1) .
|
||||||
|
' AND ' .
|
||||||
|
($this->statusValue('OCCUPIED')-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
function conditionUnavailable() {
|
||||||
|
return ('Unit.status <= ' . $this->statusValue('UNAVAILABLE'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: updateStatus
|
||||||
|
* - Update the given unit to the given status
|
||||||
|
*/
|
||||||
|
function updateStatus($id, $status) {
|
||||||
|
$this->id = $id;
|
||||||
|
//pr(compact('id', 'status'));
|
||||||
|
$this->saveField('status', $status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: stats
|
||||||
|
* - Returns summary data from the requested customer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function stats($id = null) {
|
||||||
|
if (!$id)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// Get the basic information necessary
|
||||||
|
$unit = $this->find('first',
|
||||||
|
array('contain' => array
|
||||||
|
('Lease' => array
|
||||||
|
('fields' => array('Lease.id')),
|
||||||
|
|
||||||
|
'CurrentLease' => array
|
||||||
|
('fields' => array('CurrentLease.id'))),
|
||||||
|
|
||||||
|
'conditions' => array
|
||||||
|
(array('Unit.id' => $id)),
|
||||||
|
));
|
||||||
|
|
||||||
|
// Get the stats for the current lease
|
||||||
|
$stats['CurrentLease'] = $this->Lease->stats($unit['CurrentLease']['id']);
|
||||||
|
|
||||||
|
// Sum the stats for all leases together
|
||||||
|
foreach ($unit['Lease'] AS $lease) {
|
||||||
|
$this->statsMerge($stats['Lease'], $this->Lease->stats($lease['id']));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the collection
|
||||||
|
return $stats;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,29 +14,11 @@ class UnitSize extends AppModel {
|
|||||||
);
|
);
|
||||||
|
|
||||||
var $belongsTo = array(
|
var $belongsTo = array(
|
||||||
'UnitType' => array(
|
'UnitType',
|
||||||
'className' => 'UnitType',
|
|
||||||
'foreignKey' => 'unit_type_id',
|
|
||||||
'conditions' => '',
|
|
||||||
'fields' => '',
|
|
||||||
'order' => ''
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
var $hasMany = array(
|
var $hasMany = array(
|
||||||
'Unit' => array(
|
'Unit',
|
||||||
'className' => 'Unit',
|
|
||||||
'foreignKey' => 'unit_size_id',
|
|
||||||
'dependent' => false,
|
|
||||||
'conditions' => '',
|
|
||||||
'fields' => '',
|
|
||||||
'order' => '',
|
|
||||||
'limit' => '',
|
|
||||||
'offset' => '',
|
|
||||||
'exclusive' => '',
|
|
||||||
'finderQuery' => '',
|
|
||||||
'counterQuery' => ''
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,19 +9,7 @@ class UnitType extends AppModel {
|
|||||||
);
|
);
|
||||||
|
|
||||||
var $hasMany = array(
|
var $hasMany = array(
|
||||||
'UnitSize' => array(
|
'UnitSize',
|
||||||
'className' => 'UnitSize',
|
|
||||||
'foreignKey' => 'unit_type_id',
|
|
||||||
'dependent' => false,
|
|
||||||
'conditions' => '',
|
|
||||||
'fields' => '',
|
|
||||||
'order' => '',
|
|
||||||
'limit' => '',
|
|
||||||
'offset' => '',
|
|
||||||
'exclusive' => '',
|
|
||||||
'finderQuery' => '',
|
|
||||||
'counterQuery' => ''
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
5
site/plugins/debug_kit/README
Normal file
5
site/plugins/debug_kit/README
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
To install copy the debug_kit directory to the plugins folder and include the toolbar component in your app_controller.php:
|
||||||
|
|
||||||
|
$components = array('DebugKit.Toolbar');
|
||||||
|
|
||||||
|
+ Set debug mode to at least 1.
|
||||||
0
site/plugins/debug_kit/controllers/components/empty
Normal file
0
site/plugins/debug_kit/controllers/components/empty
Normal file
471
site/plugins/debug_kit/controllers/components/toolbar.php
Normal file
471
site/plugins/debug_kit/controllers/components/toolbar.php
Normal file
@@ -0,0 +1,471 @@
|
|||||||
|
<?php
|
||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* DebugKit DebugToolbar Component
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||||
|
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* 1785 E. Sahara Avenue, Suite 490-204
|
||||||
|
* Las Vegas, Nevada 89104
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||||
|
* @package cake
|
||||||
|
* @subpackage cake.cake.libs.
|
||||||
|
* @since CakePHP v 1.2.0.4487
|
||||||
|
* @version $Revision$
|
||||||
|
* @modifiedby $LastChangedBy$
|
||||||
|
* @lastmodified $Date$
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
class ToolbarComponent extends Object {
|
||||||
|
/**
|
||||||
|
* Controller instance reference
|
||||||
|
*
|
||||||
|
* @var object
|
||||||
|
*/
|
||||||
|
var $controller;
|
||||||
|
/**
|
||||||
|
* Components used by DebugToolbar
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
var $components = array('RequestHandler');
|
||||||
|
/**
|
||||||
|
* The default panels the toolbar uses.
|
||||||
|
* which panels are used can be configured when attaching the component
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
var $_defaultPanels = array('session', 'request', 'sqlLog', 'timer', 'log', 'memory', 'variables');
|
||||||
|
/**
|
||||||
|
* Loaded panel objects.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
var $panels = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fallback for javascript settings
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
**/
|
||||||
|
var $_defaultJavascript = array(
|
||||||
|
'behavior' => '/debug_kit/js/js_debug_toolbar'
|
||||||
|
);
|
||||||
|
/**
|
||||||
|
* javascript files component will be using.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
**/
|
||||||
|
var $javascript = array();
|
||||||
|
/**
|
||||||
|
* initialize
|
||||||
|
*
|
||||||
|
* If debug is off the component will be disabled and not do any further time tracking
|
||||||
|
* or load the toolbar helper.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
**/
|
||||||
|
function initialize(&$controller, $settings) {
|
||||||
|
if (Configure::read('debug') == 0) {
|
||||||
|
$this->enabled = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
App::import('Vendor', 'DebugKit.DebugKitDebugger');
|
||||||
|
|
||||||
|
DebugKitDebugger::startTimer('componentInit', __('Component initialization and startup', true));
|
||||||
|
if (!isset($settings['panels'])) {
|
||||||
|
$settings['panels'] = $this->_defaultPanels;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($settings['javascript'])) {
|
||||||
|
$settings['javascript'] = $this->_setJavascript($settings['javascript']);
|
||||||
|
} else {
|
||||||
|
$settings['javascript'] = $this->_defaultJavascript;
|
||||||
|
}
|
||||||
|
$this->_loadPanels($settings['panels']);
|
||||||
|
unset($settings['panels']);
|
||||||
|
|
||||||
|
$this->_set($settings);
|
||||||
|
$this->controller =& $controller;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component Startup
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
**/
|
||||||
|
function startup(&$controller) {
|
||||||
|
$currentViewClass = $controller->view;
|
||||||
|
$this->_makeViewClass($currentViewClass);
|
||||||
|
$controller->view = 'DebugKit.Debug';
|
||||||
|
if (!isset($controller->params['url']['ext']) || (isset($controller->params['url']['ext']) && $controller->params['url']['ext'] == 'html')) {
|
||||||
|
$format = 'Html';
|
||||||
|
} else {
|
||||||
|
$format = 'FirePhp';
|
||||||
|
}
|
||||||
|
$controller->helpers['DebugKit.Toolbar'] = array('output' => sprintf('DebugKit.%sToolbar', $format));
|
||||||
|
$panels = array_keys($this->panels);
|
||||||
|
foreach ($panels as $panelName) {
|
||||||
|
$this->panels[$panelName]->startup($controller);
|
||||||
|
}
|
||||||
|
DebugKitDebugger::stopTimer('componentInit');
|
||||||
|
DebugKitDebugger::startTimer('controllerAction', __('Controller Action', true));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* beforeRender callback
|
||||||
|
*
|
||||||
|
* Calls beforeRender on all the panels and set the aggregate to the controller.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function beforeRender(&$controller) {
|
||||||
|
DebugKitDebugger::stopTimer('controllerAction');
|
||||||
|
$vars = array();
|
||||||
|
$panels = array_keys($this->panels);
|
||||||
|
|
||||||
|
foreach ($panels as $panelName) {
|
||||||
|
$panel =& $this->panels[$panelName];
|
||||||
|
$vars[$panelName]['content'] = $panel->beforeRender($controller);
|
||||||
|
$elementName = Inflector::underscore($panelName) . '_panel';
|
||||||
|
if (isset($panel->elementName)) {
|
||||||
|
$elementName = $panel->elementName;
|
||||||
|
}
|
||||||
|
$vars[$panelName]['elementName'] = $elementName;
|
||||||
|
$vars[$panelName]['plugin'] = $panel->plugin;
|
||||||
|
$vars[$panelName]['disableTimer'] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$controller->set(array('debugToolbarPanels' => $vars, 'debugToolbarJavascript' => $this->javascript));
|
||||||
|
DebugKitDebugger::startTimer('controllerRender', __('Render Controller Action', true));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load Panels used in the debug toolbar
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @access protected
|
||||||
|
**/
|
||||||
|
function _loadPanels($panels) {
|
||||||
|
foreach ($panels as $panel) {
|
||||||
|
$className = $panel . 'Panel';
|
||||||
|
if (!class_exists($className) && !App::import('Vendor', $className)) {
|
||||||
|
trigger_error(sprintf(__('Could not load DebugToolbar panel %s', true), $panel), E_USER_WARNING);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$panelObj =& new $className();
|
||||||
|
if (is_subclass_of($panelObj, 'DebugPanel') || is_subclass_of($panelObj, 'debugpanel')) {
|
||||||
|
$this->panels[$panel] =& $panelObj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the javascript to user scripts.
|
||||||
|
*
|
||||||
|
* Set either script key to false to exclude it from the rendered layout.
|
||||||
|
*
|
||||||
|
* @param array $scripts Javascript config information
|
||||||
|
* @return array
|
||||||
|
* @access protected
|
||||||
|
**/
|
||||||
|
function _setJavascript($scripts) {
|
||||||
|
$behavior = false;
|
||||||
|
if (!is_array($scripts)) {
|
||||||
|
$scripts = (array)$scripts;
|
||||||
|
}
|
||||||
|
if (isset($scripts[0])) {
|
||||||
|
$behavior = $scripts[0];
|
||||||
|
}
|
||||||
|
if (isset($scripts['behavior'])) {
|
||||||
|
$behavior = $scripts['behavior'];
|
||||||
|
}
|
||||||
|
if (!$behavior) {
|
||||||
|
return array();
|
||||||
|
} elseif ($behavior === true) {
|
||||||
|
$behavior = 'js';
|
||||||
|
}
|
||||||
|
if (strpos($behavior, '/') !== 0) {
|
||||||
|
$behavior .= '_debug_toolbar';
|
||||||
|
}
|
||||||
|
$pluginFile = APP . 'plugins' . DS . 'debug_kit' . DS . 'vendors' . DS . 'js' . DS . $behavior . '.js';
|
||||||
|
if (file_exists($pluginFile)) {
|
||||||
|
$behavior = '/debug_kit/js/' . $behavior . '.js';
|
||||||
|
}
|
||||||
|
return compact('behavior');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Makes the DoppleGangerView class if it doesn't already exist.
|
||||||
|
* This allows DebugView to be compatible with all view classes.
|
||||||
|
*
|
||||||
|
* @param string $baseClassName
|
||||||
|
* @access protected
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function _makeViewClass($baseClassName) {
|
||||||
|
if (!class_exists('DoppelGangerView')) {
|
||||||
|
App::import('View', $baseClassName);
|
||||||
|
if (strpos('View', $baseClassName) === false) {
|
||||||
|
$baseClassName .= 'View';
|
||||||
|
}
|
||||||
|
$class = "class DoppelGangerView extends $baseClassName {}";
|
||||||
|
eval($class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Debug Panel
|
||||||
|
*
|
||||||
|
* Abstract class for debug panels.
|
||||||
|
*
|
||||||
|
* @package cake.debug_kit
|
||||||
|
*/
|
||||||
|
class DebugPanel extends Object {
|
||||||
|
/**
|
||||||
|
* Defines which plugin this panel is from so the element can be located.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
var $plugin = null;
|
||||||
|
/**
|
||||||
|
* startup the panel
|
||||||
|
*
|
||||||
|
* Pull information from the controller / request
|
||||||
|
*
|
||||||
|
* @param object $controller Controller reference.
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function startup(&$controller) { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare output vars before Controller Rendering.
|
||||||
|
*
|
||||||
|
* @param object $controller Controller reference.
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function beforeRender(&$controller) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variables Panel
|
||||||
|
*
|
||||||
|
* Provides debug information on the View variables.
|
||||||
|
*
|
||||||
|
* @package cake.debug_kit.panels
|
||||||
|
**/
|
||||||
|
class VariablesPanel extends DebugPanel {
|
||||||
|
var $plugin = 'debug_kit';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Session Panel
|
||||||
|
*
|
||||||
|
* Provides debug information on the Session contents.
|
||||||
|
*
|
||||||
|
* @package cake.debug_kit.panels
|
||||||
|
**/
|
||||||
|
class SessionPanel extends DebugPanel {
|
||||||
|
var $plugin = 'debug_kit';
|
||||||
|
/**
|
||||||
|
* beforeRender callback
|
||||||
|
*
|
||||||
|
* @param object $controller
|
||||||
|
* @access public
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
function beforeRender(&$controller) {
|
||||||
|
return $controller->Session->read();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request Panel
|
||||||
|
*
|
||||||
|
* Provides debug information on the Current request params.
|
||||||
|
*
|
||||||
|
* @package cake.debug_kit.panels
|
||||||
|
**/
|
||||||
|
class RequestPanel extends DebugPanel {
|
||||||
|
var $plugin = 'debug_kit';
|
||||||
|
/**
|
||||||
|
* beforeRender callback - grabs request params
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
**/
|
||||||
|
function beforeRender(&$controller) {
|
||||||
|
$out = array();
|
||||||
|
$out['params'] = $controller->params;
|
||||||
|
if (isset($controller->Cookie)) {
|
||||||
|
$out['cookie'] = $controller->Cookie->read();
|
||||||
|
}
|
||||||
|
$out['get'] = $_GET;
|
||||||
|
$out['currentRoute'] = Router::currentRoute();
|
||||||
|
return $out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer Panel
|
||||||
|
*
|
||||||
|
* Provides debug information on all timers used in a request.
|
||||||
|
*
|
||||||
|
* @package cake.debug_kit.panels
|
||||||
|
**/
|
||||||
|
class TimerPanel extends DebugPanel {
|
||||||
|
var $plugin = 'debug_kit';
|
||||||
|
/**
|
||||||
|
* startup - add in necessary helpers
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function startup(&$controller) {
|
||||||
|
if (!in_array('Number', $controller->helpers)) {
|
||||||
|
$controller->helpers[] = 'Number';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Memory Panel
|
||||||
|
*
|
||||||
|
* Provides debug information on the memory consumption.
|
||||||
|
*
|
||||||
|
* @package cake.debug_kit.panels
|
||||||
|
**/
|
||||||
|
class MemoryPanel extends DebugPanel {
|
||||||
|
var $plugin = 'debug_kit';
|
||||||
|
/**
|
||||||
|
* startup - add in necessary helpers
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function startup(&$controller) {
|
||||||
|
if (!in_array('Number', $controller->helpers)) {
|
||||||
|
$controller->helpers[] = 'Number';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sqlLog Panel
|
||||||
|
*
|
||||||
|
* Provides debug information on the SQL logs and provides links to an ajax explain interface.
|
||||||
|
*
|
||||||
|
* @package cake.debug_kit.panels
|
||||||
|
**/
|
||||||
|
class sqlLogPanel extends DebugPanel {
|
||||||
|
var $plugin = 'debug_kit';
|
||||||
|
|
||||||
|
var $dbConfigs = array();
|
||||||
|
/**
|
||||||
|
* get db configs.
|
||||||
|
*
|
||||||
|
* @param string $controller
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function startUp(&$controller) {
|
||||||
|
if (!class_exists('ConnectionManager')) {
|
||||||
|
$this->dbConfigs = array();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$this->dbConfigs = ConnectionManager::sourceList();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Get Sql Logs for each DB config
|
||||||
|
*
|
||||||
|
* @param string $controller
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function beforeRender(&$controller) {
|
||||||
|
$queryLogs = array();
|
||||||
|
if (!class_exists('ConnectionManager')) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
foreach ($this->dbConfigs as $configName) {
|
||||||
|
$db =& ConnectionManager::getDataSource($configName);
|
||||||
|
if ($db->isInterfaceSupported('showLog')) {
|
||||||
|
ob_start();
|
||||||
|
$db->showLog();
|
||||||
|
$queryLogs[$configName] = ob_get_clean();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $queryLogs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log Panel - Reads log entries made this request.
|
||||||
|
*
|
||||||
|
* @package cake.debug_kit.panels
|
||||||
|
*/
|
||||||
|
class LogPanel extends DebugPanel {
|
||||||
|
var $plugin = 'debug_kit';
|
||||||
|
/**
|
||||||
|
* Log files to scan
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
var $logFiles = array('error.log', 'debug.log');
|
||||||
|
/**
|
||||||
|
* startup
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function startup(&$controller) {
|
||||||
|
if (!class_exists('CakeLog')) {
|
||||||
|
App::import('Core', 'Log');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* beforeRender Callback
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
**/
|
||||||
|
function beforeRender(&$controller) {
|
||||||
|
$this->startTime = DebugKitDebugger::requestStartTime();
|
||||||
|
$this->currentTime = DebugKitDebugger::requestTime();
|
||||||
|
$out = array();
|
||||||
|
foreach ($this->logFiles as $log) {
|
||||||
|
$file = LOGS . $log;
|
||||||
|
if (!file_exists($file)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$out[$log] = $this->_parseFile($file);
|
||||||
|
}
|
||||||
|
return $out;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* parse a log file and find the relevant entries
|
||||||
|
*
|
||||||
|
* @param string $filename Name of file to read
|
||||||
|
* @access protected
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
function _parseFile($filename) {
|
||||||
|
$file =& new File($filename);
|
||||||
|
$contents = $file->read();
|
||||||
|
$timePattern = '/(\d{4}-\d{2}\-\d{2}\s\d{1,2}\:\d{1,2}\:\d{1,2})/';
|
||||||
|
$chunks = preg_split($timePattern, $contents, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
|
||||||
|
for ($i = 0, $len = count($chunks); $i < $len; $i += 2) {
|
||||||
|
if (strtotime($chunks[$i]) < $this->startTime) {
|
||||||
|
unset($chunks[$i], $chunks[$i + 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return array_values($chunks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
32
site/plugins/debug_kit/debug_kit_app_controller.php
Normal file
32
site/plugins/debug_kit/debug_kit_app_controller.php
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* Debug Kit App Controller
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||||
|
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* 1785 E. Sahara Avenue, Suite 490-204
|
||||||
|
* Las Vegas, Nevada 89104
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||||
|
* @package cake
|
||||||
|
* @subpackage cake.cake.libs.
|
||||||
|
* @since CakePHP v 1.2.0.4487
|
||||||
|
* @version $Revision$
|
||||||
|
* @modifiedby $LastChangedBy$
|
||||||
|
* @lastmodified $Date$
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
class DebugKitAppController extends AppController {
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
32
site/plugins/debug_kit/debug_kit_app_model.php
Normal file
32
site/plugins/debug_kit/debug_kit_app_model.php
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* Debug Kit App Model
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||||
|
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* 1785 E. Sahara Avenue, Suite 490-204
|
||||||
|
* Las Vegas, Nevada 89104
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||||
|
* @package cake
|
||||||
|
* @subpackage cake.cake.libs.
|
||||||
|
* @since CakePHP v 1.2.0.4487
|
||||||
|
* @version $Revision$
|
||||||
|
* @modifiedby $LastChangedBy$
|
||||||
|
* @lastmodified $Date$
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
class DebugKitAppModel extends AppModel {
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
0
site/plugins/debug_kit/models/empty
Normal file
0
site/plugins/debug_kit/models/empty
Normal file
@@ -0,0 +1,323 @@
|
|||||||
|
<?php
|
||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* DebugToolbar Test
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||||
|
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* 1785 E. Sahara Avenue, Suite 490-204
|
||||||
|
* Las Vegas, Nevada 89104
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||||
|
* @package cake
|
||||||
|
* @subpackage cake.cake.libs.
|
||||||
|
* @since CakePHP v 1.2.0.4487
|
||||||
|
* @version $Revision$
|
||||||
|
* @modifiedby $LastChangedBy$
|
||||||
|
* @lastmodified $Date$
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
App::import('Component', 'DebugKit.Toolbar');
|
||||||
|
|
||||||
|
class TestToolbarComponent extends ToolbarComponent {
|
||||||
|
|
||||||
|
function loadPanels($panels) {
|
||||||
|
$this->_loadPanels($panels);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Mock::generate('DebugPanel');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DebugToolbar Test case
|
||||||
|
*/
|
||||||
|
class DebugToolbarTestCase extends CakeTestCase {
|
||||||
|
|
||||||
|
function setUp() {
|
||||||
|
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
|
||||||
|
Router::parse('/');
|
||||||
|
$this->Controller =& ClassRegistry::init('Controller');
|
||||||
|
$this->Controller->Component =& ClassRegistry::init('Component');
|
||||||
|
$this->Controller->Toolbar =& ClassRegistry::init('TestToolBarComponent', 'Component');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test Loading of panel classes
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testLoadPanels() {
|
||||||
|
$this->Controller->Toolbar->loadPanels(array('session', 'request'));
|
||||||
|
$this->assertTrue(is_a($this->Controller->Toolbar->panels['session'], 'SessionPanel'));
|
||||||
|
$this->assertTrue(is_a($this->Controller->Toolbar->panels['request'], 'RequestPanel'));
|
||||||
|
|
||||||
|
$this->expectError();
|
||||||
|
$this->Controller->Toolbar->loadPanels(array('randomNonExisting', 'request'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test loading of vendor panels from test_app folder
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function testVendorPanels() {
|
||||||
|
$_back = Configure::read('vendorPaths');
|
||||||
|
Configure::write('vendorPaths', array(APP . 'plugins' . DS . 'debug_kit' . DS . 'tests' . DS . 'test_app' . DS . 'vendors' . DS));
|
||||||
|
$this->Controller->components = array(
|
||||||
|
'DebugKit.Toolbar' => array(
|
||||||
|
'panels' => array('test'),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$this->Controller->Component->init($this->Controller);
|
||||||
|
$this->Controller->Component->initialize($this->Controller);
|
||||||
|
$this->Controller->Component->startup($this->Controller);
|
||||||
|
$this->assertTrue(isset($this->Controller->Toolbar->panels['test']));
|
||||||
|
$this->assertTrue(is_a($this->Controller->Toolbar->panels['test'], 'TestPanel'));
|
||||||
|
|
||||||
|
Configure::write('vendorPaths', $_back);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test initialize
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @access public
|
||||||
|
**/
|
||||||
|
function testInitialize() {
|
||||||
|
$this->Controller->components = array('DebugKit.Toolbar');
|
||||||
|
$this->Controller->Component->init($this->Controller);
|
||||||
|
$this->Controller->Component->initialize($this->Controller);
|
||||||
|
|
||||||
|
$this->assertFalse(empty($this->Controller->Toolbar->panels));
|
||||||
|
|
||||||
|
$timers = DebugKitDebugger::getTimers();
|
||||||
|
$this->assertTrue(isset($timers['componentInit']));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test startup
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testStartup() {
|
||||||
|
$this->Controller->components = array(
|
||||||
|
'DebugKit.Toolbar' => array(
|
||||||
|
'panels' => array('MockDebug')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$this->Controller->Component->init($this->Controller);
|
||||||
|
$this->Controller->Component->initialize($this->Controller);
|
||||||
|
$this->Controller->Toolbar->panels['MockDebug']->expectOnce('startup');
|
||||||
|
$this->Controller->Toolbar->startup($this->Controller);
|
||||||
|
|
||||||
|
$this->assertEqual(count($this->Controller->Toolbar->panels), 1);
|
||||||
|
$this->assertTrue(isset($this->Controller->helpers['DebugKit.Toolbar']));
|
||||||
|
$this->assertEqual($this->Controller->helpers['DebugKit.Toolbar'], array('output' => 'DebugKit.HtmlToolbar'));
|
||||||
|
|
||||||
|
$timers = DebugKitDebugger::getTimers();
|
||||||
|
$this->assertTrue(isset($timers['controllerAction']));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test Before Render callback
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testBeforeRender() {
|
||||||
|
$this->Controller->components = array(
|
||||||
|
'DebugKit.Toolbar' => array(
|
||||||
|
'panels' => array('MockDebug', 'session')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$this->Controller->Component->init($this->Controller);
|
||||||
|
$this->Controller->Component->initialize($this->Controller);
|
||||||
|
$this->Controller->Toolbar->panels['MockDebug']->expectOnce('beforeRender');
|
||||||
|
$this->Controller->Toolbar->beforeRender($this->Controller);
|
||||||
|
|
||||||
|
$this->assertTrue(isset($this->Controller->viewVars['debugToolbarPanels']));
|
||||||
|
$vars = $this->Controller->viewVars['debugToolbarPanels'];
|
||||||
|
|
||||||
|
$expected = array(
|
||||||
|
'plugin' => 'debug_kit',
|
||||||
|
'elementName' => 'session_panel',
|
||||||
|
'content' => $this->Controller->Session->read(),
|
||||||
|
'disableTimer' => true,
|
||||||
|
);
|
||||||
|
$this->assertEqual($expected, $vars['session']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test alternate javascript library use
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testAlternateJavascript() {
|
||||||
|
$this->Controller->components = array(
|
||||||
|
'DebugKit.Toolbar'
|
||||||
|
);
|
||||||
|
$this->Controller->Component->init($this->Controller);
|
||||||
|
$this->Controller->Component->initialize($this->Controller);
|
||||||
|
$this->Controller->Component->startup($this->Controller);
|
||||||
|
$this->Controller->Component->beforeRender($this->Controller);
|
||||||
|
$this->assertTrue(isset($this->Controller->viewVars['debugToolbarJavascript']));
|
||||||
|
$expected = array(
|
||||||
|
'behavior' => '/debug_kit/js/js_debug_toolbar',
|
||||||
|
);
|
||||||
|
$this->assertEqual($this->Controller->viewVars['debugToolbarJavascript'], $expected);
|
||||||
|
|
||||||
|
$this->Controller->components = array(
|
||||||
|
'DebugKit.Toolbar' => array(
|
||||||
|
'javascript' => 'jquery',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
$this->Controller->Component->init($this->Controller);
|
||||||
|
$this->Controller->Component->initialize($this->Controller);
|
||||||
|
$this->Controller->Component->startup($this->Controller);
|
||||||
|
$this->Controller->Component->beforeRender($this->Controller);
|
||||||
|
$this->assertTrue(isset($this->Controller->viewVars['debugToolbarJavascript']));
|
||||||
|
$expected = array(
|
||||||
|
'behavior' => '/debug_kit/js/jquery_debug_toolbar.js',
|
||||||
|
);
|
||||||
|
$this->assertEqual($this->Controller->viewVars['debugToolbarJavascript'], $expected);
|
||||||
|
|
||||||
|
|
||||||
|
$this->Controller->components = array(
|
||||||
|
'DebugKit.Toolbar' => array(
|
||||||
|
'javascript' => false
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$this->Controller->Component->init($this->Controller);
|
||||||
|
$this->Controller->Component->initialize($this->Controller);
|
||||||
|
$this->Controller->Component->startup($this->Controller);
|
||||||
|
$this->Controller->Component->beforeRender($this->Controller);
|
||||||
|
$this->assertTrue(isset($this->Controller->viewVars['debugToolbarJavascript']));
|
||||||
|
$expected = array();
|
||||||
|
$this->assertEqual($this->Controller->viewVars['debugToolbarJavascript'], $expected);
|
||||||
|
|
||||||
|
|
||||||
|
$this->Controller->components = array(
|
||||||
|
'DebugKit.Toolbar' => array(
|
||||||
|
'javascript' => array('my_library'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
$this->Controller->Component->init($this->Controller);
|
||||||
|
$this->Controller->Component->initialize($this->Controller);
|
||||||
|
$this->Controller->Component->startup($this->Controller);
|
||||||
|
$this->Controller->Component->beforeRender($this->Controller);
|
||||||
|
$this->assertTrue(isset($this->Controller->viewVars['debugToolbarJavascript']));
|
||||||
|
$expected = array(
|
||||||
|
'behavior' => 'my_library_debug_toolbar'
|
||||||
|
);
|
||||||
|
$this->assertEqual($this->Controller->viewVars['debugToolbarJavascript'], $expected);
|
||||||
|
|
||||||
|
$this->Controller->components = array(
|
||||||
|
'DebugKit.Toolbar' => array(
|
||||||
|
'javascript' => array('/my/path/to/file')
|
||||||
|
),
|
||||||
|
);
|
||||||
|
$this->Controller->Component->init($this->Controller);
|
||||||
|
$this->Controller->Component->initialize($this->Controller);
|
||||||
|
$this->Controller->Component->startup($this->Controller);
|
||||||
|
$this->Controller->Component->beforeRender($this->Controller);
|
||||||
|
$this->assertTrue(isset($this->Controller->viewVars['debugToolbarJavascript']));
|
||||||
|
$expected = array(
|
||||||
|
'behavior' => '/my/path/to/file',
|
||||||
|
);
|
||||||
|
$this->assertEqual($this->Controller->viewVars['debugToolbarJavascript'], $expected);
|
||||||
|
|
||||||
|
$this->Controller->components = array(
|
||||||
|
'DebugKit.Toolbar' => array(
|
||||||
|
'javascript' => '/js/custom_behavior',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
$this->Controller->Component->init($this->Controller);
|
||||||
|
$this->Controller->Component->initialize($this->Controller);
|
||||||
|
$this->Controller->Component->startup($this->Controller);
|
||||||
|
$this->Controller->Component->beforeRender($this->Controller);
|
||||||
|
$this->assertTrue(isset($this->Controller->viewVars['debugToolbarJavascript']));
|
||||||
|
$expected = array(
|
||||||
|
'behavior' => '/js/custom_behavior',
|
||||||
|
);
|
||||||
|
$this->assertEqual($this->Controller->viewVars['debugToolbarJavascript'], $expected);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Test alternate javascript existing in the plugin.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testExistingAlterateJavascript() {
|
||||||
|
$filename = APP . 'plugins' . DS . 'debug_kit' . DS . 'vendors' . DS . 'js' . DS . 'test_alternate_debug_toolbar.js';
|
||||||
|
$this->skipIf(!is_writable(dirname($filename)), 'Skipping existing javascript test, debug_kit/vendors/js must be writable');
|
||||||
|
|
||||||
|
@touch($filename);
|
||||||
|
$this->Controller->components = array(
|
||||||
|
'DebugKit.Toolbar' => array(
|
||||||
|
'javascript' => 'test_alternate',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
$this->Controller->Component->init($this->Controller);
|
||||||
|
$this->Controller->Component->initialize($this->Controller);
|
||||||
|
$this->Controller->Component->startup($this->Controller);
|
||||||
|
$this->Controller->Component->beforeRender($this->Controller);
|
||||||
|
$this->assertTrue(isset($this->Controller->viewVars['debugToolbarJavascript']));
|
||||||
|
$expected = array(
|
||||||
|
'behavior' => '/debug_kit/js/test_alternate_debug_toolbar.js',
|
||||||
|
);
|
||||||
|
$this->assertEqual($this->Controller->viewVars['debugToolbarJavascript'], $expected);
|
||||||
|
@unlink($filename);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* test the Log panel log reading.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testLogPanel() {
|
||||||
|
usleep(20);
|
||||||
|
$this->Controller->log('This is a log I made this request');
|
||||||
|
$this->Controller->log('This is the second log I made this request');
|
||||||
|
$this->Controller->log('This time in the debug log!', LOG_DEBUG);
|
||||||
|
|
||||||
|
$this->Controller->components = array(
|
||||||
|
'DebugKit.Toolbar' => array(
|
||||||
|
'panels' => array('log', 'session')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$this->Controller->Component->init($this->Controller);
|
||||||
|
$this->Controller->Component->initialize($this->Controller);
|
||||||
|
$this->Controller->Component->startup($this->Controller);
|
||||||
|
$this->Controller->Component->beforeRender($this->Controller);
|
||||||
|
$result = $this->Controller->viewVars['debugToolbarPanels']['log'];
|
||||||
|
|
||||||
|
$this->assertEqual(count($result['content']), 2);
|
||||||
|
$this->assertEqual(count($result['content']['error.log']), 4);
|
||||||
|
$this->assertEqual(count($result['content']['debug.log']), 2);
|
||||||
|
|
||||||
|
$this->assertEqual(trim($result['content']['debug.log'][1]), 'Debug: This time in the debug log!');
|
||||||
|
$this->assertEqual(trim($result['content']['error.log'][1]), 'Error: This is a log I made this request');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* teardown
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function tearDown() {
|
||||||
|
unset($this->Controller);
|
||||||
|
if (class_exists('DebugKitDebugger')) {
|
||||||
|
DebugKitDebugger::clearTimers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
0
site/plugins/debug_kit/tests/cases/empty
Normal file
0
site/plugins/debug_kit/tests/cases/empty
Normal file
62
site/plugins/debug_kit/tests/cases/test_objects.php
Normal file
62
site/plugins/debug_kit/tests/cases/test_objects.php
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* Common test objects used in DebugKit tests
|
||||||
|
*
|
||||||
|
* Long description for file
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP(tm) Tests <https://trac.cakephp.org/wiki/Developement/TestSuite>
|
||||||
|
* Copyright 2005-2008, Cake Software Foundation, Inc.
|
||||||
|
* 1785 E. Sahara Avenue, Suite 490-204
|
||||||
|
* Las Vegas, Nevada 89104
|
||||||
|
*
|
||||||
|
* Licensed under The Open Group Test Suite License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link https://trac.cakephp.org/wiki/Developement/TestSuite CakePHP(tm) Tests
|
||||||
|
* @package cake.tests
|
||||||
|
* @subpackage cake.tests.cases.libs
|
||||||
|
* @since CakePHP(tm) v 1.2.0.5432
|
||||||
|
* @version $Revision$
|
||||||
|
* @modifiedby $LastChangedBy$
|
||||||
|
* @lastmodified $Date$
|
||||||
|
* @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* TestFireCake class allows for testing of FireCake
|
||||||
|
*
|
||||||
|
* @package debug_kit.tests.
|
||||||
|
*/
|
||||||
|
class TestFireCake extends FireCake {
|
||||||
|
var $sentHeaders = array();
|
||||||
|
|
||||||
|
function _sendHeader($name, $value) {
|
||||||
|
$_this = FireCake::getInstance();
|
||||||
|
$_this->sentHeaders[$name] = $value;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* skip client detection as headers are not being sent.
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function detectClientExtension() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Reset the fireCake
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function reset() {
|
||||||
|
$_this = FireCake::getInstance();
|
||||||
|
$_this->sentHeaders = array();
|
||||||
|
$_this->_messageIndex = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
157
site/plugins/debug_kit/tests/cases/vendors/debug_kit_debugger.test.php
vendored
Normal file
157
site/plugins/debug_kit/tests/cases/vendors/debug_kit_debugger.test.php
vendored
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
<?php
|
||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* DebugKit Debugger Test Case File
|
||||||
|
*
|
||||||
|
* Long description for file
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP(tm) Tests <https://trac.cakephp.org/wiki/Developement/TestSuite>
|
||||||
|
* Copyright 2005-2008, Cake Software Foundation, Inc.
|
||||||
|
* 1785 E. Sahara Avenue, Suite 490-204
|
||||||
|
* Las Vegas, Nevada 89104
|
||||||
|
*
|
||||||
|
* Licensed under The Open Group Test Suite License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link https://trac.cakephp.org/wiki/Developement/TestSuite CakePHP(tm) Tests
|
||||||
|
* @package cake.tests
|
||||||
|
* @subpackage cake.tests.cases.libs
|
||||||
|
* @since CakePHP(tm) v 1.2.0.5432
|
||||||
|
* @version $Revision$
|
||||||
|
* @modifiedby $LastChangedBy$
|
||||||
|
* @lastmodified $Date$
|
||||||
|
* @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
|
||||||
|
*/
|
||||||
|
App::import('Core', 'Debugger');
|
||||||
|
App::import('Vendor', 'DebugKit.DebugKitDebugger');
|
||||||
|
|
||||||
|
require_once APP . 'plugins' . DS . 'debug_kit' . DS . 'tests' . DS . 'cases' . DS . 'test_objects.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Short description for class.
|
||||||
|
*
|
||||||
|
* @package cake.tests
|
||||||
|
* @subpackage cake.tests.cases.libs
|
||||||
|
*/
|
||||||
|
class DebugKitDebuggerTest extends CakeTestCase {
|
||||||
|
/**
|
||||||
|
* setUp method
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function setUp() {
|
||||||
|
Configure::write('log', false);
|
||||||
|
if (!defined('SIMPLETESTVENDORPATH')) {
|
||||||
|
if (file_exists(APP . DS . 'vendors' . DS . 'simpletest' . DS . 'reporter.php')) {
|
||||||
|
define('SIMPLETESTVENDORPATH', 'APP' . DS . 'vendors');
|
||||||
|
} else {
|
||||||
|
define('SIMPLETESTVENDORPATH', 'CORE' . DS . 'vendors');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start Timer test
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testTimers() {
|
||||||
|
$this->assertTrue(DebugKitDebugger::startTimer('test1', 'this is my first test'));
|
||||||
|
usleep(5000);
|
||||||
|
$this->assertTrue(DebugKitDebugger::stopTimer('test1'));
|
||||||
|
$elapsed = DebugKitDebugger::elapsedTime('test1');
|
||||||
|
$this->assertTrue($elapsed > 0.0050);
|
||||||
|
|
||||||
|
$this->assertTrue(DebugKitDebugger::startTimer('test2', 'this is my second test'));
|
||||||
|
sleep(1);
|
||||||
|
$this->assertTrue(DebugKitDebugger::stopTimer('test2'));
|
||||||
|
$elapsed = DebugKitDebugger::elapsedTime('test2');
|
||||||
|
$this->assertTrue($elapsed > 1);
|
||||||
|
|
||||||
|
DebugKitDebugger::startTimer('test3');
|
||||||
|
$this->assertFalse(DebugKitDebugger::elapsedTime('test3'));
|
||||||
|
$this->assertFalse(DebugKitDebugger::stopTimer('wrong'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* testRequestTime
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function testRequestTime() {
|
||||||
|
$result1 = DebugKitDebugger::requestTime();
|
||||||
|
usleep(50);
|
||||||
|
$result2 = DebugKitDebugger::requestTime();
|
||||||
|
$this->assertTrue($result1 < $result2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test getting all the set timers.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testGetTimers() {
|
||||||
|
DebugKitDebugger::clearTimers();
|
||||||
|
DebugKitDebugger::startTimer('test1', 'this is my first test');
|
||||||
|
DebugKitDebugger::stopTimer('test1');
|
||||||
|
usleep(50);
|
||||||
|
DebugKitDebugger::startTimer('test2');
|
||||||
|
DebugKitDebugger::stopTimer('test2');
|
||||||
|
$timers = DebugKitDebugger::getTimers();
|
||||||
|
|
||||||
|
$this->assertEqual(count($timers), 2);
|
||||||
|
$this->assertTrue(is_float($timers['test1']['time']));
|
||||||
|
$this->assertTrue(isset($timers['test1']['message']));
|
||||||
|
$this->assertTrue(isset($timers['test2']['message']));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test memory usage
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testMemoryUsage() {
|
||||||
|
$result = DebugKitDebugger::getMemoryUse();
|
||||||
|
$this->assertTrue(is_int($result));
|
||||||
|
|
||||||
|
$result = DebugKitDebugger::getPeakMemoryUse();
|
||||||
|
$this->assertTrue(is_int($result));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* test _output switch to firePHP
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function testOutput() {
|
||||||
|
$firecake =& FireCake::getInstance('TestFireCake');
|
||||||
|
Debugger::invoke(DebugKitDebugger::getInstance('DebugKitDebugger'));
|
||||||
|
Debugger::output('fb');
|
||||||
|
$foo .= '';
|
||||||
|
$result = $firecake->sentHeaders;
|
||||||
|
|
||||||
|
$this->assertPattern('/GROUP_START/', $result['X-Wf-1-1-1-1']);
|
||||||
|
$this->assertPattern('/ERROR/', $result['X-Wf-1-1-1-2']);
|
||||||
|
$this->assertPattern('/GROUP_END/', $result['X-Wf-1-1-1-5']);
|
||||||
|
|
||||||
|
Debugger::invoke(Debugger::getInstance('Debugger'));
|
||||||
|
Debugger::output();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tearDown method
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function tearDown() {
|
||||||
|
Configure::write('log', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
336
site/plugins/debug_kit/tests/cases/vendors/fire_cake.test.php
vendored
Normal file
336
site/plugins/debug_kit/tests/cases/vendors/fire_cake.test.php
vendored
Normal file
@@ -0,0 +1,336 @@
|
|||||||
|
<?php
|
||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* CakeFirePHP test case
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||||
|
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* 1785 E. Sahara Avenue, Suite 490-204
|
||||||
|
* Las Vegas, Nevada 89104
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||||
|
* @package debug_kit
|
||||||
|
* @subpackage cake.debug_kit.tests
|
||||||
|
* @since CakePHP v 1.2.0.4487
|
||||||
|
* @version
|
||||||
|
* @modifiedby
|
||||||
|
* @lastmodified
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
App::import('Vendor', 'DebugKit.FireCake');
|
||||||
|
|
||||||
|
require_once APP . 'plugins' . DS . 'debug_kit' . DS . 'tests' . DS . 'cases' . DS . 'test_objects.php';
|
||||||
|
/**
|
||||||
|
* Test Case For FireCake
|
||||||
|
*
|
||||||
|
* @package debug_kit.tests
|
||||||
|
*/
|
||||||
|
class FireCakeTestCase extends CakeTestCase {
|
||||||
|
/**
|
||||||
|
* setup test
|
||||||
|
*
|
||||||
|
* Fill FireCake with TestFireCake instance.
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function setUp() {
|
||||||
|
$this->firecake =& FireCake::getInstance('TestFireCake');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* test getInstance cheat.
|
||||||
|
*
|
||||||
|
* If this fails the rest of the test is going to fail too.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testGetInstanceOverride() {
|
||||||
|
$instance =& FireCake::getInstance();
|
||||||
|
$instance2 =& FireCake::getInstance();
|
||||||
|
$this->assertReference($instance, $instance2);
|
||||||
|
$this->assertIsA($instance, 'FireCake');
|
||||||
|
$this->assertIsA($instance, 'TestFireCake', 'Stored instance is not a copy of TestFireCake, test case is broken.');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* testsetoption
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testSetOptions() {
|
||||||
|
FireCake::setOptions(array('includeLineNumbers' => false));
|
||||||
|
$this->assertEqual($this->firecake->options['includeLineNumbers'], false);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* test Log()
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function testLog() {
|
||||||
|
FireCake::setOptions(array('includeLineNumbers' => false));
|
||||||
|
FireCake::log('Testing');
|
||||||
|
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-Protocol-1']));
|
||||||
|
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Plugin-1']));
|
||||||
|
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Structure-1']));
|
||||||
|
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-Index'], 1);
|
||||||
|
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-1'], '26|[{"Type":"LOG"},"Testing"]|');
|
||||||
|
|
||||||
|
FireCake::log('Testing', 'log-info');
|
||||||
|
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-2'], '45|[{"Type":"LOG","Label":"log-info"},"Testing"]|');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* test info()
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function testInfo() {
|
||||||
|
FireCake::setOptions(array('includeLineNumbers' => false));
|
||||||
|
FireCake::info('I have information');
|
||||||
|
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-Protocol-1']));
|
||||||
|
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Plugin-1']));
|
||||||
|
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Structure-1']));
|
||||||
|
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-Index'], 1);
|
||||||
|
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-1'], '38|[{"Type":"INFO"},"I have information"]|');
|
||||||
|
|
||||||
|
FireCake::info('I have information', 'info-label');
|
||||||
|
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-2'], '59|[{"Type":"INFO","Label":"info-label"},"I have information"]|');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* test info()
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function testWarn() {
|
||||||
|
FireCake::setOptions(array('includeLineNumbers' => false));
|
||||||
|
FireCake::warn('A Warning');
|
||||||
|
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-Protocol-1']));
|
||||||
|
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Plugin-1']));
|
||||||
|
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Structure-1']));
|
||||||
|
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-Index'], 1);
|
||||||
|
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-1'], '29|[{"Type":"WARN"},"A Warning"]|');
|
||||||
|
|
||||||
|
FireCake::warn('A Warning', 'Bzzz');
|
||||||
|
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-2'], '44|[{"Type":"WARN","Label":"Bzzz"},"A Warning"]|');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* test error()
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testError() {
|
||||||
|
FireCake::setOptions(array('includeLineNumbers' => false));
|
||||||
|
FireCake::error('An error');
|
||||||
|
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-Protocol-1']));
|
||||||
|
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Plugin-1']));
|
||||||
|
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Structure-1']));
|
||||||
|
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-Index'], 1);
|
||||||
|
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-1'], '29|[{"Type":"ERROR"},"An error"]|');
|
||||||
|
|
||||||
|
FireCake::error('An error', 'wonky');
|
||||||
|
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-2'], '45|[{"Type":"ERROR","Label":"wonky"},"An error"]|');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* test dump()
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testDump() {
|
||||||
|
FireCake::dump('mydump', array('one' => 1, 'two' => 2));
|
||||||
|
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-2-1-1'], '28|{"mydump":{"one":1,"two":2}}|');
|
||||||
|
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Structure-2']));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* test table() generation
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testTable() {
|
||||||
|
$table[] = array('Col 1 Heading','Col 2 Heading');
|
||||||
|
$table[] = array('Row 1 Col 1','Row 1 Col 2');
|
||||||
|
$table[] = array('Row 2 Col 1','Row 2 Col 2');
|
||||||
|
$table[] = array('Row 3 Col 1','Row 3 Col 2');
|
||||||
|
FireCake::table('myTrace', $table);
|
||||||
|
$expected = '162|[{"Type":"TABLE","Label":"myTrace"},[["Col 1 Heading","Col 2 Heading"],["Row 1 Col 1","Row 1 Col 2"],["Row 2 Col 1","Row 2 Col 2"],["Row 3 Col 1","Row 3 Col 2"]]]|';
|
||||||
|
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-1'], $expected);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* testStringEncoding
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testStringEncode() {
|
||||||
|
$result = $this->firecake->stringEncode(array(1,2,3));
|
||||||
|
$this->assertEqual($result, array(1,2,3));
|
||||||
|
|
||||||
|
$this->firecake->setOptions(array('maxArrayDepth' => 3));
|
||||||
|
$deep = array(1 => array(2 => array(3)));
|
||||||
|
$result = $this->firecake->stringEncode($deep);
|
||||||
|
$this->assertEqual($result, array(1 => array(2 => '** Max Array Depth (3) **')));
|
||||||
|
|
||||||
|
$obj =& FireCake::getInstance();
|
||||||
|
$result = $this->firecake->stringEncode($obj);
|
||||||
|
$this->assertTrue(is_array($result));
|
||||||
|
$this->assertEqual($result['_defaultOptions']['useNativeJsonEncode'], true);
|
||||||
|
$this->assertEqual($result['_log'], null);
|
||||||
|
$this->assertEqual($result['_encodedObjects'][0], '** Recursion (TestFireCake) **');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* test trace()
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testTrace() {
|
||||||
|
FireCake::trace('myTrace');
|
||||||
|
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-Protocol-1']));
|
||||||
|
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Plugin-1']));
|
||||||
|
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Structure-1']));
|
||||||
|
$dump = $this->firecake->sentHeaders['X-Wf-1-1-1-1'];
|
||||||
|
$this->assertPattern('/"Message":"myTrace"/', $dump);
|
||||||
|
$this->assertPattern('/"Trace":\[/', $dump);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* test enabling and disabling of FireCake output
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testEnableDisable() {
|
||||||
|
FireCake::disable();
|
||||||
|
FireCake::trace('myTrace');
|
||||||
|
$this->assertTrue(empty($this->firecake->sentHeaders));
|
||||||
|
|
||||||
|
FireCake::enable();
|
||||||
|
FireCake::trace('myTrace');
|
||||||
|
$this->assertFalse(empty($this->firecake->sentHeaders));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* test correct line continuation markers on multi line headers.
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function testMultiLineOutput() {
|
||||||
|
FireCake::trace('myTrace');
|
||||||
|
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-Index'], 3);
|
||||||
|
$header = $this->firecake->sentHeaders['X-Wf-1-1-1-1'];
|
||||||
|
$this->assertEqual(substr($header, -2), '|\\');
|
||||||
|
|
||||||
|
$header = $this->firecake->sentHeaders['X-Wf-1-1-1-2'];
|
||||||
|
$this->assertEqual(substr($header, -2), '|\\');
|
||||||
|
|
||||||
|
$header = $this->firecake->sentHeaders['X-Wf-1-1-1-3'];
|
||||||
|
$this->assertEqual(substr($header, -1), '|');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test inclusion of line numbers
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testIncludeLineNumbers() {
|
||||||
|
FireCake::setOptions(array('includeLineNumbers' => true));
|
||||||
|
FireCake::info('Testing');
|
||||||
|
$result = $this->firecake->sentHeaders['X-Wf-1-1-1-1'];
|
||||||
|
$this->assertPattern('/"File"\:"APP.*fire_cake.test.php/', $result);
|
||||||
|
$this->assertPattern('/"Line"\:\d+/', $result);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* test Group messages
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testGroup() {
|
||||||
|
FireCake::setOptions(array('includeLineNumbers' => false));
|
||||||
|
FireCake::group('test');
|
||||||
|
FireCake::info('my info');
|
||||||
|
FireCake::groupEnd();
|
||||||
|
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-1'], '44|[{"Type":"GROUP_START","Label":"test"},null]|');
|
||||||
|
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-3'], '27|[{"Type":"GROUP_END"},null]|');
|
||||||
|
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-Index'], 3);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* test fb() parameter parsing
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testFbParameterParsing() {
|
||||||
|
FireCake::setOptions(array('includeLineNumbers' => false));
|
||||||
|
FireCake::fb('Test');
|
||||||
|
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-1'], '23|[{"Type":"LOG"},"Test"]|');
|
||||||
|
|
||||||
|
FireCake::fb('Test', 'warn');
|
||||||
|
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-2'], '24|[{"Type":"WARN"},"Test"]|');
|
||||||
|
|
||||||
|
FireCake::fb('Test', 'Custom label', 'warn');
|
||||||
|
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-3'], '47|[{"Type":"WARN","Label":"Custom label"},"Test"]|');
|
||||||
|
|
||||||
|
$this->expectError();
|
||||||
|
$this->assertFalse(FireCake::fb('Test', 'Custom label', 'warn', 'more parameters'));
|
||||||
|
|
||||||
|
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-Index'], 3);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Test defaulting to log if incorrect message type is used
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testIncorrectMessageType() {
|
||||||
|
FireCake::setOptions(array('includeLineNumbers' => false));
|
||||||
|
FireCake::fb('Hello World', 'foobared');
|
||||||
|
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-1'], '30|[{"Type":"LOG"},"Hello World"]|');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* testClientExtensionDetection.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testDetectClientExtension() {
|
||||||
|
$back = env('HTTP_USER_AGENT');
|
||||||
|
$_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4 FirePHP/0.2.1';
|
||||||
|
$this->assertTrue(FireCake::detectClientExtension());
|
||||||
|
|
||||||
|
$_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4 FirePHP/0.0.4';
|
||||||
|
$this->assertFalse(FireCake::detectClientExtension());
|
||||||
|
|
||||||
|
$_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4';
|
||||||
|
$this->assertFalse(FireCake::detectClientExtension());
|
||||||
|
$_SERVER['HTTP_USER_AGENT'] = $back;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* test of Non Native JSON encoding.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testNonNativeEncoding() {
|
||||||
|
FireCake::setOptions(array('useNativeJsonEncode' => false));
|
||||||
|
$json = FireCake::jsonEncode(array('one' => 1, 'two' => 2));
|
||||||
|
$this->assertEqual($json, '{"one":1,"two":2}');
|
||||||
|
|
||||||
|
$json = FireCake::jsonEncode(array(1,2,3));
|
||||||
|
$this->assertEqual($json, '[1,2,3]');
|
||||||
|
|
||||||
|
$json = FireCake::jsonEncode(FireCake::getInstance());
|
||||||
|
$this->assertPattern('/"options"\:\{"maxObjectDepth"\:\d*,/', $json);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* reset the FireCake counters and headers.
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function tearDown() {
|
||||||
|
TestFireCake::reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
144
site/plugins/debug_kit/tests/cases/views/debug.test.php
Normal file
144
site/plugins/debug_kit/tests/cases/views/debug.test.php
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
<?php
|
||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* DebugView test Case
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||||
|
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* 1785 E. Sahara Avenue, Suite 490-204
|
||||||
|
* Las Vegas, Nevada 89104
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||||
|
* @package cake
|
||||||
|
* @subpackage cake.cake.libs.
|
||||||
|
* @since CakePHP v 1.2.0.4487
|
||||||
|
* @version $Revision$
|
||||||
|
* @modifiedby $LastChangedBy$
|
||||||
|
* @lastmodified $Date$
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
App::import('Core', 'View');
|
||||||
|
|
||||||
|
if (!class_exists('DoppelGangerView')) {
|
||||||
|
class DoppelGangerView extends View {}
|
||||||
|
}
|
||||||
|
|
||||||
|
App::import('View', 'DebugKit.Debug');
|
||||||
|
App::import('Vendor', 'DebugKit.DebugKitDebugger');
|
||||||
|
/**
|
||||||
|
* Debug View Test Case
|
||||||
|
*
|
||||||
|
* @package debug_kit.tests
|
||||||
|
*/
|
||||||
|
class DebugViewTestCase extends CakeTestCase {
|
||||||
|
/**
|
||||||
|
* set Up test case
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function setUp() {
|
||||||
|
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
|
||||||
|
Router::parse('/');
|
||||||
|
$this->Controller =& ClassRegistry::init('Controller');
|
||||||
|
$this->View =& new DebugView($this->Controller, false);
|
||||||
|
$this->_debug = Configure::read('debug');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* start Case - switch view paths
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function startCase() {
|
||||||
|
$this->_viewPaths = Configure::read('viewPaths');
|
||||||
|
Configure::write('viewPaths', array(
|
||||||
|
TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views'. DS,
|
||||||
|
APP . 'plugins' . DS . 'debug_kit' . DS . 'views'. DS,
|
||||||
|
ROOT . DS . LIBS . 'view' . DS
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test that element timers are working
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testElementTimers() {
|
||||||
|
$result = $this->View->element('test_element');
|
||||||
|
$this->assertPattern('/^this is the test element$/', $result);
|
||||||
|
|
||||||
|
$result = DebugKitDebugger::getTimers();
|
||||||
|
$this->assertTrue(isset($result['render_test_element.ctp']));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test rendering and ensure that timers are being set.
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function testRenderTimers() {
|
||||||
|
$this->Controller->viewPath = 'posts';
|
||||||
|
$this->Controller->action = 'index';
|
||||||
|
$this->Controller->params = array(
|
||||||
|
'action' => 'index',
|
||||||
|
'controller' => 'posts',
|
||||||
|
'plugin' => null,
|
||||||
|
'url' => array('url' => 'posts/index'),
|
||||||
|
'base' => null,
|
||||||
|
'here' => '/posts/index',
|
||||||
|
);
|
||||||
|
$this->Controller->layout = 'default';
|
||||||
|
$View =& new DebugView($this->Controller, false);
|
||||||
|
$View->render('index');
|
||||||
|
|
||||||
|
$result = DebugKitDebugger::getTimers();
|
||||||
|
$this->assertEqual(count($result), 3);
|
||||||
|
$this->assertTrue(isset($result['viewRender']));
|
||||||
|
$this->assertTrue(isset($result['render_default.ctp']));
|
||||||
|
$this->assertTrue(isset($result['render_index.ctp']));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for correct loading of helpers into custom view
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function testLoadHelpers() {
|
||||||
|
$loaded = array();
|
||||||
|
$result = $this->View->_loadHelpers($loaded, array('Html', 'Javascript', 'Number'));
|
||||||
|
$this->assertTrue(is_object($result['Html']));
|
||||||
|
$this->assertTrue(is_object($result['Javascript']));
|
||||||
|
$this->assertTrue(is_object($result['Number']));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reset the view paths
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function endCase() {
|
||||||
|
Configure::write('viewPaths', $this->_viewPaths);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tear down function
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function tearDown() {
|
||||||
|
unset($this->View, $this->Controller);
|
||||||
|
DebugKitDebugger::clearTimers();
|
||||||
|
Configure::write('debug', $this->_debug);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
<?php
|
||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* Toolbar Abstract Helper Test Case
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||||
|
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* 1785 E. Sahara Avenue, Suite 490-204
|
||||||
|
* Las Vegas, Nevada 89104
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||||
|
* @package cake
|
||||||
|
* @subpackage debug_kit.tests.views.helpers
|
||||||
|
* @version $Revision$
|
||||||
|
* @modifiedby $LastChangedBy$
|
||||||
|
* @lastmodified $Date$
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
App::import('Helper', 'DebugKit.FirePhpToolbar');
|
||||||
|
App::import('Core', array('View', 'Controller'));
|
||||||
|
require_once APP . 'plugins' . DS . 'debug_kit' . DS . 'tests' . DS . 'cases' . DS . 'test_objects.php';
|
||||||
|
|
||||||
|
FireCake::getInstance('TestFireCake');
|
||||||
|
|
||||||
|
class FirePhpToolbarHelperTestCase extends CakeTestCase {
|
||||||
|
/**
|
||||||
|
* setUp
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function setUp() {
|
||||||
|
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
|
||||||
|
Router::parse('/');
|
||||||
|
|
||||||
|
$this->Toolbar =& new ToolbarHelper(array('output' => 'DebugKit.FirePhpToolbar'));
|
||||||
|
$this->Toolbar->FirePhpToolbar =& new FirePhpToolbarHelper();
|
||||||
|
|
||||||
|
$this->Controller =& ClassRegistry::init('Controller');
|
||||||
|
if (isset($this->_debug)) {
|
||||||
|
Configure::write('debug', $this->_debug);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* start Case - switch view paths
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function startCase() {
|
||||||
|
$this->_viewPaths = Configure::read('viewPaths');
|
||||||
|
Configure::write('viewPaths', array(
|
||||||
|
TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views'. DS,
|
||||||
|
APP . 'plugins' . DS . 'debug_kit' . DS . 'views'. DS,
|
||||||
|
ROOT . DS . LIBS . 'view' . DS
|
||||||
|
));
|
||||||
|
$this->_debug = Configure::read('debug');
|
||||||
|
$this->firecake =& FireCake::getInstance();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* test neat array (dump)creation
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function testMakeNeatArray() {
|
||||||
|
$this->Toolbar->makeNeatArray(array(1,2,3));
|
||||||
|
$result = $this->firecake->sentHeaders;
|
||||||
|
$this->assertTrue(isset($result['X-Wf-1-1-1-1']));
|
||||||
|
$this->assertPattern('/\[1,2,3\]/', $result['X-Wf-1-1-1-1']);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* testAfterlayout element rendering
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function testAfterLayout(){
|
||||||
|
$this->Controller->viewPath = 'posts';
|
||||||
|
$this->Controller->action = 'index';
|
||||||
|
$this->Controller->params = array(
|
||||||
|
'action' => 'index',
|
||||||
|
'controller' => 'posts',
|
||||||
|
'plugin' => null,
|
||||||
|
'url' => array('url' => 'posts/index', 'ext' => 'xml'),
|
||||||
|
'base' => null,
|
||||||
|
'here' => '/posts/index',
|
||||||
|
);
|
||||||
|
$this->Controller->layout = 'default';
|
||||||
|
$this->Controller->uses = null;
|
||||||
|
$this->Controller->components = array('DebugKit.Toolbar');
|
||||||
|
$this->Controller->constructClasses();
|
||||||
|
$this->Controller->Component->initialize($this->Controller);
|
||||||
|
$this->Controller->Component->startup($this->Controller);
|
||||||
|
$this->Controller->Component->beforeRender($this->Controller);
|
||||||
|
$result = $this->Controller->render();
|
||||||
|
$this->assertNoPattern('/debug-toolbar/', $result);
|
||||||
|
$result = $this->firecake->sentHeaders;
|
||||||
|
$this->assertTrue(is_array($result));
|
||||||
|
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* endTest()
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function endTest() {
|
||||||
|
TestFireCake::reset();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* reset the view paths
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function endCase() {
|
||||||
|
Configure::write('viewPaths', $this->_viewPaths);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tearDown
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function tearDown() {
|
||||||
|
unset($this->Toolbar, $this->Controller);
|
||||||
|
ClassRegistry::removeObject('view');
|
||||||
|
ClassRegistry::flush();
|
||||||
|
Router::reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -0,0 +1,358 @@
|
|||||||
|
<?php
|
||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* Toolbar HTML Helper Test Case
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||||
|
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* 1785 E. Sahara Avenue, Suite 490-204
|
||||||
|
* Las Vegas, Nevada 89104
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||||
|
* @package cake
|
||||||
|
* @subpackage debug_kit.tests.views.helpers
|
||||||
|
* @version $Revision$
|
||||||
|
* @modifiedby $LastChangedBy$
|
||||||
|
* @lastmodified $Date$
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
App::import('Helper', array('DebugKit.HtmlToolbar', 'Html', 'Javascript'));
|
||||||
|
App::import('Core', array('View', 'Controller'));
|
||||||
|
|
||||||
|
class HtmlToolbarHelperTestCase extends CakeTestCase {
|
||||||
|
/**
|
||||||
|
* setUp
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function setUp() {
|
||||||
|
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
|
||||||
|
Router::parse('/');
|
||||||
|
|
||||||
|
$this->Toolbar =& new ToolbarHelper(array('output' => 'DebugKit.HtmlToolbar'));
|
||||||
|
$this->Toolbar->HtmlToolbar =& new HtmlToolbarHelper();
|
||||||
|
$this->Toolbar->HtmlToolbar->Html =& new HtmlHelper();
|
||||||
|
$this->Toolbar->HtmlToolbar->Javascript =& new JavascriptHelper();
|
||||||
|
|
||||||
|
$this->Controller =& ClassRegistry::init('Controller');
|
||||||
|
if (isset($this->_debug)) {
|
||||||
|
Configure::write('debug', $this->_debug);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* start Case - switch view paths
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function startCase() {
|
||||||
|
$this->_viewPaths = Configure::read('viewPaths');
|
||||||
|
Configure::write('viewPaths', array(
|
||||||
|
TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views'. DS,
|
||||||
|
APP . 'plugins' . DS . 'debug_kit' . DS . 'views'. DS,
|
||||||
|
ROOT . DS . LIBS . 'view' . DS
|
||||||
|
));
|
||||||
|
$this->_debug = Configure::read('debug');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test Neat Array formatting
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testMakeNeatArray() {
|
||||||
|
$in = false;
|
||||||
|
$result = $this->Toolbar->makeNeatArray($in);
|
||||||
|
$expected = array(
|
||||||
|
'ul' => array('class' => 'neat-array depth-0'),
|
||||||
|
'<li', '<strong', '0' , '/strong', '(false)', '/li',
|
||||||
|
'/ul'
|
||||||
|
);
|
||||||
|
$this->assertTags($result, $expected);
|
||||||
|
|
||||||
|
$in = null;
|
||||||
|
$result = $this->Toolbar->makeNeatArray($in);
|
||||||
|
$expected = array(
|
||||||
|
'ul' => array('class' => 'neat-array depth-0'),
|
||||||
|
'<li', '<strong', '0' , '/strong', '(null)', '/li',
|
||||||
|
'/ul'
|
||||||
|
);
|
||||||
|
$this->assertTags($result, $expected);
|
||||||
|
|
||||||
|
$in = true;
|
||||||
|
$result = $this->Toolbar->makeNeatArray($in);
|
||||||
|
$expected = array(
|
||||||
|
'ul' => array('class' => 'neat-array depth-0'),
|
||||||
|
'<li', '<strong', '0' , '/strong', '(true)', '/li',
|
||||||
|
'/ul'
|
||||||
|
);
|
||||||
|
$this->assertTags($result, $expected);
|
||||||
|
|
||||||
|
$in = array('key' => 'value');
|
||||||
|
$result = $this->Toolbar->makeNeatArray($in);
|
||||||
|
$expected = array(
|
||||||
|
'ul' => array('class' => 'neat-array depth-0'),
|
||||||
|
'<li', '<strong', 'key', '/strong', 'value', '/li',
|
||||||
|
'/ul'
|
||||||
|
);
|
||||||
|
$this->assertTags($result, $expected);
|
||||||
|
|
||||||
|
$in = array('key' => null);
|
||||||
|
$result = $this->Toolbar->makeNeatArray($in);
|
||||||
|
$expected = array(
|
||||||
|
'ul' => array('class' => 'neat-array depth-0'),
|
||||||
|
'<li', '<strong', 'key', '/strong', '(null)', '/li',
|
||||||
|
'/ul'
|
||||||
|
);
|
||||||
|
$this->assertTags($result, $expected);
|
||||||
|
|
||||||
|
$in = array('key' => 'value', 'foo' => 'bar');
|
||||||
|
$result = $this->Toolbar->makeNeatArray($in);
|
||||||
|
$expected = array(
|
||||||
|
'ul' => array('class' => 'neat-array depth-0'),
|
||||||
|
'<li', '<strong', 'key', '/strong', 'value', '/li',
|
||||||
|
'<li', '<strong', 'foo', '/strong', 'bar', '/li',
|
||||||
|
'/ul'
|
||||||
|
);
|
||||||
|
$this->assertTags($result, $expected);
|
||||||
|
|
||||||
|
$in = array(
|
||||||
|
'key' => 'value',
|
||||||
|
'foo' => array(
|
||||||
|
'this' => 'deep',
|
||||||
|
'another' => 'value'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$result = $this->Toolbar->makeNeatArray($in);
|
||||||
|
$expected = array(
|
||||||
|
'ul' => array('class' => 'neat-array depth-0'),
|
||||||
|
'<li', '<strong', 'key', '/strong', 'value', '/li',
|
||||||
|
'<li', '<strong', 'foo', '/strong',
|
||||||
|
array('ul' => array('class' => 'neat-array depth-1')),
|
||||||
|
'<li', '<strong', 'this', '/strong', 'deep', '/li',
|
||||||
|
'<li', '<strong', 'another', '/strong', 'value', '/li',
|
||||||
|
'/ul',
|
||||||
|
'/li',
|
||||||
|
'/ul'
|
||||||
|
);
|
||||||
|
$this->assertTags($result, $expected);
|
||||||
|
|
||||||
|
$in = array(
|
||||||
|
'key' => 'value',
|
||||||
|
'foo' => array(
|
||||||
|
'this' => 'deep',
|
||||||
|
'another' => 'value'
|
||||||
|
),
|
||||||
|
'lotr' => array(
|
||||||
|
'gandalf' => 'wizard',
|
||||||
|
'bilbo' => 'hobbit'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$result = $this->Toolbar->makeNeatArray($in, 1);
|
||||||
|
$expected = array(
|
||||||
|
'ul' => array('class' => 'neat-array depth-0 expanded'),
|
||||||
|
'<li', '<strong', 'key', '/strong', 'value', '/li',
|
||||||
|
'<li', '<strong', 'foo', '/strong',
|
||||||
|
array('ul' => array('class' => 'neat-array depth-1')),
|
||||||
|
'<li', '<strong', 'this', '/strong', 'deep', '/li',
|
||||||
|
'<li', '<strong', 'another', '/strong', 'value', '/li',
|
||||||
|
'/ul',
|
||||||
|
'/li',
|
||||||
|
'<li', '<strong', 'lotr', '/strong',
|
||||||
|
array('ul' => array('class' => 'neat-array depth-1')),
|
||||||
|
'<li', '<strong', 'gandalf', '/strong', 'wizard', '/li',
|
||||||
|
'<li', '<strong', 'bilbo', '/strong', 'hobbit', '/li',
|
||||||
|
'/ul',
|
||||||
|
'/li',
|
||||||
|
'/ul'
|
||||||
|
);
|
||||||
|
$this->assertTags($result, $expected);
|
||||||
|
|
||||||
|
$result = $this->Toolbar->makeNeatArray($in, 2);
|
||||||
|
$expected = array(
|
||||||
|
'ul' => array('class' => 'neat-array depth-0 expanded'),
|
||||||
|
'<li', '<strong', 'key', '/strong', 'value', '/li',
|
||||||
|
'<li', '<strong', 'foo', '/strong',
|
||||||
|
array('ul' => array('class' => 'neat-array depth-1 expanded')),
|
||||||
|
'<li', '<strong', 'this', '/strong', 'deep', '/li',
|
||||||
|
'<li', '<strong', 'another', '/strong', 'value', '/li',
|
||||||
|
'/ul',
|
||||||
|
'/li',
|
||||||
|
'<li', '<strong', 'lotr', '/strong',
|
||||||
|
array('ul' => array('class' => 'neat-array depth-1 expanded')),
|
||||||
|
'<li', '<strong', 'gandalf', '/strong', 'wizard', '/li',
|
||||||
|
'<li', '<strong', 'bilbo', '/strong', 'hobbit', '/li',
|
||||||
|
'/ul',
|
||||||
|
'/li',
|
||||||
|
'/ul'
|
||||||
|
);
|
||||||
|
$this->assertTags($result, $expected);
|
||||||
|
|
||||||
|
$in = array('key' => 'value', 'array' => array());
|
||||||
|
$result = $this->Toolbar->makeNeatArray($in);
|
||||||
|
$expected = array(
|
||||||
|
'ul' => array('class' => 'neat-array depth-0'),
|
||||||
|
'<li', '<strong', 'key', '/strong', 'value', '/li',
|
||||||
|
'<li', '<strong', 'array', '/strong', '(empty)', '/li',
|
||||||
|
'/ul'
|
||||||
|
);
|
||||||
|
$this->assertTags($result, $expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test injection of toolbar
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testInjectToolbar() {
|
||||||
|
$this->Controller->viewPath = 'posts';
|
||||||
|
$this->Controller->action = 'index';
|
||||||
|
$this->Controller->params = array(
|
||||||
|
'action' => 'index',
|
||||||
|
'controller' => 'posts',
|
||||||
|
'plugin' => null,
|
||||||
|
'url' => array('url' => 'posts/index'),
|
||||||
|
'base' => null,
|
||||||
|
'here' => '/posts/index',
|
||||||
|
);
|
||||||
|
$this->Controller->helpers = array('Html', 'Javascript', 'DebugKit.Toolbar');
|
||||||
|
$this->Controller->layout = 'default';
|
||||||
|
$this->Controller->uses = null;
|
||||||
|
$this->Controller->components = array('DebugKit.Toolbar');
|
||||||
|
$this->Controller->constructClasses();
|
||||||
|
$this->Controller->Component->initialize($this->Controller);
|
||||||
|
$this->Controller->Component->startup($this->Controller);
|
||||||
|
$this->Controller->Component->beforeRender($this->Controller);
|
||||||
|
$result = $this->Controller->render();
|
||||||
|
$result = str_replace(array("\n", "\r"), '', $result);
|
||||||
|
$this->assertPattern('#<div id\="debug-kit-toolbar">.+</div></body>#', $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test injection of javascript
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testJavascriptInjection() {
|
||||||
|
$this->Controller->viewPath = 'posts';
|
||||||
|
$this->Controller->uses = null;
|
||||||
|
$this->Controller->action = 'index';
|
||||||
|
$this->Controller->params = array(
|
||||||
|
'action' => 'index',
|
||||||
|
'controller' => 'posts',
|
||||||
|
'plugin' => null,
|
||||||
|
'url' => array('url' => 'posts/index'),
|
||||||
|
'base' => '/',
|
||||||
|
'here' => '/posts/index',
|
||||||
|
);
|
||||||
|
$this->Controller->helpers = array('Javascript', 'Html');
|
||||||
|
$this->Controller->components = array('DebugKit.Toolbar');
|
||||||
|
$this->Controller->layout = 'default';
|
||||||
|
$this->Controller->constructClasses();
|
||||||
|
$this->Controller->Component->initialize($this->Controller);
|
||||||
|
$this->Controller->Component->startup($this->Controller);
|
||||||
|
$this->Controller->Component->beforeRender($this->Controller);
|
||||||
|
$result = $this->Controller->render();
|
||||||
|
$result = str_replace(array("\n", "\r"), '', $result);
|
||||||
|
$this->assertPattern('#<script\s*type="text/javascript"\s*src="/debug_kit/js/js_debug_toolbar.js"\s*>\s?</script>#', $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test Injection of user defined javascript
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function testCustomJavascriptInjection() {
|
||||||
|
$this->Controller->viewPath = 'posts';
|
||||||
|
$this->Controller->uses = null;
|
||||||
|
$this->Controller->action = 'index';
|
||||||
|
$this->Controller->params = array(
|
||||||
|
'action' => 'index',
|
||||||
|
'controller' => 'posts',
|
||||||
|
'plugin' => null,
|
||||||
|
'url' => array('url' => 'posts/index'),
|
||||||
|
'base' => '/',
|
||||||
|
'here' => '/posts/index',
|
||||||
|
);
|
||||||
|
$this->Controller->helpers = array('Javascript', 'Html');
|
||||||
|
$this->Controller->components = array('DebugKit.Toolbar' => array('javascript' => array('my_custom')));
|
||||||
|
$this->Controller->layout = 'default';
|
||||||
|
$this->Controller->constructClasses();
|
||||||
|
$this->Controller->Component->initialize($this->Controller);
|
||||||
|
$this->Controller->Component->startup($this->Controller);
|
||||||
|
$this->Controller->Component->beforeRender($this->Controller);
|
||||||
|
$result = $this->Controller->render();
|
||||||
|
$result = str_replace(array("\n", "\r"), '', $result);
|
||||||
|
$this->assertPattern('#<script\s*type="text/javascript"\s*src="js/my_custom_debug_toolbar.js"\s*>\s?</script>#', $result);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* test message creation
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function testMessage() {
|
||||||
|
$result = $this->Toolbar->message('test', 'one, two');
|
||||||
|
$expected = array(
|
||||||
|
'<p',
|
||||||
|
'<strong', 'test', '/strong',
|
||||||
|
' one, two',
|
||||||
|
'/p',
|
||||||
|
);
|
||||||
|
$this->assertTags($result, $expected);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Test Table generation
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function testTable() {
|
||||||
|
$rows = array(
|
||||||
|
array(1,2),
|
||||||
|
array(3,4),
|
||||||
|
);
|
||||||
|
$result = $this->Toolbar->table($rows);
|
||||||
|
$expected = array(
|
||||||
|
'table' => array('class' =>'debug-table'),
|
||||||
|
array('tr' => array('class' => 'odd')),
|
||||||
|
'<td', '1', '/td',
|
||||||
|
'<td', '2', '/td',
|
||||||
|
'/tr',
|
||||||
|
array('tr' => array('class' => 'even')),
|
||||||
|
'<td', '3', '/td',
|
||||||
|
'<td', '4', '/td',
|
||||||
|
'/tr',
|
||||||
|
'/table'
|
||||||
|
);
|
||||||
|
$this->assertTags($result, $expected);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* reset the view paths
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function endCase() {
|
||||||
|
Configure::write('viewPaths', $this->_viewPaths);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tearDown
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function tearDown() {
|
||||||
|
unset($this->Toolbar, $this->Controller);
|
||||||
|
ClassRegistry::removeObject('view');
|
||||||
|
ClassRegistry::flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
0
site/plugins/debug_kit/tests/fixtures/empty
vendored
Normal file
0
site/plugins/debug_kit/tests/fixtures/empty
vendored
Normal file
0
site/plugins/debug_kit/tests/groups/empty
Normal file
0
site/plugins/debug_kit/tests/groups/empty
Normal file
33
site/plugins/debug_kit/tests/test_app/vendors/test_panel.php
vendored
Normal file
33
site/plugins/debug_kit/tests/test_app/vendors/test_panel.php
vendored
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* Test Panel
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||||
|
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* 1785 E. Sahara Avenue, Suite 490-204
|
||||||
|
* Las Vegas, Nevada 89104
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||||
|
* @package cake.debug_kit
|
||||||
|
* @subpackage cake.debug_kit.tests
|
||||||
|
* @version $Revision$
|
||||||
|
* @modifiedby $LastChangedBy$
|
||||||
|
* @lastmodified $Date$
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
class TestPanel extends DebugPanel {
|
||||||
|
function startup(&$controller) {
|
||||||
|
$controller->testPanel = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
165
site/plugins/debug_kit/vendors/css/debug_toolbar.css
vendored
Normal file
165
site/plugins/debug_kit/vendors/css/debug_toolbar.css
vendored
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
/* @override http://localhost/cake_debug_kit/debug_kit/css/debug_toolbar.css */
|
||||||
|
#debug-kit-toolbar {
|
||||||
|
position: fixed;
|
||||||
|
top: 0px;
|
||||||
|
right:0px;
|
||||||
|
width: 100%;
|
||||||
|
height: 1%;
|
||||||
|
overflow: visible;
|
||||||
|
z-index:10000;
|
||||||
|
}
|
||||||
|
/* panel tabs */
|
||||||
|
#debug-kit-toolbar #panel-tabs {
|
||||||
|
float: right;
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
#debug-kit-toolbar .panel-tab {
|
||||||
|
clear: none;
|
||||||
|
float: left;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#debug-kit-toolbar .panel-tab a {
|
||||||
|
float: left;
|
||||||
|
clear: none;
|
||||||
|
background: #efefef;
|
||||||
|
color: #222;
|
||||||
|
padding: 6px;
|
||||||
|
border-right: 1px solid #ccc;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 16px;
|
||||||
|
margin: 0;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
#debug-kit-toolbar .panel-tab .active,
|
||||||
|
#debug-kit-toolbar .panel-tab a:hover {
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
#debug-kit-toolbar .panel-tab.icon a {
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hovering over link shows tab, useful for no js */
|
||||||
|
#debug-kit-toolbar .panel-tab a:hover + .panel-content,
|
||||||
|
#debug-kit-toolbar .panel-tab a + .panel-content:hover {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* panel content */
|
||||||
|
#debug-kit-toolbar .panel-content {
|
||||||
|
position: absolute;
|
||||||
|
text-align: left;
|
||||||
|
width: auto;
|
||||||
|
top:28px;
|
||||||
|
right:0px;
|
||||||
|
background: #fff;
|
||||||
|
color: #000;
|
||||||
|
width:96%;
|
||||||
|
padding:20px 2%;
|
||||||
|
max-height: 550px;
|
||||||
|
overflow:auto;
|
||||||
|
border-bottom: 3px solid #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hide panel content by default */
|
||||||
|
.panel-content {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-content p {
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
|
.panel-content h2 {
|
||||||
|
padding: 0;
|
||||||
|
margin-top:0;
|
||||||
|
}
|
||||||
|
.panel-content h3 {
|
||||||
|
padding: 0;
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
|
.panel-content .info {
|
||||||
|
padding: 4px;
|
||||||
|
border-top: 1px dashed #6c6cff;
|
||||||
|
border-bottom: 1px dashed #6c6cff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* panel tables */
|
||||||
|
table.debug-table {
|
||||||
|
width: auto;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
table.debug-table td,
|
||||||
|
table.debug-table th {
|
||||||
|
text-align: left;
|
||||||
|
border: 0;
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
table.debug-table th {
|
||||||
|
border-bottom: 1px solid #222;
|
||||||
|
background: 0;;
|
||||||
|
}
|
||||||
|
table.debug-table tr.even td {
|
||||||
|
background:#efefef;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** code tables **/
|
||||||
|
#debug-kit-toolbar .code-table td {
|
||||||
|
white-space: pre;
|
||||||
|
font-family: monaco, corsiva, "courier new", courier, monospaced;
|
||||||
|
}
|
||||||
|
#debug-kit-toolbar .code-table td:first-child {
|
||||||
|
width: 15%;
|
||||||
|
}
|
||||||
|
#debug-kit-toolbar .code-table td:last-child {
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.panel-content.request {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Neat Array styles **/
|
||||||
|
.neat-array {
|
||||||
|
padding: 1px 2px 1px 20px;
|
||||||
|
background: #CE9E23;
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.neat-array .neat-array {
|
||||||
|
padding: 0 0 0 20px;
|
||||||
|
}
|
||||||
|
.neat-array li {
|
||||||
|
background: #FEF6E5;
|
||||||
|
border-top: 1px solid #CE9E23;
|
||||||
|
border-bottom: 1px solid #CE9E23;
|
||||||
|
margin: 0;
|
||||||
|
line-height: 1.5em;
|
||||||
|
}
|
||||||
|
.neat-array li:hover {
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
.neat-array li strong {
|
||||||
|
padding: 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* expandable sections */
|
||||||
|
.neat-array li.expandable {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.neat-array li.expandable.expanded > strong:before {
|
||||||
|
content: 'v ';
|
||||||
|
}
|
||||||
|
.neat-array li.expandable.collapsed > strong:before,
|
||||||
|
.neat-array li.expandable.expanded .expandable.collapsed > strong:before {
|
||||||
|
content: '> ';
|
||||||
|
}
|
||||||
|
|
||||||
|
.neat-array li {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
226
site/plugins/debug_kit/vendors/debug_kit_debugger.php
vendored
Normal file
226
site/plugins/debug_kit/vendors/debug_kit_debugger.php
vendored
Normal file
@@ -0,0 +1,226 @@
|
|||||||
|
<?php
|
||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* DebugKit Debugger class. Extends and enhances core
|
||||||
|
* debugger. Adds benchmarking and timing functionality.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||||
|
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* 1785 E. Sahara Avenue, Suite 490-204
|
||||||
|
* Las Vegas, Nevada 89104
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||||
|
* @package cake
|
||||||
|
* @subpackage cake.cake.libs.
|
||||||
|
* @since CakePHP v 1.2.0.4487
|
||||||
|
* @version $Revision$
|
||||||
|
* @modifiedby $LastChangedBy$
|
||||||
|
* @lastmodified $Date$
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
App::import('Core', 'Debugger');
|
||||||
|
App::import('Vendor', 'DebugKit.FireCake');
|
||||||
|
/**
|
||||||
|
* Debug Kit Temporary Debugger Class
|
||||||
|
*
|
||||||
|
* Provides the future features that are planned. Yet not implemented in the 1.2 code base
|
||||||
|
*
|
||||||
|
* This file will not be needed in future version of CakePHP.
|
||||||
|
* @todo merge these changes with core Debugger
|
||||||
|
*/
|
||||||
|
class DebugKitDebugger extends Debugger {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start an benchmarking timer.
|
||||||
|
*
|
||||||
|
* @param string $name The name of the timer to start.
|
||||||
|
* @param string $message A message for your timer
|
||||||
|
* @return bool true
|
||||||
|
* @static
|
||||||
|
**/
|
||||||
|
function startTimer($name = 'default', $message = '') {
|
||||||
|
$now = getMicrotime();
|
||||||
|
$_this = DebugKitDebugger::getInstance();
|
||||||
|
$_this->__benchmarks[$name] = array(
|
||||||
|
'start' => $now,
|
||||||
|
'message' => $message,
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop a benchmarking timer.
|
||||||
|
*
|
||||||
|
* $name should be the same as the $name used in startTimer().
|
||||||
|
*
|
||||||
|
* @param string $name The name of the timer to end.
|
||||||
|
* @access public
|
||||||
|
* @return boolean true if timer was ended, false if timer was not started.
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
function stopTimer($name = 'default') {
|
||||||
|
$now = getMicrotime();
|
||||||
|
$_this = DebugKitDebugger::getInstance();
|
||||||
|
if (!isset($_this->__benchmarks[$name])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$_this->__benchmarks[$name]['end'] = $now;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all timers that have been started and stopped.
|
||||||
|
* Calculates elapsed time for each timer.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
**/
|
||||||
|
function getTimers() {
|
||||||
|
$_this =& DebugKitDebugger::getInstance();
|
||||||
|
$times = array();
|
||||||
|
foreach ($_this->__benchmarks as $name => $timer) {
|
||||||
|
$times[$name]['time'] = DebugKitDebugger::elapsedTime($name);
|
||||||
|
$times[$name]['message'] = $timer['message'];
|
||||||
|
}
|
||||||
|
return $times;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all existing timers
|
||||||
|
*
|
||||||
|
* @return bool true
|
||||||
|
**/
|
||||||
|
function clearTimers() {
|
||||||
|
$_this =& DebugKitDebugger::getInstance();
|
||||||
|
$_this->__benchmarks = array();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the difference in time between the timer start and timer end.
|
||||||
|
*
|
||||||
|
* @param $name string the name of the timer you want elapsed time for.
|
||||||
|
* @param $precision int the number of decimal places to return, defaults to 5.
|
||||||
|
* @return float number of seconds elapsed for timer name, 0 on missing key
|
||||||
|
* @static
|
||||||
|
**/
|
||||||
|
function elapsedTime($name = 'default', $precision = 5) {
|
||||||
|
$_this =& DebugKitDebugger::getInstance();
|
||||||
|
if (!isset($_this->__benchmarks[$name]['start']) || !isset($_this->__benchmarks[$name]['end'])) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return round($_this->__benchmarks[$name]['end'] - $_this->__benchmarks[$name]['start'], $precision);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the total execution time until this point
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return float elapsed time in seconds since script start.
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
function requestTime() {
|
||||||
|
$start = DebugKitDebugger::requestStartTime();
|
||||||
|
$now = getMicroTime();
|
||||||
|
return ($now - $start);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* get the time the current request started.
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return float time of request start
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
function requestStartTime() {
|
||||||
|
if (defined('TIME_START')) {
|
||||||
|
$startTime = TIME_START;
|
||||||
|
} else if (isset($_GLOBALS['TIME_START'])) {
|
||||||
|
$startTime = $_GLOBALS['TIME_START'];
|
||||||
|
} else {
|
||||||
|
$startTime = env('REQUEST_TIME');
|
||||||
|
}
|
||||||
|
return $startTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get current memory usage
|
||||||
|
*
|
||||||
|
* @return integer number of bytes ram currently in use. 0 if memory_get_usage() is not available.
|
||||||
|
* @static
|
||||||
|
**/
|
||||||
|
function getMemoryUse() {
|
||||||
|
if (!function_exists('memory_get_usage')) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return memory_get_usage();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get peak memory use
|
||||||
|
*
|
||||||
|
* @return integer peak memory use (in bytes). Returns 0 if memory_get_peak_usage() is not available
|
||||||
|
* @static
|
||||||
|
**/
|
||||||
|
function getPeakMemoryUse() {
|
||||||
|
if (!function_exists('memory_get_peak_usage')) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return memory_get_peak_usage();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles object conversion to debug string.
|
||||||
|
*
|
||||||
|
* @param string $var Object to convert
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function _output($level, $error, $code, $helpCode, $description, $file, $line, $kontext) {
|
||||||
|
$files = $this->trace(array('start' => 2, 'format' => 'points'));
|
||||||
|
$listing = $this->excerpt($files[0]['file'], $files[0]['line'] - 1, 1);
|
||||||
|
$trace = $this->trace(array('start' => 2, 'depth' => '20'));
|
||||||
|
$context = array();
|
||||||
|
|
||||||
|
foreach ((array)$kontext as $var => $value) {
|
||||||
|
$context[] = "\${$var}\t=\t" . $this->exportVar($value, 1);
|
||||||
|
}
|
||||||
|
if ($this->_outputFormat == 'fb') {
|
||||||
|
$this->_fireError($error, $code, $description, $file, $line, $trace, $context);
|
||||||
|
} else {
|
||||||
|
echo parent::_output($level, $error, $code, $helpCode, $description, $file, $line, $kontext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Create a FirePHP error message
|
||||||
|
*
|
||||||
|
* @param string $error Name of error
|
||||||
|
* @param string $code Code of error
|
||||||
|
* @param string $description Description of error
|
||||||
|
* @param string $file File error occured in
|
||||||
|
* @param string $line Line error occured on
|
||||||
|
* @param string $trace Stack trace at time of error
|
||||||
|
* @param string $context context of error
|
||||||
|
* @return void
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function _fireError($error, $code, $description, $file, $line, $trace, $context) {
|
||||||
|
$name = $error . ' - ' . $description;
|
||||||
|
$message = "$error $code $description on line: $line in file: $file";
|
||||||
|
FireCake::group($name);
|
||||||
|
FireCake::error($message, $name);
|
||||||
|
FireCake::log($context, 'Context');
|
||||||
|
FireCake::log($trace, 'Trace');
|
||||||
|
FireCake::groupEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Debugger::invoke(DebugKitDebugger::getInstance());
|
||||||
|
Debugger::getInstance('DebugKitDebugger');
|
||||||
|
?>
|
||||||
539
site/plugins/debug_kit/vendors/fire_cake.php
vendored
Normal file
539
site/plugins/debug_kit/vendors/fire_cake.php
vendored
Normal file
@@ -0,0 +1,539 @@
|
|||||||
|
<?php
|
||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* FirePHP Class for CakePHP
|
||||||
|
*
|
||||||
|
* Provides most of the functionality offered by FirePHPCore
|
||||||
|
* Interoperates with FirePHP extension for firefox
|
||||||
|
*
|
||||||
|
* For more information see: http://www.firephp.org/
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||||
|
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* 1785 E. Sahara Avenue, Suite 490-204
|
||||||
|
* Las Vegas, Nevada 89104
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||||
|
* @package debug_kit.
|
||||||
|
* @subpackage debug_kit.vendors
|
||||||
|
* @since
|
||||||
|
* @version $Revision$
|
||||||
|
* @modifiedby $LastChangedBy$
|
||||||
|
* @lastmodified $Date$
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
App::import('Core', 'Debugger');
|
||||||
|
|
||||||
|
class FireCake extends Object {
|
||||||
|
/**
|
||||||
|
* Options for FireCake.
|
||||||
|
*
|
||||||
|
* @see _defaultOptions and setOptions();
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
var $options = array();
|
||||||
|
/**
|
||||||
|
* Default Options used in CakeFirePhp
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
var $_defaultOptions = array(
|
||||||
|
'maxObjectDepth' => 10,
|
||||||
|
'maxArrayDepth' => 20,
|
||||||
|
'useNativeJsonEncode' => true,
|
||||||
|
'includeLineNumbers' => true,
|
||||||
|
);
|
||||||
|
/**
|
||||||
|
* Message Levels for messages sent via FirePHP
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
var $_levels = array(
|
||||||
|
'log' => 'LOG',
|
||||||
|
'info' => 'INFO',
|
||||||
|
'warn' => 'WARN',
|
||||||
|
'error' => 'ERROR',
|
||||||
|
'dump' => 'DUMP',
|
||||||
|
'trace' => 'TRACE',
|
||||||
|
'exception' => 'EXCEPTION',
|
||||||
|
'table' => 'TABLE',
|
||||||
|
'groupStart' => 'GROUP_START',
|
||||||
|
'groupEnd' => 'GROUP_END',
|
||||||
|
);
|
||||||
|
|
||||||
|
var $_version = '0.2.1';
|
||||||
|
/**
|
||||||
|
* internal messageIndex counter
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
var $_messageIndex = 1;
|
||||||
|
/**
|
||||||
|
* stack of objects encoded by stringEncode()
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
**/
|
||||||
|
var $_encodedObjects = array();
|
||||||
|
/**
|
||||||
|
* methodIndex to include in tracebacks when using includeLineNumbers
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
**/
|
||||||
|
var $_methodIndex = array('info', 'log', 'warn', 'error', 'table', 'trace');
|
||||||
|
/**
|
||||||
|
* FireCake output status
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
**/
|
||||||
|
var $_enabled = true;
|
||||||
|
/**
|
||||||
|
* get Instance of the singleton
|
||||||
|
*
|
||||||
|
* @param string $class Class instance to store in the singleton. Used with subclasses and Tests.
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function &getInstance($class = null) {
|
||||||
|
static $instance = array();
|
||||||
|
if (!empty($class)) {
|
||||||
|
if (!$instance || strtolower($class) != strtolower(get_class($instance[0]))) {
|
||||||
|
$instance[0] = new $class();
|
||||||
|
$instance[0]->setOptions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isset($instance[0]) || !$instance[0]) {
|
||||||
|
$instance[0] = new FireCake();
|
||||||
|
$instance[0]->setOptions();
|
||||||
|
}
|
||||||
|
return $instance[0];
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* setOptions
|
||||||
|
*
|
||||||
|
* @param array $options Array of options to set.
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function setOptions($options = array()) {
|
||||||
|
$_this = FireCake::getInstance();
|
||||||
|
if (empty($_this->options)) {
|
||||||
|
$_this->options = array_merge($_this->_defaultOptions, $options);
|
||||||
|
} else {
|
||||||
|
$_this->options = array_merge($_this->options, $options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Return boolean based on presence of FirePHP extension
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return boolean
|
||||||
|
**/
|
||||||
|
function detectClientExtension() {
|
||||||
|
$ua = FireCake::getUserAgent();
|
||||||
|
if (!preg_match('/\sFirePHP\/([\.|\d]*)\s?/si', $ua, $match) || !version_compare($match[1], '0.0.6', '>=')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Get the Current UserAgent
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
* @return string UserAgent string of active client connection
|
||||||
|
**/
|
||||||
|
function getUserAgent() {
|
||||||
|
return env('HTTP_USER_AGENT');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Disable FireCake output
|
||||||
|
* All subsequent output calls will not be run.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function disable() {
|
||||||
|
$_this = FireCake::getInstance();
|
||||||
|
$_this->_enabled = false;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Enable FireCake output
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function enable() {
|
||||||
|
$_this = FireCake::getInstance();
|
||||||
|
$_this->_enabled = true;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Convenience wrapper for LOG messages
|
||||||
|
*
|
||||||
|
* @param string $message Message to log
|
||||||
|
* @param string $label Label for message (optional)
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function log($message, $label = null) {
|
||||||
|
FireCake::fb($message, $label, 'log');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Convenience wrapper for WARN messages
|
||||||
|
*
|
||||||
|
* @param string $message Message to log
|
||||||
|
* @param string $label Label for message (optional)
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function warn($message, $label = null) {
|
||||||
|
FireCake::fb($message, $label, 'warn');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Convenience wrapper for INFO messages
|
||||||
|
*
|
||||||
|
* @param string $message Message to log
|
||||||
|
* @param string $label Label for message (optional)
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function info($message, $label = null) {
|
||||||
|
FireCake::fb($message, $label, 'info');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Convenience wrapper for ERROR messages
|
||||||
|
*
|
||||||
|
* @param string $message Message to log
|
||||||
|
* @param string $label Label for message (optional)
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function error($message, $label = null) {
|
||||||
|
FireCake::fb($message, $label, 'error');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Convenience wrapper for TABLE messages
|
||||||
|
*
|
||||||
|
* @param string $message Message to log
|
||||||
|
* @param string $label Label for message (optional)
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function table($label, $message) {
|
||||||
|
FireCake::fb($message, $label, 'table');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Convenience wrapper for DUMP messages
|
||||||
|
*
|
||||||
|
* @param string $message Message to log
|
||||||
|
* @param string $label Unique label for message
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function dump($label, $message) {
|
||||||
|
FireCake::fb($message, $label, 'dump');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Convenience wrapper for TRACE messages
|
||||||
|
*
|
||||||
|
* @param string $label Label for message (optional)
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function trace($label) {
|
||||||
|
FireCake::fb($label, 'trace');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Convenience wrapper for GROUP messages
|
||||||
|
* Messages following the group call will be nested in a group block
|
||||||
|
*
|
||||||
|
* @param string $label Label for group (optional)
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function group($label) {
|
||||||
|
FireCake::fb(null, $label, 'groupStart');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Convenience wrapper for GROUPEND messages
|
||||||
|
* Closes a group block
|
||||||
|
*
|
||||||
|
* @param string $label Label for group (optional)
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function groupEnd() {
|
||||||
|
FireCake::fb(null, null, 'groupEnd');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* fb - Send messages with FireCake to FirePHP
|
||||||
|
*
|
||||||
|
* Much like FirePHP's fb() this method can be called with various parameter counts
|
||||||
|
* fb($message) - Just send a message defaults to LOG type
|
||||||
|
* fb($message, $type) - Send a message with a specific type
|
||||||
|
* fb($message, $label, $type) - Send a message with a custom label and type.
|
||||||
|
*
|
||||||
|
* @param mixed $message Message to output. For other parameters see usage above.
|
||||||
|
* @static
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function fb($message) {
|
||||||
|
$_this = FireCake::getInstance();
|
||||||
|
|
||||||
|
if (headers_sent($filename, $linenum)) {
|
||||||
|
trigger_error(sprintf(__('Headers already sent in %s on line %s. Cannot send log data to FirePHP.', true), $filename, $linenum), E_USER_WARNING);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!$_this->_enabled || !$_this->detectClientExtension()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$args = func_get_args();
|
||||||
|
$type = $label = null;
|
||||||
|
switch (count($args)) {
|
||||||
|
case 1:
|
||||||
|
$type = $_this->_levels['log'];
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
$type = $args[1];
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
$type = $args[2];
|
||||||
|
$label = $args[1];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
trigger_error(__('Incorrect parameter count for FireCake::fb()', true), E_USER_WARNING);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (isset($_this->_levels[$type])) {
|
||||||
|
$type = $_this->_levels[$type];
|
||||||
|
} else {
|
||||||
|
$type = $_this->_levels['log'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$meta = array();
|
||||||
|
$skipFinalObjectEncode = false;
|
||||||
|
if ($type == $_this->_levels['trace']) {
|
||||||
|
$trace = debug_backtrace();
|
||||||
|
if (!$trace) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$message = $_this->_parseTrace($trace, $args[0]);
|
||||||
|
$skipFinalObjectEncode = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($_this->options['includeLineNumbers']) {
|
||||||
|
if (!isset($meta['file']) || !isset($meta['line'])) {
|
||||||
|
$trace = debug_backtrace();
|
||||||
|
for ($i = 0, $len = count($trace); $i < $len ; $i++) {
|
||||||
|
$keySet = (isset($trace[$i]['class']) && isset($trace[$i]['function']));
|
||||||
|
$selfCall = ($keySet && $trace[$i]['class'] == 'FireCake' && in_array($trace[$i]['function'], $_this->_methodIndex));
|
||||||
|
if ($selfCall) {
|
||||||
|
$meta['File'] = isset($trace[$i]['file']) ? Debugger::trimPath($trace[$i]['file']) : '';
|
||||||
|
$meta['Line'] = isset($trace[$i]['line']) ? $trace[$i]['line'] : '';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$structureIndex = 1;
|
||||||
|
if ($type == $_this->_levels['dump']) {
|
||||||
|
$structureIndex = 2;
|
||||||
|
$_this->_sendHeader('X-Wf-1-Structure-2','http://meta.firephp.org/Wildfire/Structure/FirePHP/Dump/0.1');
|
||||||
|
} else {
|
||||||
|
$_this->_sendHeader('X-Wf-1-Structure-1','http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1');
|
||||||
|
}
|
||||||
|
|
||||||
|
$_this->_sendHeader('X-Wf-Protocol-1', 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2');
|
||||||
|
$_this->_sendHeader('X-Wf-1-Plugin-1', 'http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/'. $_this->_version);
|
||||||
|
|
||||||
|
if ($type == $_this->_levels['dump']) {
|
||||||
|
$dump = $_this->jsonEncode($message);
|
||||||
|
$msg = '{"' . $label .'":' . $dump .'}';
|
||||||
|
} else {
|
||||||
|
$meta['Type'] = $type;
|
||||||
|
if ($label !== null) {
|
||||||
|
$meta['Label'] = $label;
|
||||||
|
}
|
||||||
|
$msg = '[' . $_this->jsonEncode($meta) . ',' . $_this->jsonEncode($message, $skipFinalObjectEncode).']';
|
||||||
|
}
|
||||||
|
|
||||||
|
$lines = explode("\n", chunk_split($msg, 5000, "\n"));
|
||||||
|
foreach ($lines as $i => $line) {
|
||||||
|
if (empty($line)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$header = 'X-Wf-1-' . $structureIndex . '-1-' . $_this->_messageIndex;
|
||||||
|
if (count($lines) > 2) {
|
||||||
|
$first = ($i == 0) ? strlen($msg) : '';
|
||||||
|
$end = ($i < count($lines) - 2) ? '\\' : '';
|
||||||
|
$message = $first . '|' . $line . '|' . $end;
|
||||||
|
$_this->_sendHeader($header, $message);
|
||||||
|
} else {
|
||||||
|
$_this->_sendHeader($header, strlen($line) . '|' . $line . '|');
|
||||||
|
}
|
||||||
|
$_this->_messageIndex++;
|
||||||
|
if ($_this->_messageIndex > 99999) {
|
||||||
|
trigger_error(__('Maximum number (99,999) of messages reached!', true), E_USER_WARNING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$_this->_sendHeader('X-Wf-1-Index', $_this->_messageIndex - 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Parse a debug backtrace
|
||||||
|
*
|
||||||
|
* @param array $trace Debug backtrace output
|
||||||
|
* @access protected
|
||||||
|
* @return array
|
||||||
|
**/
|
||||||
|
function _parseTrace($trace, $messageName) {
|
||||||
|
$message = array();
|
||||||
|
for ($i = 0, $len = count($trace); $i < $len ; $i++) {
|
||||||
|
$keySet = (isset($trace[$i]['class']) && isset($trace[$i]['function']));
|
||||||
|
$selfCall = ($keySet && $trace[$i]['class'] == 'FireCake');
|
||||||
|
if (!$selfCall) {
|
||||||
|
$message = array(
|
||||||
|
'Class' => isset($trace[$i]['class']) ? $trace[$i]['class'] : '',
|
||||||
|
'Type' => isset($trace[$i]['type']) ? $trace[$i]['type'] : '',
|
||||||
|
'Function' => isset($trace[$i]['function']) ? $trace[$i]['function'] : '',
|
||||||
|
'Message' => $messageName,
|
||||||
|
'File' => isset($trace[$i]['file']) ? Debugger::trimPath($trace[$i]['file']) : '',
|
||||||
|
'Line' => isset($trace[$i]['line']) ? $trace[$i]['line'] : '',
|
||||||
|
'Args' => isset($trace[$i]['args']) ? $this->stringEncode($trace[$i]['args']) : '',
|
||||||
|
'Trace' => $this->_escapeTrace(array_splice($trace, $i + 1))
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $message;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Fix a trace for use in output
|
||||||
|
*
|
||||||
|
* @param mixed $trace Trace to fix
|
||||||
|
* @access protected
|
||||||
|
* @static
|
||||||
|
* @return string
|
||||||
|
**/
|
||||||
|
function _escapeTrace($trace) {
|
||||||
|
for ($i = 0, $len = count($trace); $i < $len; $i++) {
|
||||||
|
if (isset($trace[$i]['file'])) {
|
||||||
|
$trace[$i]['file'] = Debugger::trimPath($trace[$i]['file']);
|
||||||
|
}
|
||||||
|
if (isset($trace[$i]['args'])) {
|
||||||
|
$trace[$i]['args'] = $this->stringEncode($trace[$i]['args']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $trace;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Encode non string objects to string.
|
||||||
|
* Filter out recursion, so no errors are raised by json_encode or $javascript->object()
|
||||||
|
*
|
||||||
|
* @param mixed $object Object or variable to encode to string.
|
||||||
|
* @param int $objectDepth Current Depth in object chains.
|
||||||
|
* @param int $arrayDepth Current Depth in array chains.
|
||||||
|
* @static
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function stringEncode($object, $objectDepth = 1, $arrayDepth = 1) {
|
||||||
|
$_this = FireCake::getInstance();
|
||||||
|
$return = array();
|
||||||
|
if (is_resource($object)) {
|
||||||
|
return '** ' . (string)$object . '**';
|
||||||
|
}
|
||||||
|
if (is_object($object)) {
|
||||||
|
if ($objectDepth == $_this->options['maxObjectDepth']) {
|
||||||
|
return '** Max Object Depth (' . $_this->options['maxObjectDepth'] . ') **';
|
||||||
|
}
|
||||||
|
foreach ($_this->_encodedObjects as $encoded) {
|
||||||
|
if ($encoded === $object) {
|
||||||
|
return '** Recursion (' . get_class($object) . ') **';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$_this->_encodedObjects[] = $object;
|
||||||
|
|
||||||
|
$return['__className'] = $class = get_class($object);
|
||||||
|
$properties = (array) $object;
|
||||||
|
foreach ($properties as $name => $property) {
|
||||||
|
$return[$name] = FireCake::stringEncode($property, 1, $objectDepth + 1);
|
||||||
|
}
|
||||||
|
array_pop($_this->_encodedObjects);
|
||||||
|
}
|
||||||
|
if (is_array($object)) {
|
||||||
|
if ($arrayDepth == $_this->options['maxArrayDepth']) {
|
||||||
|
return '** Max Array Depth ('. $_this->options['maxArrayDepth'] . ') **';
|
||||||
|
}
|
||||||
|
foreach ($object as $key => $value) {
|
||||||
|
$return[$key] = FireCake::stringEncode($value, 1, $arrayDepth + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_string($object) || is_numeric($object) || is_bool($object) || is_null($object)) {
|
||||||
|
return $object;
|
||||||
|
}
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Encode an object into JSON
|
||||||
|
*
|
||||||
|
* @param mixed $object Object or array to json encode
|
||||||
|
* @param boolean $doIt
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
* @return string
|
||||||
|
**/
|
||||||
|
function jsonEncode($object, $skipEncode = false) {
|
||||||
|
$_this = FireCake::getInstance();
|
||||||
|
if (!$skipEncode) {
|
||||||
|
$object = FireCake::stringEncode($object);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (function_exists('json_encode') && $_this->options['useNativeJsonEncode']) {
|
||||||
|
return json_encode($object);
|
||||||
|
} else {
|
||||||
|
return FireCake::_jsonEncode($object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* jsonEncode Helper method for PHP4 compatibility
|
||||||
|
*
|
||||||
|
* @param mixed $object Something to encode
|
||||||
|
* @access protected
|
||||||
|
* @static
|
||||||
|
* @return string
|
||||||
|
**/
|
||||||
|
function _jsonEncode($object) {
|
||||||
|
if (!class_exists('JavascriptHelper')) {
|
||||||
|
App::import('Helper', 'Javascript');
|
||||||
|
}
|
||||||
|
$javascript = new JavascriptHelper();
|
||||||
|
$javascript->useNative = false;
|
||||||
|
return $javascript->object($object);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Send Headers - write headers.
|
||||||
|
*
|
||||||
|
* @access protected
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
function _sendHeader($name, $value) {
|
||||||
|
header($name . ': ' . $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
BIN
site/plugins/debug_kit/vendors/img/cake.icon.png
vendored
Normal file
BIN
site/plugins/debug_kit/vendors/img/cake.icon.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.0 KiB |
84
site/plugins/debug_kit/vendors/js/jquery_debug_toolbar.js
vendored
Normal file
84
site/plugins/debug_kit/vendors/js/jquery_debug_toolbar.js
vendored
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* Debug Toolbar Javascript. jQuery 1.2.x compatible.
|
||||||
|
*
|
||||||
|
* Long description here.
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||||
|
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* 1785 E. Sahara Avenue, Suite 490-204
|
||||||
|
* Las Vegas, Nevada 89104
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||||
|
* @package cake
|
||||||
|
* @subpackage cake.cake.libs.
|
||||||
|
* @since CakePHP v 1.2.0.4487
|
||||||
|
* @version $Revision$
|
||||||
|
* @modifiedby $LastChangedBy$
|
||||||
|
* @lastmodified $Date$
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function($) {
|
||||||
|
$(document).ready(function(){
|
||||||
|
DebugKit.Toolbar();
|
||||||
|
DebugKit.NeatArray();
|
||||||
|
});
|
||||||
|
|
||||||
|
var DebugKit = {};
|
||||||
|
/**
|
||||||
|
* Create all behaviors for neat array elements
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
DebugKit.NeatArray = function() {
|
||||||
|
$('.neat-array').find('li:has(ul)').toggle(
|
||||||
|
function() {
|
||||||
|
$(this).toggleClass('expanded').removeClass('collapsed').find('ul:first').show();
|
||||||
|
},
|
||||||
|
function() {
|
||||||
|
$(this).toggleClass('expanded').addClass('collapsed').find('ul:first').hide();
|
||||||
|
}
|
||||||
|
).addClass('expandable').addClass('collapsed').find('ul').hide();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Add behavior for toolbar buttons
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
DebugKit.Toolbar = function() {
|
||||||
|
var tabCollection = $('#debug-kit-toolbar li > div');
|
||||||
|
|
||||||
|
$('#debug-kit-toolbar .panel-tab > a').click(
|
||||||
|
function(e){
|
||||||
|
e.preventDefault();
|
||||||
|
var targetPanel = $(this.hash + '-tab');
|
||||||
|
if (targetPanel.hasClass('active')) {
|
||||||
|
tabCollection.hide().removeClass('active');
|
||||||
|
} else {
|
||||||
|
tabCollection
|
||||||
|
.hide().removeClass('active')
|
||||||
|
.filter(this.hash + '-tab').show().addClass('active');
|
||||||
|
}
|
||||||
|
$('#debug-kit-toolbar .panel-tab > a').removeClass('active');
|
||||||
|
$(this).addClass('active');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
//enable hiding of toolbar.
|
||||||
|
var panelButtons = $('#debug-kit-toolbar .panel-tab:not(.panel-tab.icon)');
|
||||||
|
$('#debug-kit-toolbar #hide-toolbar').toggle(
|
||||||
|
function() {
|
||||||
|
panelButtons.hide();
|
||||||
|
},
|
||||||
|
function() {
|
||||||
|
panelButtons.show();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})(jQuery);
|
||||||
212
site/plugins/debug_kit/vendors/js/js_debug_toolbar.js
vendored
Normal file
212
site/plugins/debug_kit/vendors/js/js_debug_toolbar.js
vendored
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* Debug Toolbar Javascript.
|
||||||
|
*
|
||||||
|
* Long description here.
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||||
|
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* 1785 E. Sahara Avenue, Suite 490-204
|
||||||
|
* Las Vegas, Nevada 89104
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||||
|
* @package cake
|
||||||
|
* @subpackage cake.cake.libs.
|
||||||
|
* @since CakePHP v 1.2.0.4487
|
||||||
|
* @version $Revision$
|
||||||
|
* @modifiedby $LastChangedBy$
|
||||||
|
* @lastmodified $Date$
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
var DebugKit = function(id) {
|
||||||
|
var undefined,
|
||||||
|
elements = {},
|
||||||
|
panels = {},
|
||||||
|
hidden = false;
|
||||||
|
|
||||||
|
this.initialize = function(id) {
|
||||||
|
elements.toolbar = document.getElementById(id || 'debug-kit-toolbar');
|
||||||
|
|
||||||
|
if (elements.toolbar === undefined) {
|
||||||
|
throw new Exception('Toolbar not found, make sure you loaded it.');
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i in elements.toolbar.childNodes) {
|
||||||
|
var element = elements.toolbar.childNodes[i];
|
||||||
|
if (element.nodeName && element.id === 'panel-tabs') {
|
||||||
|
elements.panel = element;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i in elements.panel.childNodes) {
|
||||||
|
var element = elements.panel.childNodes[i];
|
||||||
|
if (element.className && element.className.match(/panel-tab/)) {
|
||||||
|
this.addPanel(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var lists = document.getElementsByTagName('ul'), index = 0;
|
||||||
|
while (lists[index] !== undefined) {
|
||||||
|
var element = lists[index];
|
||||||
|
if (element.className && element.className.match(/neat-array/)) {
|
||||||
|
neatArray(element);
|
||||||
|
}
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Add a panel to the toolbar
|
||||||
|
*/
|
||||||
|
this.addPanel = function(tab, callback) {
|
||||||
|
if (!tab.nodeName || tab.nodeName.toUpperCase() !== 'LI') {
|
||||||
|
throw new Exception('Toolbar not found, make sure you loaded it.');
|
||||||
|
}
|
||||||
|
var panel = {
|
||||||
|
id : false,
|
||||||
|
element : tab,
|
||||||
|
callback : callback,
|
||||||
|
button : undefined,
|
||||||
|
content : undefined,
|
||||||
|
active : false
|
||||||
|
};
|
||||||
|
for (var i in tab.childNodes) {
|
||||||
|
var element = tab.childNodes[i],
|
||||||
|
tag = element.nodeName? element.nodeName.toUpperCase(): false;
|
||||||
|
if (tag === 'A') {
|
||||||
|
panel.id = element.hash.replace(/^#/, '');
|
||||||
|
panel.button = element;
|
||||||
|
} else if (tag === 'DIV') {
|
||||||
|
panel.content = element;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!panel.id) {
|
||||||
|
throw new Exception('invalid element');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (panel.button.id && panel.button.id === 'hide-toolbar') {
|
||||||
|
panel.callback = this.toggleToolbar;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (panel.callback !== undefined) {
|
||||||
|
panel.button.onclick = function() { return panel.callback(); };
|
||||||
|
} else {
|
||||||
|
panel.button.onclick = function() { return window.DebugKit.togglePanel(panel.id); };
|
||||||
|
}
|
||||||
|
|
||||||
|
panels[panel.id] = panel;
|
||||||
|
return panel.id;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Hide/show the toolbar (minimize cake)
|
||||||
|
*/
|
||||||
|
this.toggleToolbar = function() {
|
||||||
|
for (var i in panels) {
|
||||||
|
var panel = panels[i],
|
||||||
|
display = hidden? 'block': 'none';
|
||||||
|
if (panel.content !== undefined) {
|
||||||
|
panel.element.style.display = display;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hidden = !hidden;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Toggle a panel
|
||||||
|
*/
|
||||||
|
this.togglePanel = function(id) {
|
||||||
|
if (panels[id] && panels[id].active) {
|
||||||
|
this.deactivatePanel(true);
|
||||||
|
} else {
|
||||||
|
this.deactivatePanel(true);
|
||||||
|
this.activatePanel(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Make a panel active.
|
||||||
|
*/
|
||||||
|
this.activatePanel = function(id, unique) {
|
||||||
|
if (panels[id] !== undefined && !panels[id].active) {
|
||||||
|
var panel = panels[id];
|
||||||
|
this.deactivatePanel(true);
|
||||||
|
if (panel.content !== undefined) {
|
||||||
|
panel.content.style.display = 'block';
|
||||||
|
}
|
||||||
|
panel.button.className = panel.button.className.replace(/^(.*)$/, '$1 active');
|
||||||
|
panel.active = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Deactivate a panel. use true to hide all panels.
|
||||||
|
*/
|
||||||
|
this.deactivatePanel = function(id) {
|
||||||
|
if (id === true) {
|
||||||
|
for (var i in panels) {
|
||||||
|
this.deactivatePanel(i);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (panels[id] !== undefined && panels[id].active) {
|
||||||
|
var panel = panels[id];
|
||||||
|
if (panel.content !== undefined) {
|
||||||
|
panel.content.style.display = 'none';
|
||||||
|
}
|
||||||
|
panel.button.className = panel.button.className.replace(/ ?(active) ?/, '');
|
||||||
|
panel.active = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Add neat array functionality.
|
||||||
|
*/
|
||||||
|
function neatArray(list) {
|
||||||
|
if (!list.className.match(/depth-0/)) {
|
||||||
|
var item = list.parentNode;
|
||||||
|
list.style.display = 'none';
|
||||||
|
item.className = (item.className || '').replace(/^(.*)$/, '$1 expandable collapsed');
|
||||||
|
item.onclick = function(event) {
|
||||||
|
//var element = (event === undefined)? this: event.target;
|
||||||
|
var element = this,
|
||||||
|
event = event || window.event,
|
||||||
|
act = Boolean(item === element),
|
||||||
|
hide = Boolean(list.style.display === 'block');
|
||||||
|
if (act && hide) {
|
||||||
|
list.style.display = 'none';
|
||||||
|
item.className = item.className.replace(/expanded|$/, 'collapsed');
|
||||||
|
} else if (act) {
|
||||||
|
list.style.display = 'block';
|
||||||
|
item.className = item.className.replace('collapsed', 'expanded');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.cancelBubble !== undefined) {
|
||||||
|
event.cancelBubble = true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.initialize(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugKit.install = function() {
|
||||||
|
var initializer = window.onload || function() {};
|
||||||
|
window.onload = function() {
|
||||||
|
initializer();
|
||||||
|
// makes DebugKit a singletone instance
|
||||||
|
window.DebugKit = new DebugKit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugKit.install();
|
||||||
95
site/plugins/debug_kit/vendors/js/mootools_debug_toolbar.js
vendored
Normal file
95
site/plugins/debug_kit/vendors/js/mootools_debug_toolbar.js
vendored
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* Debug Toolbar Javascript. Mootools 1.2 compatible.
|
||||||
|
*
|
||||||
|
* Requires Class, Event, Element, and Selectors
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||||
|
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* 1785 E. Sahara Avenue, Suite 490-204
|
||||||
|
* Las Vegas, Nevada 89104
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||||
|
* @package cake
|
||||||
|
* @subpackage cake.cake.libs.
|
||||||
|
* @since CakePHP v 1.2.0.4487
|
||||||
|
* @version $Revision$
|
||||||
|
* @modifiedby $LastChangedBy$
|
||||||
|
* @lastmodified $Date$
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
window.addEvent('domready', function() {
|
||||||
|
new DebugKit();
|
||||||
|
});
|
||||||
|
var DebugKit = new Class({
|
||||||
|
initialize : function() {
|
||||||
|
this.neatArray();
|
||||||
|
this.toolbar();
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Create all behaviors for neat array elements
|
||||||
|
*/
|
||||||
|
neatArray : function() {
|
||||||
|
$$('#debug-kit-toolbar .neat-array li').each(function(listItem) {
|
||||||
|
var subUl = listItem.getElement('ul');
|
||||||
|
if (subUl) {
|
||||||
|
listItem.addClass('expandable').addClass('collapsed');
|
||||||
|
subUl.setStyle('display', 'none').set('state', 'closed');
|
||||||
|
listItem.addEvent('click', function(event) {
|
||||||
|
event.stop();
|
||||||
|
this.toggleClass('expanded').toggleClass('collapsed');
|
||||||
|
if (subUl.get('state') == 'closed') {
|
||||||
|
subUl.setStyle('display', 'block').set('state', 'open');
|
||||||
|
} else {
|
||||||
|
subUl.setStyle('display', 'none').set('state', 'closed');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add behavior for toolbar buttons
|
||||||
|
*/
|
||||||
|
toolbar : function() {
|
||||||
|
var tabCollection = $$('#debug-kit-toolbar li > div');
|
||||||
|
|
||||||
|
$$('#debug-kit-toolbar .panel-tab > a').addEvent('click', function(event) {
|
||||||
|
event.stop();
|
||||||
|
var buttonId = this.hash.substring(1, this.hash.length) + '-tab';
|
||||||
|
var targetPanel = $(buttonId);
|
||||||
|
if (!targetPanel) return;
|
||||||
|
$$('#debug-kit-toolbar .panel-tab > a').removeClass('active');
|
||||||
|
if (targetPanel.hasClass('active')) {
|
||||||
|
tabCollection.removeClass('active').setStyle('display', 'none');
|
||||||
|
} else {
|
||||||
|
tabCollection.setStyle('display', 'none').removeClass('active');
|
||||||
|
targetPanel.addClass('active').setStyle('display', 'block');
|
||||||
|
this.addClass('active');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//enable hiding of toolbar.
|
||||||
|
var panelButtons = $$('#debug-kit-toolbar .panel-tab:not(.panel-tab.icon)');
|
||||||
|
var toolbarHide = $('hide-toolbar').set('state', 'open');
|
||||||
|
toolbarHide.addEvent('click', function(event) {
|
||||||
|
event.stop();
|
||||||
|
var state = this.get('state');
|
||||||
|
if (state == 'open') {
|
||||||
|
panelButtons.setStyle('display', 'none');
|
||||||
|
this.set('state', 'closed')
|
||||||
|
} else {
|
||||||
|
panelButtons.setStyle('display');
|
||||||
|
this.set('state', 'open');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
95
site/plugins/debug_kit/vendors/js/prototype_debug_toolbar.js
vendored
Normal file
95
site/plugins/debug_kit/vendors/js/prototype_debug_toolbar.js
vendored
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* Debug Toolbar Javascript. Prototype 1.6.x compatible.
|
||||||
|
*
|
||||||
|
* Long description here.
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||||
|
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* 1785 E. Sahara Avenue, Suite 490-204
|
||||||
|
* Las Vegas, Nevada 89104
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||||
|
* @package cake
|
||||||
|
* @subpackage cake.cake.libs.
|
||||||
|
* @since CakePHP v 1.2.0.4487
|
||||||
|
* @version $Revision$
|
||||||
|
* @modifiedby $LastChangedBy$
|
||||||
|
* @lastmodified $Date$
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
document.observe('dom:loaded', function() {
|
||||||
|
new DebugKit();
|
||||||
|
});
|
||||||
|
|
||||||
|
var DebugKit = Class.create({
|
||||||
|
|
||||||
|
initialize: function(){
|
||||||
|
this.toolbar();
|
||||||
|
this.neatArray();
|
||||||
|
},
|
||||||
|
|
||||||
|
toolbar: function(){
|
||||||
|
var tabCollection = $('debug-kit-toolbar').select('li > div');
|
||||||
|
|
||||||
|
$('debug-kit-toolbar').select('.panel-tab > a').invoke('observe', 'click', function(e){
|
||||||
|
e.stop();
|
||||||
|
var targetPanel = $(e.element().hash.replace(/#/, '') + '-tab');
|
||||||
|
if (targetPanel.hasClassName('active')) {
|
||||||
|
tabCollection.each(function(ele){
|
||||||
|
ele.hide().removeClassName('active');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
tabCollection.each(function(ele){
|
||||||
|
ele.hide().removeClassName('active');
|
||||||
|
if (targetPanel.id == ele.id) {
|
||||||
|
ele.setStyle({display: 'block'}).addClassName('active');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
$('debug-kit-toolbar').select('.panel-tab > a').invoke('removeClassName', 'active');
|
||||||
|
e.element().addClassName('active');
|
||||||
|
});
|
||||||
|
|
||||||
|
// enable hiding of toolbar.
|
||||||
|
var panelButtons = $('debug-kit-toolbar').select('.panel-tab');
|
||||||
|
$('hide-toolbar').observe('click', function(eve){
|
||||||
|
eve.stop();
|
||||||
|
panelButtons.each(function(panel){
|
||||||
|
if (!panel.hasClassName('icon')) {
|
||||||
|
panel.toggle();
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create all behaviors for neat array elements
|
||||||
|
*/
|
||||||
|
neatArray: function() {
|
||||||
|
$('debug-kit-toolbar').select('.neat-array li').each(function(ele){
|
||||||
|
var sub = ele.select('ul');
|
||||||
|
if (sub.length > 0) {
|
||||||
|
ele.addClassName('collapsed').addClassName('expandable');
|
||||||
|
sub.invoke('hide');
|
||||||
|
ele.observe('click', function(eve){
|
||||||
|
if (eve.element() == ele || eve.element().up() == ele) {
|
||||||
|
if (sub.length > 0) {
|
||||||
|
ele.toggleClassName('expanded').toggleClassName('collapsed');
|
||||||
|
sub[0].toggle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
126
site/plugins/debug_kit/vendors/js/yui_debug_toolbar.js
vendored
Normal file
126
site/plugins/debug_kit/vendors/js/yui_debug_toolbar.js
vendored
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* Debug Toolbar Javascript. YUI 2.6 compatible.
|
||||||
|
*
|
||||||
|
* Long description here.
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||||
|
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* 1785 E. Sahara Avenue, Suite 490-204
|
||||||
|
* Las Vegas, Nevada 89104
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||||
|
* @package cake
|
||||||
|
* @subpackage cake.cake.libs.
|
||||||
|
* @since CakePHP v 1.2.0.4487
|
||||||
|
* @version $Revision$
|
||||||
|
* @modifiedby $LastChangedBy$
|
||||||
|
* @lastmodified $Date$
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
YAHOO.namespace('CakePHP.DebugKit');
|
||||||
|
|
||||||
|
YAHOO.CakePHP.DebugKit = function() {
|
||||||
|
|
||||||
|
var Event = YAHOO.util.Event;
|
||||||
|
var Dom = YAHOO.util.Dom;
|
||||||
|
var Selector = YAHOO.util.Selector;
|
||||||
|
|
||||||
|
|
||||||
|
var toggle = function(el) {
|
||||||
|
Dom.setStyle(el, 'display', ((Dom.getStyle(el, 'display') == 'none') ? '' : 'none'));
|
||||||
|
};
|
||||||
|
|
||||||
|
var toggleClass = function(element, className) {
|
||||||
|
(Dom.hasClass(element, className)) ? Dom.removeClass(element, className) : Dom.addClass(element, className);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var toolbar = function() {
|
||||||
|
var tabCollection = Selector.query('#debug-kit-toolbar li > div');
|
||||||
|
|
||||||
|
Dom.batch(Selector.query('#debug-kit-toolbar .panel-tab > a'), function(el) {
|
||||||
|
Event.on(el, 'click', function(ev) {
|
||||||
|
Event.preventDefault(ev);
|
||||||
|
targetPanel =Dom.get(el.hash.replace(/#/, '') + '-tab');
|
||||||
|
|
||||||
|
if (Dom.hasClass(targetPanel, 'active')) {
|
||||||
|
Dom.batch(tabCollection, function(ele) {
|
||||||
|
toggle(ele);
|
||||||
|
Dom.removeClass(ele, 'active');
|
||||||
|
Dom.setStyle(ele, 'display', '');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Dom.batch(tabCollection, function(ele) {
|
||||||
|
toggle(ele);
|
||||||
|
Dom.removeClass(ele, 'active');
|
||||||
|
|
||||||
|
if (targetPanel && targetPanel.id == ele.id) {
|
||||||
|
Dom.setStyle(ele, 'display', 'block');
|
||||||
|
Dom.addClass(ele, 'active');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Dom.removeClass(Selector.query('#debug-kit-toolbar .panel-tab > a'), 'active');
|
||||||
|
Dom.addClass(el, 'active');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var neatArray = function() {
|
||||||
|
nodes = Selector.query('#debug-kit-toolbar .panel-content > ul.neat-array li > ul');
|
||||||
|
|
||||||
|
if (nodes.length > 0) {
|
||||||
|
Dom.batch(nodes, function(el) {
|
||||||
|
|
||||||
|
var parent = el.parentNode;
|
||||||
|
|
||||||
|
Dom.addClass(parent, 'collapsed');
|
||||||
|
Dom.addClass(parent, 'expandable');
|
||||||
|
toggle(nodes);
|
||||||
|
|
||||||
|
Event.on(parent, 'click', function(ev) {
|
||||||
|
sub = Selector.query('ul', parent);
|
||||||
|
toggleClass(parent, 'expanded');
|
||||||
|
toggleClass(parent, 'collapsed');
|
||||||
|
toggle(sub);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var panelButtons = function() {
|
||||||
|
Event.on('hide-toolbar', 'click', function(ev) {
|
||||||
|
Event.preventDefault(ev);
|
||||||
|
|
||||||
|
Dom.getElementsByClassName('panel-tab', 'li', 'debug-kit-toolbar', function (el) {
|
||||||
|
if (!Dom.hasClass(el, 'icon')) {
|
||||||
|
toggle(el);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
initialize: function() {
|
||||||
|
neatArray();
|
||||||
|
toolbar();
|
||||||
|
panelButtons();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}(); // Execute annonymous closure & return results
|
||||||
|
|
||||||
|
YAHOO.util.Event.onDOMReady(YAHOO.CakePHP.DebugKit.initialize);
|
||||||
79
site/plugins/debug_kit/vendors/shells/benchmark.php
vendored
Normal file
79
site/plugins/debug_kit/vendors/shells/benchmark.php
vendored
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
<?php
|
||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* Benchmark Shell.
|
||||||
|
*
|
||||||
|
* Provides basic benchmarking of application requests
|
||||||
|
* functionally similar to Apache AB
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||||
|
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* 1785 E. Sahara Avenue, Suite 490-204
|
||||||
|
* Las Vegas, Nevada 89104
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||||
|
* @package cake
|
||||||
|
* @subpackage cake.debug_kit.vendors.shells
|
||||||
|
* @version $Revision$
|
||||||
|
* @modifiedby $LastChangedBy$
|
||||||
|
* @lastmodified $Date$
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
class BenchmarkShell extends Shell {
|
||||||
|
function main() {
|
||||||
|
$url = $this->args[0];
|
||||||
|
$this->out(sprintf('-> Testing %s', $url));
|
||||||
|
|
||||||
|
$n = 100;
|
||||||
|
$t = $i = 0;
|
||||||
|
if (isset($this->params['n'])) {
|
||||||
|
$n = $this->params['n'];
|
||||||
|
}
|
||||||
|
if (isset($this->params['t'])) {
|
||||||
|
$t = $this->params['t'];
|
||||||
|
}
|
||||||
|
$start = microtime(true);
|
||||||
|
while (true) {
|
||||||
|
if ($t && $t <= floor(microtime(true) - $start)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ($n <= $i) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
file_get_contents($url);
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
$duration = microtime(true) - $start;
|
||||||
|
$this->out('Total Requests made: ' . $i);
|
||||||
|
$this->out('Total Time elapsed: ' . $duration . '(s)');
|
||||||
|
$this->out(round($n / $duration, 2).' req/sec');
|
||||||
|
}
|
||||||
|
|
||||||
|
function help() {
|
||||||
|
$out = <<<EOL
|
||||||
|
DebugKit Benchmark Shell
|
||||||
|
|
||||||
|
Test a fully qualified url to get avg requests per second.
|
||||||
|
By default it does 100 requests to the provided url.
|
||||||
|
|
||||||
|
Use:
|
||||||
|
cake benchmark [params] [url]
|
||||||
|
|
||||||
|
Params
|
||||||
|
-n The maximum number of iterations to do.
|
||||||
|
|
||||||
|
-t The maximum time to take. If a single request takes more
|
||||||
|
than this time. Only one request will be made.
|
||||||
|
EOL;
|
||||||
|
$this->out($out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
154
site/plugins/debug_kit/views/debug.php
Normal file
154
site/plugins/debug_kit/views/debug.php
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
<?php
|
||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* Debug View
|
||||||
|
*
|
||||||
|
* Custom Debug View class, helps with development.
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||||
|
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* 1785 E. Sahara Avenue, Suite 490-204
|
||||||
|
* Las Vegas, Nevada 89104
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||||
|
* @package cake
|
||||||
|
* @subpackage cake.cake.libs.
|
||||||
|
* @since CakePHP v 1.2.0.4487
|
||||||
|
* @version $Revision$
|
||||||
|
* @modifiedby $LastChangedBy$
|
||||||
|
* @lastmodified $Date$
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
App::import('Vendor', 'DebugKit.DebugKitDebugger');
|
||||||
|
App::import('Component', 'DebugKit.Toolbar');
|
||||||
|
/**
|
||||||
|
* DebugView used by DebugKit
|
||||||
|
*
|
||||||
|
* @package debug_kit.views
|
||||||
|
* @todo Remove workarounds.
|
||||||
|
*/
|
||||||
|
class DebugView extends DoppelGangerView {
|
||||||
|
/**
|
||||||
|
* The old extension of the current template.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
var $_oldExtension = null;
|
||||||
|
/**
|
||||||
|
* Overload _render to capture filenames and time actual rendering of each view file
|
||||||
|
*
|
||||||
|
* @param string $___viewFn Filename of the view
|
||||||
|
* @param array $___dataForView Data to include in rendered view
|
||||||
|
* @return string Rendered output
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function _render($___viewFn, $___dataForView, $loadHelpers = true, $cached = false) {
|
||||||
|
/* pr(array('function' => 'DebugView::_render', */
|
||||||
|
/* 'args' => compact('__viewFn', '__dataForView', 'loadHelpers'), */
|
||||||
|
/* 'this-output-len' => strlen($this->output), */
|
||||||
|
/* )); */
|
||||||
|
if (isset($this->_oldExtension) && strstr($___viewFn, '.debug_view')) {
|
||||||
|
$___viewFn = substr($___viewFn, 0, -10) . $this->_oldExtension;
|
||||||
|
}
|
||||||
|
if (!isset($___dataForView['disableTimer'])) {
|
||||||
|
DebugKitDebugger::startTimer('render_' . basename($___viewFn), sprintf(__('Rendering %s', true), Debugger::trimPath($___viewFn)));
|
||||||
|
}
|
||||||
|
|
||||||
|
$out = parent::_render($___viewFn, $___dataForView, $loadHelpers, $cached);
|
||||||
|
|
||||||
|
if (!isset($___dataForView['disableTimer'])) {
|
||||||
|
DebugKitDebugger::stopTimer('render_' . basename($___viewFn));
|
||||||
|
}
|
||||||
|
/* pr(array('function' => 'DebugView::_render', */
|
||||||
|
/* 'out-len' => strlen($out), */
|
||||||
|
/* 'this-output-len' => strlen($this->output), */
|
||||||
|
/* 'return' => $out ? 'not-empty' : 'empty')); */
|
||||||
|
return $out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders view for given action and layout. If $file is given, that is used
|
||||||
|
* for a view filename (e.g. customFunkyView.ctp).
|
||||||
|
* Adds timers, for all subsequent rendering, and injects the debugKit toolbar.
|
||||||
|
*
|
||||||
|
* @param string $action Name of action to render for
|
||||||
|
* @param string $layout Layout to use
|
||||||
|
* @param string $file Custom filename for view
|
||||||
|
* @return string Rendered Element
|
||||||
|
*/
|
||||||
|
function render($action = null, $layout = null, $file = null) {
|
||||||
|
/* pr(array('function' => 'DebugView::render', */
|
||||||
|
/* 'args' => compact('action', 'layout', 'file'), */
|
||||||
|
/* 'this-output-len' => strlen($this->output), */
|
||||||
|
/* )); */
|
||||||
|
DebugKitDebugger::startTimer('viewRender', __('Rendering View', true));
|
||||||
|
$out = parent::render($action, $layout, $file);
|
||||||
|
/* pr(array('function' => 'DebugView::render', */
|
||||||
|
/* 'checkpoint' => 'parent::render', */
|
||||||
|
/* 'out' => $out ? 'not-empty' : 'empty')); */
|
||||||
|
DebugKitDebugger::stopTimer('viewRender');
|
||||||
|
DebugKitDebugger::stopTimer('controllerRender');
|
||||||
|
|
||||||
|
if (isset($this->loaded['toolbar'])) {
|
||||||
|
/* pr(array('function' => 'DebugView::render', */
|
||||||
|
/* 'checkpoint' => 'toolbarLoaded')); */
|
||||||
|
$this->loaded['toolbar']->postRender();
|
||||||
|
}
|
||||||
|
//Temporary work around to hide the SQL dump at page bottom
|
||||||
|
Configure::write('debug', 0);
|
||||||
|
/* pr(array('function' => 'DebugView::render', */
|
||||||
|
/* 'out-len' => strlen($out), */
|
||||||
|
/* 'this-output-len' => strlen($this->output), */
|
||||||
|
/* 'return' => $this->output ? 'not-empty' : 'empty')); */
|
||||||
|
return $this->output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Workaround _render() limitation in core. Which forces View::_render() for .ctp and .thtml templates
|
||||||
|
* Creates temporary extension to trick View::render() & View::renderLayout()
|
||||||
|
*
|
||||||
|
* @param string $name Action name.
|
||||||
|
* @return string
|
||||||
|
**/
|
||||||
|
function _getViewFileName($name = null) {
|
||||||
|
$filename = parent::_getViewFileName($name);
|
||||||
|
return $this->_replaceExtension($filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Workaround _render() limitation in core. Which forces View::_render() for .ctp and .thtml templates
|
||||||
|
* Creates temporary extension to trick View::render() & View::renderLayout()
|
||||||
|
*
|
||||||
|
* @param string $name Layout Name
|
||||||
|
* @return string
|
||||||
|
**/
|
||||||
|
function _getLayoutFileName($name = null) {
|
||||||
|
$filename = parent::_getLayoutFileName($name);
|
||||||
|
return $this->_replaceExtension($filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* replace the Extension on a filename and set the temporary workaround extension.
|
||||||
|
*
|
||||||
|
* @param string $filename Filename to replace extension for.
|
||||||
|
* @return string
|
||||||
|
**/
|
||||||
|
function _replaceExtension($filename) {
|
||||||
|
if (substr($filename, -3) == 'ctp') {
|
||||||
|
$this->_oldExtension = 'ctp';
|
||||||
|
$filename = substr($filename, 0, strlen($filename) -3) . 'debug_view';
|
||||||
|
} elseif (substr($filename, -5) == 'thtml') {
|
||||||
|
$this->_oldExtension = 'thtml';
|
||||||
|
$filename = substr($filename, 0, strlen($filename) -5) . 'debug_view';
|
||||||
|
}
|
||||||
|
return $filename;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
52
site/plugins/debug_kit/views/elements/debug_toolbar.ctp
Normal file
52
site/plugins/debug_kit/views/elements/debug_toolbar.ctp
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* Debug Toolbar Element
|
||||||
|
*
|
||||||
|
* Renders all of the other panel elements.
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||||
|
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* 1785 E. Sahara Avenue, Suite 490-204
|
||||||
|
* Las Vegas, Nevada 89104
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||||
|
* @package cake
|
||||||
|
* @subpackage cake.debug_kit.views.elements
|
||||||
|
* @since
|
||||||
|
* @version $Revision$
|
||||||
|
* @modifiedby $LastChangedBy$
|
||||||
|
* @lastmodified $Date$
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
?>
|
||||||
|
<div id="debug-kit-toolbar">
|
||||||
|
<?php if (empty($debugToolbarPanels)) :?>
|
||||||
|
<p class="warning"><?php __('There are no active panels. You must enable a panel to see its output.'); ?></p>
|
||||||
|
<?php else: ?>
|
||||||
|
<ul id="panel-tabs">
|
||||||
|
<li class="panel-tab icon">
|
||||||
|
<a href="#hide" id="hide-toolbar">
|
||||||
|
<?php echo $html->image('/debug_kit/img/cake.icon.png', array('alt' => 'cakePHP')); ?>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<?php foreach ($debugToolbarPanels as $panelName => $panelInfo): ?>
|
||||||
|
<li class="panel-tab">
|
||||||
|
<a href="#<?php echo Inflector::underscore($panelName); ?>">
|
||||||
|
<?php echo Inflector::humanize(Inflector::underscore($panelName)); ?>
|
||||||
|
</a>
|
||||||
|
<div class="panel-content" id="<?php echo Inflector::underscore($panelName); ?>-tab">
|
||||||
|
<?php echo $this->element($panelInfo['elementName'], $panelInfo); ?>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<?php endforeach ?>
|
||||||
|
</ul>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
0
site/plugins/debug_kit/views/elements/empty
Normal file
0
site/plugins/debug_kit/views/elements/empty
Normal file
48
site/plugins/debug_kit/views/elements/log_panel.ctp
Normal file
48
site/plugins/debug_kit/views/elements/log_panel.ctp
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* Log Panel Element
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||||
|
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* 1785 E. Sahara Avenue, Suite 490-204
|
||||||
|
* Las Vegas, Nevada 89104
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||||
|
* @package cake
|
||||||
|
* @subpackage cake.debug_kit.views.elements
|
||||||
|
* @version $Revision$
|
||||||
|
* @modifiedby $LastChangedBy$
|
||||||
|
* @lastmodified $Date$
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
?>
|
||||||
|
<h2><?php __('Logs') ?></h2>
|
||||||
|
<div class="code-table">
|
||||||
|
<?php foreach ($content as $logName => $logs): ?>
|
||||||
|
<h3><?php echo $logName ?></h3>
|
||||||
|
<?php
|
||||||
|
$len = count($logs);
|
||||||
|
if ($len > 0):
|
||||||
|
$headers = array(__('Time', true), __('Message', true));
|
||||||
|
$rows = array();
|
||||||
|
for ($i = 0; $i < $len; $i += 2):
|
||||||
|
$rows[] = array(
|
||||||
|
$logs[$i], $logs[$i + 1]
|
||||||
|
);
|
||||||
|
endfor;
|
||||||
|
echo $toolbar->table($rows, $headers, array('title' => $logName));
|
||||||
|
else: ?>
|
||||||
|
<p class="info"><?php __('There were no log entries made this request'); ?></p>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
43
site/plugins/debug_kit/views/elements/memory_panel.ctp
Normal file
43
site/plugins/debug_kit/views/elements/memory_panel.ctp
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* Session Panel Element
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||||
|
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* 1785 E. Sahara Avenue, Suite 490-204
|
||||||
|
* Las Vegas, Nevada 89104
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||||
|
* @package cake
|
||||||
|
* @subpackage cake.debug_kit.views.elements
|
||||||
|
* @since
|
||||||
|
* @version $Revision$
|
||||||
|
* @modifiedby $LastChangedBy$
|
||||||
|
* @lastmodified $Date$
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
?>
|
||||||
|
<h2><?php __('Memory'); ?></h2>
|
||||||
|
<div class="current-mem-use">
|
||||||
|
<?php echo $toolbar->message(
|
||||||
|
__('Current Memory Use',true),
|
||||||
|
$number->toReadableSize(DebugKitDebugger::getMemoryUse())
|
||||||
|
);?>
|
||||||
|
</div>
|
||||||
|
<div class="peak-mem-use">
|
||||||
|
<?php
|
||||||
|
echo $toolbar->message(
|
||||||
|
__('Peak Memory Use', true),
|
||||||
|
$number->toReadableSize(DebugKitDebugger::getPeakMemoryUse())
|
||||||
|
);
|
||||||
|
?></div>
|
||||||
45
site/plugins/debug_kit/views/elements/request_panel.ctp
Normal file
45
site/plugins/debug_kit/views/elements/request_panel.ctp
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* Request Panel Element
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||||
|
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* 1785 E. Sahara Avenue, Suite 490-204
|
||||||
|
* Las Vegas, Nevada 89104
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||||
|
* @package cake
|
||||||
|
* @subpackage cake.debug_kit.views.elements
|
||||||
|
* @since
|
||||||
|
* @version $Revision$
|
||||||
|
* @modifiedby $LastChangedBy$
|
||||||
|
* @lastmodified $Date$
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
?>
|
||||||
|
<h2> <?php __('Request'); ?></h2>
|
||||||
|
<h4>Cake Params</h4>
|
||||||
|
<?php echo $toolbar->makeNeatArray($content['params']); ?>
|
||||||
|
|
||||||
|
<h4>$_GET</h4>
|
||||||
|
<?php echo $toolbar->makeNeatArray($content['get']); ?>
|
||||||
|
|
||||||
|
<h4>Cookie</h4>
|
||||||
|
<?php if (isset($content['cookie'])): ?>
|
||||||
|
<?php echo $toolbar->makeNeatArray($content['cookie']); ?>
|
||||||
|
<?php else: ?>
|
||||||
|
<p class="warning">To view Cookies, add CookieComponent to Controller
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<h4><?php __('Current Route') ?></h4>
|
||||||
|
<?php echo $toolbar->makeNeatArray($content['currentRoute']); ?>
|
||||||
31
site/plugins/debug_kit/views/elements/session_panel.ctp
Normal file
31
site/plugins/debug_kit/views/elements/session_panel.ctp
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* Session Panel Element
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||||
|
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* 1785 E. Sahara Avenue, Suite 490-204
|
||||||
|
* Las Vegas, Nevada 89104
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||||
|
* @package cake
|
||||||
|
* @subpackage cake.debug_kit.views.elements
|
||||||
|
* @since
|
||||||
|
* @version $Revision$
|
||||||
|
* @modifiedby $LastChangedBy$
|
||||||
|
* @lastmodified $Date$
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
?>
|
||||||
|
<h2><?php __('Session'); ?></h2>
|
||||||
|
<?php echo $toolbar->makeNeatArray($content); ?>
|
||||||
40
site/plugins/debug_kit/views/elements/sql_log_panel.ctp
Normal file
40
site/plugins/debug_kit/views/elements/sql_log_panel.ctp
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* Session Panel Element
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||||
|
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* 1785 E. Sahara Avenue, Suite 490-204
|
||||||
|
* Las Vegas, Nevada 89104
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||||
|
* @package cake
|
||||||
|
* @subpackage cake.debug_kit.views.elements
|
||||||
|
* @since
|
||||||
|
* @version $Revision$
|
||||||
|
* @modifiedby $LastChangedBy$
|
||||||
|
* @lastmodified $Date$
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
?>
|
||||||
|
<h2><?php __('Sql Logs')?></h2>
|
||||||
|
<?php if (!empty($content)) : ?>
|
||||||
|
<?php foreach ($content as $dbName => $queryLog) : ?>
|
||||||
|
<div class="sql-log-panel-query-log">
|
||||||
|
<h4><?php echo $dbName ?></h4>
|
||||||
|
<?php echo $queryLog; ?>
|
||||||
|
</div>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<?php else: ?>
|
||||||
|
<p class="warning"><?php __('No active database connections'); ?>
|
||||||
|
<?php endif; ?>
|
||||||
44
site/plugins/debug_kit/views/elements/timer_panel.ctp
Normal file
44
site/plugins/debug_kit/views/elements/timer_panel.ctp
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* Timer Panel Element
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||||
|
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* 1785 E. Sahara Avenue, Suite 490-204
|
||||||
|
* Las Vegas, Nevada 89104
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||||
|
* @package cake
|
||||||
|
* @subpackage cake.debug_kit.views.elements
|
||||||
|
* @since
|
||||||
|
* @version $Revision$
|
||||||
|
* @modifiedby $LastChangedBy$
|
||||||
|
* @lastmodified $Date$
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
$timers = DebugKitDebugger::getTimers();
|
||||||
|
?>
|
||||||
|
<h2><?php __('Timers'); ?></h2>
|
||||||
|
<p class="request-time">
|
||||||
|
<?php $totalTime = sprintf(__('%s (seconds)', true), $number->precision(DebugKitDebugger::requestTime(), 6)); ?>
|
||||||
|
<?php echo $toolbar->message(__('Total Request Time:', true), $totalTime)?>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<?php foreach ($timers as $timerName => $timeInfo):
|
||||||
|
$rows[] = array(
|
||||||
|
$timeInfo['message'],
|
||||||
|
$number->precision($timeInfo['time'], 6)
|
||||||
|
);
|
||||||
|
$headers = array(__('Message', true), __('time in seconds', true));
|
||||||
|
endforeach;
|
||||||
|
echo $toolbar->table($rows, $headers, array('title' => 'Timers')); ?>
|
||||||
35
site/plugins/debug_kit/views/elements/variables_panel.ctp
Normal file
35
site/plugins/debug_kit/views/elements/variables_panel.ctp
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* View Variables Panel Element
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||||
|
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* 1785 E. Sahara Avenue, Suite 490-204
|
||||||
|
* Las Vegas, Nevada 89104
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||||
|
* @package cake
|
||||||
|
* @subpackage cake.debug_kit.views.elements
|
||||||
|
* @since
|
||||||
|
* @version $Revision$
|
||||||
|
* @modifiedby $LastChangedBy$
|
||||||
|
* @lastmodified $Date$
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
?>
|
||||||
|
<h2> <?php __('View Variables'); ?></h2>
|
||||||
|
<?php
|
||||||
|
$vars = $this->viewVars;
|
||||||
|
unset($vars['debugToolbarPanels'], $vars['debugToolbarJavascript']);
|
||||||
|
?>
|
||||||
|
<?php echo $toolbar->makeNeatArray($vars); ?>
|
||||||
79
site/plugins/debug_kit/views/helpers/fire_php_toolbar.php
Normal file
79
site/plugins/debug_kit/views/helpers/fire_php_toolbar.php
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
<?php
|
||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* FirePHP Toolbar Helper
|
||||||
|
*
|
||||||
|
* Injects the toolbar elements into non-HTML layouts via FireCake.
|
||||||
|
*
|
||||||
|
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||||
|
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* 1785 E. Sahara Avenue, Suite 490-204
|
||||||
|
* Las Vegas, Nevada 89104
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||||
|
* @package debug_kit
|
||||||
|
* @subpackage debug_kit.views.helpers
|
||||||
|
* @version $Revision$
|
||||||
|
* @modifiedby $LastChangedBy$
|
||||||
|
* @lastmodified $Date$
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
App::import('helper', 'DebugKit.Toolbar');
|
||||||
|
App::import('Vendor', 'DebugKit.FireCake');
|
||||||
|
|
||||||
|
class FirePhpToolbarHelper extends ToolbarHelper {
|
||||||
|
/**
|
||||||
|
* send method
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function _send() {
|
||||||
|
$view =& ClassRegistry::getObject('view');
|
||||||
|
$view->element('debug_toolbar', array('plugin' => 'debug_kit', 'disableTimer' => true));
|
||||||
|
Configure::write('debug', 1);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* makeNeatArray.
|
||||||
|
*
|
||||||
|
* wraps FireCake::dump() allowing panel elements to continue functioning
|
||||||
|
*
|
||||||
|
* @param string $values
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function makeNeatArray($values) {
|
||||||
|
FireCake::info($values);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Create a simple message
|
||||||
|
*
|
||||||
|
* @param string $label Label of message
|
||||||
|
* @param string $message Message content
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function message($label, $message) {
|
||||||
|
FireCake::log($message, $label);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Generate a table with FireCake
|
||||||
|
*
|
||||||
|
* @param array $rows Rows to print
|
||||||
|
* @param array $headers Headers for table
|
||||||
|
* @param array $options Additional options and params
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function table($rows, $headers, $options = array()) {
|
||||||
|
$title = $headers[0];
|
||||||
|
if (isset($options['title'])) {
|
||||||
|
$title = $options['title'];
|
||||||
|
}
|
||||||
|
array_unshift($rows, $headers);
|
||||||
|
FireCake::table($title, $rows);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
150
site/plugins/debug_kit/views/helpers/html_toolbar.php
Normal file
150
site/plugins/debug_kit/views/helpers/html_toolbar.php
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
<?php
|
||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* Html Toolbar Helper
|
||||||
|
*
|
||||||
|
* Injects the toolbar elements into HTML layouts.
|
||||||
|
* Contains helper methods for
|
||||||
|
*
|
||||||
|
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||||
|
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* 1785 E. Sahara Avenue, Suite 490-204
|
||||||
|
* Las Vegas, Nevada 89104
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||||
|
* @package debug_kit
|
||||||
|
* @subpackage debug_kit.views.helpers
|
||||||
|
* @version $Revision$
|
||||||
|
* @modifiedby $LastChangedBy$
|
||||||
|
* @lastmodified $Date$
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
App::import('helper', 'DebugKit.Toolbar');
|
||||||
|
|
||||||
|
class HtmlToolbarHelper extends ToolbarHelper {
|
||||||
|
/**
|
||||||
|
* helpers property
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
var $helpers = array('Html', 'Javascript');
|
||||||
|
/**
|
||||||
|
* settings property
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
var $settings = array('format' => 'html');
|
||||||
|
/**
|
||||||
|
* Recursively goes through an array and makes neat HTML out of it.
|
||||||
|
*
|
||||||
|
* @param mixed $values Array to make pretty.
|
||||||
|
* @param int $openDepth Depth to add open class
|
||||||
|
* @param int $currentDepth current depth.
|
||||||
|
* @return string
|
||||||
|
**/
|
||||||
|
function makeNeatArray($values, $openDepth = 0, $currentDepth = 0) {
|
||||||
|
$className ="neat-array depth-$currentDepth";
|
||||||
|
if ($openDepth > $currentDepth) {
|
||||||
|
$className .= ' expanded';
|
||||||
|
}
|
||||||
|
$nextDepth = $currentDepth + 1;
|
||||||
|
$out = "<ul class=\"$className\">";
|
||||||
|
if (!is_array($values)) {
|
||||||
|
if (is_bool($values)) {
|
||||||
|
$values = array($values);
|
||||||
|
}
|
||||||
|
if (is_null($values)) {
|
||||||
|
$values = array(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($values as $key => $value) {
|
||||||
|
$out .= '<li><strong>' . $key . '</strong>';
|
||||||
|
if ($value === null) {
|
||||||
|
$value = '(null)';
|
||||||
|
}
|
||||||
|
if ($value === false) {
|
||||||
|
$value = '(false)';
|
||||||
|
}
|
||||||
|
if ($value === true) {
|
||||||
|
$value = '(true)';
|
||||||
|
}
|
||||||
|
if (empty($value) && $value != 0) {
|
||||||
|
$value = '(empty)';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_object($value)) {
|
||||||
|
$value = Set::reverse($value, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($value) && !empty($value)) {
|
||||||
|
$out .= $this->makeNeatArray($value, $openDepth, $nextDepth);
|
||||||
|
} else {
|
||||||
|
$out .= $value;
|
||||||
|
}
|
||||||
|
$out .= '</li>';
|
||||||
|
}
|
||||||
|
$out .= '</ul>';
|
||||||
|
return $out;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Create an HTML message
|
||||||
|
*
|
||||||
|
* @param string $label label content
|
||||||
|
* @param string $message message content
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function message($label, $message) {
|
||||||
|
return sprintf('<p><strong>%s</strong> %s</p>', $label, $message);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Create a table.
|
||||||
|
*
|
||||||
|
* @param array $rows Rows to make.
|
||||||
|
* @param array $headers Optional header row.
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function table($rows, $headers = array()) {
|
||||||
|
$out = '<table class="debug-table">';
|
||||||
|
if (!empty($headers)) {
|
||||||
|
$out .= $this->Html->tableHeaders($headers);
|
||||||
|
}
|
||||||
|
$out .= $this->Html->tableCells($rows, array('class' => 'odd'), array('class' => 'even'));
|
||||||
|
$out .= '</table>';
|
||||||
|
return $out;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* send method
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function _send() {
|
||||||
|
if (Configure::read('debug') == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$view =& ClassRegistry::getObject('view');
|
||||||
|
$head = $this->Html->css('/debug_kit/css/debug_toolbar');
|
||||||
|
if (isset($view->viewVars['debugToolbarJavascript'])) {
|
||||||
|
foreach ($view->viewVars['debugToolbarJavascript'] as $script) {
|
||||||
|
if ($script) {
|
||||||
|
$head .= $this->Javascript->link($script);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (preg_match('#</head>#', $view->output)) {
|
||||||
|
$view->output = preg_replace('#</head>#', $head . "\n</head>", $view->output, 1);
|
||||||
|
}
|
||||||
|
$toolbar = $view->element('debug_toolbar', array('plugin' => 'debug_kit', 'disableTimer' => true));
|
||||||
|
if (preg_match('#</body>#', $view->output)) {
|
||||||
|
$view->output = preg_replace('#</body>#', $toolbar . "\n</body>", $view->output, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
90
site/plugins/debug_kit/views/helpers/toolbar.php
Normal file
90
site/plugins/debug_kit/views/helpers/toolbar.php
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
<?php
|
||||||
|
/* SVN FILE: $Id$ */
|
||||||
|
/**
|
||||||
|
* Abstract Toolbar helper. Provides Base methods for content
|
||||||
|
* specific debug toolbar helpers. Acts as a facade for other toolbars helpers as well.
|
||||||
|
*
|
||||||
|
* helps with development.
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||||
|
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||||
|
* @package debug_kit
|
||||||
|
* @subpackage debug_kit.views.helpers
|
||||||
|
* @since v 1.0
|
||||||
|
* @version $Revision$
|
||||||
|
* @modifiedby $LastChangedBy$
|
||||||
|
* @lastmodified $Date$
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
App::import('Vendor', 'DebugKit.DebugKitDebugger');
|
||||||
|
|
||||||
|
class ToolbarHelper extends AppHelper {
|
||||||
|
/**
|
||||||
|
* settings property to be overloaded. Subclasses should specify a format
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
var $settings = array();
|
||||||
|
/**
|
||||||
|
* Construct the helper and make the backend helper.
|
||||||
|
*
|
||||||
|
* @param string $options
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function __construct($options = array()) {
|
||||||
|
$this->_myName = strtolower(get_class($this));
|
||||||
|
if ($this->_myName !== 'toolbarhelper') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!isset($options['output'])) {
|
||||||
|
$options['output'] = 'DebugKit.HtmlToolbar';
|
||||||
|
}
|
||||||
|
App::import('Helper', $options['output']);
|
||||||
|
$className = $options['output'];
|
||||||
|
if (strpos($options['output'], '.') !== false) {
|
||||||
|
list($plugin, $className) = explode('.', $options['output']);
|
||||||
|
}
|
||||||
|
$this->_backEndClassName = $className;
|
||||||
|
$this->helpers = array($options['output']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* call__
|
||||||
|
*
|
||||||
|
* Allows method calls on backend helper
|
||||||
|
*
|
||||||
|
* @param string $method
|
||||||
|
* @param mixed $params
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function call__($method, $params) {
|
||||||
|
if (method_exists($this->{$this->_backEndClassName}, $method)) {
|
||||||
|
return $this->{$this->_backEndClassName}->dispatchMethod($method, $params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* postRender method
|
||||||
|
*
|
||||||
|
* Custom Callback defined in DebugView to allow helpers to modify
|
||||||
|
* View output after all rendering is complete.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function postRender() {
|
||||||
|
$this->_send();
|
||||||
|
}
|
||||||
|
}
|
||||||
204
site/views/accounts/collected.ctp
Normal file
204
site/views/accounts/collected.ctp
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
<?php /* -*- mode:PHP -*- */
|
||||||
|
|
||||||
|
echo '<div class="account collected">' . "\n";
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
* Javascript
|
||||||
|
*/
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<script type="text/javascript"><!--
|
||||||
|
|
||||||
|
// Reset the form
|
||||||
|
function resetForm() {
|
||||||
|
/* updateEntriesGrid(); */
|
||||||
|
}
|
||||||
|
|
||||||
|
function onGridLoadComplete() {
|
||||||
|
var userdata = $('#collected-entries-jqGrid').getGridParam('userData');
|
||||||
|
$('#collected-total').html(fmtCurrency(userdata['total']));
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateEntriesGrid() {
|
||||||
|
var cust = new Array();
|
||||||
|
|
||||||
|
var account_ids = new Array();
|
||||||
|
$("INPUT[type='checkbox']:checked").each(function(i) {
|
||||||
|
account_ids.push($(this).val());
|
||||||
|
});
|
||||||
|
|
||||||
|
cust['collected_account_id'] = <?php echo $account['id']; ?>;
|
||||||
|
cust['collected_from_date'] = $('#TxFromDate').val();
|
||||||
|
cust['collected_through_date'] = $('#TxThroughDate').val();
|
||||||
|
cust['collected_payment_accounts'] = account_ids;
|
||||||
|
|
||||||
|
$('#collected-total').html('Calculating...');
|
||||||
|
$('#collected-entries-jqGrid').clearGridData();
|
||||||
|
$('#collected-entries-jqGrid').setPostDataItem('custom', serialize(cust));
|
||||||
|
$('#collected-entries-jqGrid')
|
||||||
|
.setGridParam({ page: 1 })
|
||||||
|
.trigger("reloadGrid");
|
||||||
|
|
||||||
|
//$('#collected-entries .HeaderButton').click();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
--></script>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
* Summary Info Box
|
||||||
|
*/
|
||||||
|
|
||||||
|
echo '<div class="infobox">' . "\n";
|
||||||
|
|
||||||
|
$rows = array();
|
||||||
|
$rows[] = array('Total:', '<SPAN id="collected-total"></SPAN>');
|
||||||
|
echo $this->element('table',
|
||||||
|
array('class' => 'summary',
|
||||||
|
'rows' => $rows,
|
||||||
|
'column_class' => array('field', 'value'),
|
||||||
|
'suppress_alternate_rows' => true,
|
||||||
|
));
|
||||||
|
echo '</div>' . "\n";
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
* User Configuration
|
||||||
|
*/
|
||||||
|
|
||||||
|
echo $form->create(null, array('id' => 'collected-form',
|
||||||
|
'onsubmit' => 'return false',
|
||||||
|
'url' => null));
|
||||||
|
|
||||||
|
echo $form->input("id",
|
||||||
|
array('id' => 'account-id',
|
||||||
|
'type' => 'hidden',
|
||||||
|
'value' => 0));
|
||||||
|
|
||||||
|
/* echo '<fieldset class="account collected entry">'; */
|
||||||
|
/* echo ' <legend>Payment Account</legend>'; */
|
||||||
|
/* echo $form->input('Tx.account_id', */
|
||||||
|
/* array(//'label' => 'Payment<BR>Account', */
|
||||||
|
/* 'label' => false, */
|
||||||
|
/* 'type' => 'select', */
|
||||||
|
/* 'multiple' => 'checkbox', */
|
||||||
|
/* 'options' => $paymentAccounts, */
|
||||||
|
/* 'selected' => array_keys($defaultAccounts), */
|
||||||
|
/* ) */
|
||||||
|
/* ); */
|
||||||
|
/* echo '</fieldset>'; */
|
||||||
|
|
||||||
|
echo $this->element('form_table',
|
||||||
|
array('class' => "item account collected entry",
|
||||||
|
//'with_name_after' => ':',
|
||||||
|
'field_prefix' => 'Tx.',
|
||||||
|
'fields' => array
|
||||||
|
("account_id" => array('name' => 'Payment<BR>Account',
|
||||||
|
'opts' =>
|
||||||
|
array('type' => 'select',
|
||||||
|
'multiple' => 'checkbox',
|
||||||
|
'options' => $paymentAccounts,
|
||||||
|
'selected' => array_keys($defaultAccounts),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
echo $this->element('form_table',
|
||||||
|
array('class' => "item account collected entry",
|
||||||
|
//'with_name_after' => ':',
|
||||||
|
'field_prefix' => 'Tx.',
|
||||||
|
'fields' => array
|
||||||
|
("from_date" => array('opts' =>
|
||||||
|
array('type' => 'text'),
|
||||||
|
'between' => '<A HREF="#" ONCLICK="datepickerBOM(null,\'TxFromDate\'); return false;">BOM</A>',
|
||||||
|
),
|
||||||
|
"through_date" => array('opts' =>
|
||||||
|
array('type' => 'text'),
|
||||||
|
'between' => '<A HREF="#" ONCLICK="datepickerEOM(\'TxFromDate\',\'TxThroughDate\'); return false;">EOM</A>',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
echo $form->button('Update',
|
||||||
|
array('onclick' => 'updateEntriesGrid(); return false',
|
||||||
|
));
|
||||||
|
|
||||||
|
echo $form->end();
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
* Supporting Elements Section
|
||||||
|
*/
|
||||||
|
|
||||||
|
echo '<div CLASS="detail supporting">' . "\n";
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* Entries
|
||||||
|
*/
|
||||||
|
|
||||||
|
echo $this->element('ledger_entries', array
|
||||||
|
(// Element configuration
|
||||||
|
'collected_account_id' => $account['id'],
|
||||||
|
|
||||||
|
// Grid configuration
|
||||||
|
'config' => array
|
||||||
|
(
|
||||||
|
'grid_div_id' => 'collected-entries',
|
||||||
|
'grid_div_class' => 'text-below',
|
||||||
|
'grid_events' => array('loadComplete' => 'onGridLoadComplete()'),
|
||||||
|
//'grid_setup' => array('hiddengrid' => true),
|
||||||
|
//'caption' => '<SPAN id="receipt-charges-caption"></SPAN>',
|
||||||
|
'caption' => 'Collected ' . Inflector::pluralize($account['name'])
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<script type="text/javascript"><!--
|
||||||
|
$(document).ready(function(){
|
||||||
|
$("#TxFromDate")
|
||||||
|
.attr('autocomplete', 'off')
|
||||||
|
.datepicker({ constrainInput: true,
|
||||||
|
numberOfMonths: [1, 1],
|
||||||
|
showCurrentAtPos: 0,
|
||||||
|
dateFormat: 'mm/dd/yy' });
|
||||||
|
|
||||||
|
$("#TxThroughDate")
|
||||||
|
.attr('autocomplete', 'off')
|
||||||
|
.datepicker({ constrainInput: true,
|
||||||
|
numberOfMonths: [1, 1],
|
||||||
|
showCurrentAtPos: 0,
|
||||||
|
dateFormat: 'mm/dd/yy' });
|
||||||
|
|
||||||
|
resetForm();
|
||||||
|
});
|
||||||
|
--></script>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/* End "detail supporting" div */
|
||||||
|
echo '</div>' . "\n";
|
||||||
|
|
||||||
|
/* End page div */
|
||||||
|
echo '</div>' . "\n";
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<a href="#" onClick="$('#debug').html(''); return false;">Clear Debug Output</a>
|
||||||
74
site/views/accounts/deposit.ctp
Normal file
74
site/views/accounts/deposit.ctp
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
<?php /* -*- mode:PHP -*- */
|
||||||
|
|
||||||
|
echo '<div class="account deposit">' . "\n";
|
||||||
|
echo '<H2>Perform Bank Deposit</H2>' . "\n";
|
||||||
|
echo '<P>Make sure to select the checkboxes below for only those types of currency (Cash, Check, etc) which you intend to actually deposit (you can see all the individual items by dropping down the list below the checkbox). Then, select the Deposit Account where you will make the deposit, and click "Perform Deposit" to close the books on the selected currency types and reset them to a zero balance. On the next page, you will be provided with a deposit slip to prepare the actual deposit.' . "\n";
|
||||||
|
echo '<P><BR>' . "\n";
|
||||||
|
|
||||||
|
//pr(compact('tillableAccount', 'depositableAccount'));
|
||||||
|
|
||||||
|
echo $form->create(null, array('id' => 'deposit-form',
|
||||||
|
'url' => array('controller' => 'accounts',
|
||||||
|
'action' => 'deposit')));
|
||||||
|
|
||||||
|
foreach ($tillableAccount AS $acct) {
|
||||||
|
//$acct = $acct['Account'];
|
||||||
|
|
||||||
|
echo "\n";
|
||||||
|
echo $form->input('Tillable.Ledger.'.$acct['CurrentLedger']['id'].'.checked',
|
||||||
|
array(//'label' => $acct['Account']['name'],
|
||||||
|
'type' => 'checkbox',
|
||||||
|
'checked' => true,
|
||||||
|
'value' => true,
|
||||||
|
'label' => (" I have exactly " .
|
||||||
|
FormatHelper::currency($acct['Account']['stats']['Ledger']['balance']) .
|
||||||
|
" in " . ($acct['Account']['name'] === 'Cash'
|
||||||
|
? 'Cash'
|
||||||
|
: Inflector::pluralize($acct['Account']['name'])) .
|
||||||
|
" and will be depositing it all.")
|
||||||
|
));
|
||||||
|
echo "\n";
|
||||||
|
echo $form->input('Tillable.Ledger.'.$acct['CurrentLedger']['id'].'.amount',
|
||||||
|
array('type' => 'hidden',
|
||||||
|
'value' => $acct['Account']['stats']['Ledger']['balance'],
|
||||||
|
));
|
||||||
|
echo "\n";
|
||||||
|
echo $form->input('Tillable.Ledger.'.$acct['CurrentLedger']['id'].'.account_id',
|
||||||
|
array('type' => 'hidden',
|
||||||
|
'value' => $acct['Account']['id'],
|
||||||
|
));
|
||||||
|
echo "\n";
|
||||||
|
echo $form->input('Tillable.Ledger.'.$acct['CurrentLedger']['id'].'.account_name',
|
||||||
|
array('type' => 'hidden',
|
||||||
|
'value' => $acct['Account']['name'],
|
||||||
|
));
|
||||||
|
echo "\n";
|
||||||
|
|
||||||
|
$grid_div_id = 'ledger_entries'.$acct['CurrentLedger']['id'].'-list';
|
||||||
|
echo $this->element('ledger_entries', array
|
||||||
|
(// Element configuration
|
||||||
|
'ledger_id' => $acct['CurrentLedger']['id'],
|
||||||
|
'no_account' => true,
|
||||||
|
|
||||||
|
// Grid configuration
|
||||||
|
'config' => array
|
||||||
|
(
|
||||||
|
'grid_div_id' => $grid_div_id,
|
||||||
|
'caption' => ('<A HREF="#" ONCLICK="$(\'#'.$grid_div_id.' .HeaderButton\').click();'.
|
||||||
|
' return false;">Items in '.$acct['Account']['name'].' Ledger</A>'),
|
||||||
|
'grid_setup' => array('hiddengrid' => true),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
$options = array();
|
||||||
|
foreach ($depositableAccount AS $acct) {
|
||||||
|
$options[$acct['Account']['id']] = $acct['Account']['name'];
|
||||||
|
}
|
||||||
|
|
||||||
|
echo $form->input('Deposit.Account.id', array('label' => 'Deposit Account ',
|
||||||
|
'options' => $options));
|
||||||
|
echo $form->end('Perform Deposit');
|
||||||
|
|
||||||
|
/* End page div */
|
||||||
|
echo '</div>' . "\n";
|
||||||
53
site/views/accounts/deposit_slip.ctp
Normal file
53
site/views/accounts/deposit_slip.ctp
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<?php /* -*- mode:PHP -*- */
|
||||||
|
|
||||||
|
echo '<H2>Deposit Slip: ' . date('l, F jS, Y, g:ia') . '</H2>' . "\n";
|
||||||
|
|
||||||
|
//pr(compact('deposit'));
|
||||||
|
|
||||||
|
// Handle account summaries
|
||||||
|
$rows = array();
|
||||||
|
$row_class = array();
|
||||||
|
foreach ($deposit['ledgers'] AS $ledger) {
|
||||||
|
$row_class[] = array();
|
||||||
|
$rows[] = array($ledger['name'].':',
|
||||||
|
FormatHelper::_n(count($ledger['entries']), 'Item'),
|
||||||
|
FormatHelper::currency($ledger['total'], true));
|
||||||
|
}
|
||||||
|
$row_class[] = 'grand';
|
||||||
|
$rows[] = array('Deposit Total:',
|
||||||
|
null,
|
||||||
|
FormatHelper::currency($deposit['total'], true));
|
||||||
|
echo $this->element('table',
|
||||||
|
array('class' => 'deposit-summary',
|
||||||
|
'rows' => $rows,
|
||||||
|
'row_class' => $row_class,
|
||||||
|
'column_class' => array('account', 'quantity', 'total'),
|
||||||
|
'suppress_alternate_rows' => true,
|
||||||
|
));
|
||||||
|
|
||||||
|
|
||||||
|
// Print out the items of each ledger
|
||||||
|
foreach ($deposit['ledgers'] AS $ledger) {
|
||||||
|
//echo ('Count: ' . count($ledger['entries']) . '<BR>');
|
||||||
|
//pr($ledger['entries']);
|
||||||
|
if (count($ledger['entries']) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
$rows = array();
|
||||||
|
foreach ($ledger['entries'] AS $entry) {
|
||||||
|
$rows[] = array($entry['Customer']['name'],
|
||||||
|
$entry['MonetarySource']['name'],
|
||||||
|
$entry['LedgerEntry']['amount']);
|
||||||
|
}
|
||||||
|
|
||||||
|
echo $this->element('table',
|
||||||
|
array('class' => 'item deposit-slip list',
|
||||||
|
'caption' => $ledger['name'] . ' Items',
|
||||||
|
'rows' => $rows,
|
||||||
|
'headers' => array('Customer', 'Item', 'Amount'),
|
||||||
|
'column_class' => array('customer', 'item', 'amount'),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* End page div */
|
||||||
|
//echo '</div>' . "\n";
|
||||||
90
site/views/accounts/view.ctp
Normal file
90
site/views/accounts/view.ctp
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
<?php /* -*- mode:PHP -*- */
|
||||||
|
|
||||||
|
echo '<div class="account view">' . "\n";
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
* Account Detail Main Section
|
||||||
|
*/
|
||||||
|
|
||||||
|
$rows = array(array('ID', $account['Account']['id']),
|
||||||
|
array('Name', $account['Account']['name']),
|
||||||
|
array('Type', $account['Account']['type']),
|
||||||
|
array('External Name', $account['Account']['external_name']),
|
||||||
|
array('External Account', $account['Account']['external_account']),
|
||||||
|
array('Comment', $account['Account']['comment']));
|
||||||
|
|
||||||
|
echo $this->element('table',
|
||||||
|
array('class' => 'item account detail',
|
||||||
|
'caption' => 'Account Detail',
|
||||||
|
'rows' => $rows,
|
||||||
|
'column_class' => array('field', 'value')));
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* Account Info Box
|
||||||
|
*/
|
||||||
|
|
||||||
|
echo '<div class="infobox">' . "\n";
|
||||||
|
$rows = array();
|
||||||
|
$rows[] = array('Debits:', FormatHelper::currency($stats['debits']));
|
||||||
|
$rows[] = array('Credits:', FormatHelper::currency($stats['credits']));
|
||||||
|
$rows[] = array('Account Balance:', FormatHelper::currency($stats['balance']));
|
||||||
|
echo $this->element('table',
|
||||||
|
array('class' => 'summary',
|
||||||
|
'rows' => $rows,
|
||||||
|
'column_class' => array('field', 'value'),
|
||||||
|
'suppress_alternate_rows' => true,
|
||||||
|
));
|
||||||
|
echo '</div>' . "\n";
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
* Supporting Elements Section
|
||||||
|
*/
|
||||||
|
|
||||||
|
echo '<div CLASS="detail supporting">' . "\n";
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* Ledgers
|
||||||
|
*/
|
||||||
|
|
||||||
|
echo $this->element('ledgers', array
|
||||||
|
('config' => array
|
||||||
|
('caption' => $account['Account']['name'] . " Ledgers",
|
||||||
|
'rows' => $account['Ledger'],
|
||||||
|
)));
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* Current Ledger
|
||||||
|
*/
|
||||||
|
|
||||||
|
echo $this->element('ledger_entries', array
|
||||||
|
(// Element configuration
|
||||||
|
'ledger_id' => $account['CurrentLedger']['id'],
|
||||||
|
'account_type' => $account['Account']['type'],
|
||||||
|
'group_by_tx' => true,
|
||||||
|
|
||||||
|
// Grid configuration
|
||||||
|
'config' => array
|
||||||
|
('caption' =>
|
||||||
|
"Current Ledger: (" .
|
||||||
|
"#{$account['Account']['id']}" .
|
||||||
|
"-" .
|
||||||
|
"{$account['CurrentLedger']['sequence']}" .
|
||||||
|
")",
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
/* End "detail supporting" div */
|
||||||
|
echo '</div>' . "\n";
|
||||||
|
|
||||||
|
/* End page div */
|
||||||
|
echo '</div>' . "\n";
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
<div class="charges index">
|
|
||||||
<?php echo $this->element('charges', array('heading' => '<h2>'.$heading.'</h2>')) ?>
|
|
||||||
</div>
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
<?php /* -*- mode:PHP -*- */ ?>
|
|
||||||
|
|
||||||
<div class="charges view">
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
function currency($number) {
|
|
||||||
if ($number < 0)
|
|
||||||
return "($ " . number_format(-1*$number, 2) . ")";
|
|
||||||
else
|
|
||||||
return "$ " . number_format($number, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
function datefmt($date) {
|
|
||||||
$date_fmt = 'm/d/Y';
|
|
||||||
return ($date
|
|
||||||
? date_format(date_create($date), $date_fmt)
|
|
||||||
: null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************
|
|
||||||
* Charge Info
|
|
||||||
*/
|
|
||||||
|
|
||||||
$rows = array(array('ID', $charge['Charge']['id']),
|
|
||||||
array('Date', datefmt($charge['Charge']['charge_date'])),
|
|
||||||
array('Through', datefmt($charge['Charge']['charge_to_date'])),
|
|
||||||
array('Due', datefmt($charge['Charge']['due_date'])),
|
|
||||||
array('Type', $charge['ChargeType']['name']),
|
|
||||||
array('Lease', '#'.$charge['Lease']['number']),
|
|
||||||
array('Amount', currency($charge['Charge']['amount'])),
|
|
||||||
array('Tax', currency($charge['Charge']['tax'])),
|
|
||||||
array('Total', currency($charge['Charge']['total'])),
|
|
||||||
array('Comment', $charge['Charge']['comment']));
|
|
||||||
|
|
||||||
echo $this->element('table',
|
|
||||||
array('class' => 'item charge detail',
|
|
||||||
'caption' => 'Charge Info',
|
|
||||||
'rows' => $rows,
|
|
||||||
'column_class' => array('field', 'value')));
|
|
||||||
|
|
||||||
|
|
||||||
?>
|
|
||||||
<DIV CLASS="infobox charge">
|
|
||||||
<DIV CLASS="summary grand payment">
|
|
||||||
Amount Received: <?php echo currency($paymentAmount); ?>
|
|
||||||
</DIV>
|
|
||||||
<DIV CLASS="summary grand balance">
|
|
||||||
Amount Owing: <?php echo currency($balanceAmount); ?>
|
|
||||||
</DIV>
|
|
||||||
</DIV>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
|
||||||
* Receipts
|
|
||||||
*/
|
|
||||||
|
|
||||||
$headers = array('ID', 'Timestamp', 'Comment', 'Applied', 'Balance');
|
|
||||||
$rows = array();
|
|
||||||
$running_total = $charge['Charge']['total'];
|
|
||||||
foreach($charge['Receipt'] AS $receipt) {
|
|
||||||
$amount = $receipt['ChargesReceipt']['amount'];
|
|
||||||
$running_total -= $amount;
|
|
||||||
$rows[] = array($html->link('#'.$receipt['id'],
|
|
||||||
array('controller' => 'receipts',
|
|
||||||
'action' => 'view',
|
|
||||||
$receipt['id'])),
|
|
||||||
datefmt($receipt['stamp']),
|
|
||||||
$receipt['comment'],
|
|
||||||
currency($receipt['ChargesReceipt']['amount']),
|
|
||||||
currency($running_total)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
echo $this->element('table',
|
|
||||||
array('class' => 'item receipt list',
|
|
||||||
'caption' => 'Receipts towards Charge',
|
|
||||||
'headers' => $headers,
|
|
||||||
'rows' => $rows,
|
|
||||||
'column_class' => $headers));
|
|
||||||
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
403
site/views/contacts/edit.ctp
Normal file
403
site/views/contacts/edit.ctp
Normal file
@@ -0,0 +1,403 @@
|
|||||||
|
<?php /* -*- mode:PHP -*- */
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* Because we make use of functions here,
|
||||||
|
* we need to put our top level variables somewhere
|
||||||
|
* we can access them.
|
||||||
|
*/
|
||||||
|
$this->varstore = compact('methodTypes', 'methodPreferences',
|
||||||
|
'contactPhones', 'phoneTypes',
|
||||||
|
'contactAddresses',
|
||||||
|
'contactEmails');
|
||||||
|
|
||||||
|
//pr($this->data);
|
||||||
|
/**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
* Javascript
|
||||||
|
*/
|
||||||
|
|
||||||
|
function contactMethodDiv($obj, $type, $legend, $values = null) {
|
||||||
|
|
||||||
|
$div =
|
||||||
|
// BEGIN type-div
|
||||||
|
'<DIV>' . "\n" .
|
||||||
|
// BEGIN type-fieldset
|
||||||
|
'<FIELDSET CLASS="'.$type.' subset">' . "\n" .
|
||||||
|
'<LEGEND>'.$legend.' #%{id} (%{remove})</LEGEND>' . "\n" .
|
||||||
|
|
||||||
|
// BEGIN source-div
|
||||||
|
'<DIV ID="'.$type.'-%{id}-source-div">' . "\n" .
|
||||||
|
// BEGIN source-fieldset
|
||||||
|
'<FIELDSET>' . "\n" .
|
||||||
|
//'<LEGEND>Source</LEGEND>' . "\n" .
|
||||||
|
''
|
||||||
|
;
|
||||||
|
|
||||||
|
if (!isset($values)) {
|
||||||
|
foreach (array('Existing', 'New') AS $sname) {
|
||||||
|
$stype = strtolower($sname);
|
||||||
|
$div .=
|
||||||
|
'<INPUT TYPE="radio" ' . "\n" .
|
||||||
|
' NAME="data[Contact'.ucfirst($type).'][%{id}][source]"' . "\n" .
|
||||||
|
' ONCLICK="switchMethodSource(%{id}, '."'{$type}', '{$stype}'".')"' . "\n" .
|
||||||
|
' CLASS="'.$type.'-method-%{id}-source" ' . "\n" .
|
||||||
|
' ID="'.$type.'-method-%{id}-source-'.$stype.'"' . "\n" .
|
||||||
|
' VALUE="'.$stype.'"' . "\n" .
|
||||||
|
' />' . "\n" .
|
||||||
|
' <LABEL FOR="'.$type.'-method-%{id}-source-'.$stype.'">'.$sname.'</LABEL>' . "\n" .
|
||||||
|
' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$div .= "\n";
|
||||||
|
|
||||||
|
if (isset($values)) {
|
||||||
|
$div .= contactMethodTypeDiv($obj, $type, 'show', $values);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$div .= contactMethodTypeDiv($obj, $type, 'existing');
|
||||||
|
$div .= contactMethodTypeDiv($obj, $type, 'new');
|
||||||
|
}
|
||||||
|
|
||||||
|
$div .=
|
||||||
|
// END source-fieldset
|
||||||
|
'</FIELDSET>' . "\n" .
|
||||||
|
// END source-div
|
||||||
|
'</DIV>' . "\n" .
|
||||||
|
|
||||||
|
// BEGIN method-div
|
||||||
|
'<div id="'.$type.'-%{id}-method-div"' . "\n" .
|
||||||
|
|
||||||
|
$obj->element
|
||||||
|
('form_table',
|
||||||
|
array('class' => "item contact-{$type} entry",
|
||||||
|
'field_prefix' => 'Contact'.ucfirst($type).'.%{id}.ContactsMethod',
|
||||||
|
'fields' => array
|
||||||
|
(
|
||||||
|
'preference' => array
|
||||||
|
('opts' => array
|
||||||
|
('options' => $obj->varstore['methodPreferences'],
|
||||||
|
'selected' => (isset($values) ? $values['ContactsMethod']['preference'] : null),
|
||||||
|
)),
|
||||||
|
|
||||||
|
'type' => array
|
||||||
|
('opts' => array
|
||||||
|
('options' => $obj->varstore['methodTypes'],
|
||||||
|
'selected' => (isset($values) ? $values['ContactsMethod']['type'] : null),
|
||||||
|
)),
|
||||||
|
|
||||||
|
'comment' => array
|
||||||
|
('opts' => array
|
||||||
|
('value' => (isset($values) ? $values['ContactsMethod']['comment'] : null),
|
||||||
|
)),
|
||||||
|
|
||||||
|
))) . "\n" .
|
||||||
|
|
||||||
|
// END method-div
|
||||||
|
'</div>' . "\n" .
|
||||||
|
|
||||||
|
// END type-fieldset
|
||||||
|
'</FIELDSET>' . "\n" .
|
||||||
|
// END type-div
|
||||||
|
'</DIV>'
|
||||||
|
;
|
||||||
|
|
||||||
|
return $div;
|
||||||
|
}
|
||||||
|
|
||||||
|
function contactMethodTypeDiv($obj, $type, $stype, $values = null) {
|
||||||
|
|
||||||
|
$element = 'form_table';
|
||||||
|
|
||||||
|
if ($type === 'phone') {
|
||||||
|
if ($stype === 'existing') {
|
||||||
|
$fields = array
|
||||||
|
('id' => array('name' => 'Phone/Ext',
|
||||||
|
'opts' => array('options' => $obj->varstore['contactPhones'])),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
elseif ($stype === 'new') {
|
||||||
|
$fields = array
|
||||||
|
('type' => array('opts' => array('options' => $obj->varstore['phoneTypes'])),
|
||||||
|
'phone' => true,
|
||||||
|
'ext' => array('name' => "Extension"),
|
||||||
|
'comment' => true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
elseif ($stype === 'show') {
|
||||||
|
$element = 'table';
|
||||||
|
$column_class = array('field', 'value');
|
||||||
|
$rows = array
|
||||||
|
(array('Type', $values['type']),
|
||||||
|
array('Phone', $values['phone']),
|
||||||
|
array('Extension', $values['ext']),
|
||||||
|
array('Comment', $values['comment']),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
die("\n\nInvalid stype ($stype)\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
elseif ($type === 'address') {
|
||||||
|
if ($stype === 'existing') {
|
||||||
|
$fields = array
|
||||||
|
('id' => array('name' => 'Address',
|
||||||
|
'opts' => array('options' => $obj->varstore['contactAddresses'])),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
elseif ($stype === 'new') {
|
||||||
|
$fields = array
|
||||||
|
('address' => true,
|
||||||
|
'city' => true,
|
||||||
|
'state' => true,
|
||||||
|
'postcode' => array('name' => 'Zip Code'),
|
||||||
|
'country' => true,
|
||||||
|
'comment' => true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
elseif ($stype === 'show') {
|
||||||
|
$element = 'table';
|
||||||
|
$column_class = array('field', 'value');
|
||||||
|
$rows = array
|
||||||
|
(array('Address', preg_replace("/\n/", "<BR>", $values['address'])),
|
||||||
|
array('City', $values['city']),
|
||||||
|
array('State', $values['state']),
|
||||||
|
array('Zip Code', $values['postcode']),
|
||||||
|
array('Country', $values['country']),
|
||||||
|
array('Comment', $values['comment']),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
die("\n\nInvalid stype ($stype)\n\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif ($type === 'email') {
|
||||||
|
if ($stype === 'existing') {
|
||||||
|
$fields = array
|
||||||
|
('id' => array('name' => 'Email',
|
||||||
|
'opts' => array('options' => $obj->varstore['contactEmails'])),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
elseif ($stype === 'new') {
|
||||||
|
$fields = array
|
||||||
|
('email' => true,
|
||||||
|
'comment' => true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
elseif ($stype === 'show') {
|
||||||
|
$element = 'table';
|
||||||
|
$column_class = array('field', 'value');
|
||||||
|
$rows = array
|
||||||
|
(array('Email', $values['email']),
|
||||||
|
array('Comment', $values['comment']),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
die("\n\nInvalid type ($type)\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
// BEGIN sourcetype-div
|
||||||
|
'<div ' . "\n" .
|
||||||
|
' class="'.$type.'-%{id}-div"' . "\n" .
|
||||||
|
' id="'.$type.'-%{id}-'.$stype.'-div"' . "\n" .
|
||||||
|
(isset($values) ? '' : ' STYLE="display:none;"' . "\n") .
|
||||||
|
'>' . "\n" .
|
||||||
|
|
||||||
|
$obj->element
|
||||||
|
($element,
|
||||||
|
array('class' => "item contact-{$type} {$stype}",
|
||||||
|
'field_prefix' => 'Contact'.ucfirst($type).'.%{id}')
|
||||||
|
+ compact('rows', 'fields', 'column_class')) .
|
||||||
|
|
||||||
|
($stype === 'show'
|
||||||
|
? '<input type="hidden" name="data[Contact'.ucfirst($type).'][%{id}][id]" value="'.$values['id'].'"/>' . "\n"
|
||||||
|
: '') .
|
||||||
|
|
||||||
|
// END sourcetype-div
|
||||||
|
'</div>' . "\n" .
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//pr($this->data);
|
||||||
|
?>
|
||||||
|
|
||||||
|
<script type="text/javascript"><!--
|
||||||
|
|
||||||
|
function addPhone(flash) {
|
||||||
|
addDiv('phone-entry-id', 'phone', 'phones', flash, <?php
|
||||||
|
echo FormatHelper::phpVarToJavascript(contactMethodDiv($this,
|
||||||
|
'phone',
|
||||||
|
'Phone Number'),
|
||||||
|
null,
|
||||||
|
' ');
|
||||||
|
?>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addAddress(flash) {
|
||||||
|
addDiv('address-entry-id', 'address', 'addresses', flash, <?php
|
||||||
|
echo FormatHelper::phpVarToJavascript(contactMethodDiv($this,
|
||||||
|
'address',
|
||||||
|
'Address'),
|
||||||
|
null,
|
||||||
|
' ');
|
||||||
|
?>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addEmail(flash) {
|
||||||
|
addDiv('email-entry-id', 'email', 'emails', flash, <?php
|
||||||
|
echo FormatHelper::phpVarToJavascript(contactMethodDiv($this,
|
||||||
|
'email',
|
||||||
|
'Email Address'),
|
||||||
|
null,
|
||||||
|
' ');
|
||||||
|
?>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the form
|
||||||
|
function resetForm() {
|
||||||
|
$('#phones').html('');
|
||||||
|
$('#addresses').html('');
|
||||||
|
$('#emails').html('');
|
||||||
|
$('#phone-entry-id').val(1);
|
||||||
|
$('#address-entry-id').val(1);
|
||||||
|
$('#email-entry-id').val(1);
|
||||||
|
|
||||||
|
<?php foreach ($this->data['ContactPhone'] AS $phone): ?>
|
||||||
|
addDiv('phone-entry-id', 'phone', 'phones', false, <?php
|
||||||
|
echo FormatHelper::phpVarToJavascript(contactMethodDiv($this,
|
||||||
|
'phone',
|
||||||
|
'Phone Number',
|
||||||
|
$phone
|
||||||
|
),
|
||||||
|
null,
|
||||||
|
' ');
|
||||||
|
?>
|
||||||
|
);
|
||||||
|
<?php endforeach; ?>
|
||||||
|
|
||||||
|
<?php foreach ($this->data['ContactAddress'] AS $address): ?>
|
||||||
|
addDiv('address-entry-id', 'address', 'addresses', false, <?php
|
||||||
|
echo FormatHelper::phpVarToJavascript(contactMethodDiv($this,
|
||||||
|
'address',
|
||||||
|
'Address',
|
||||||
|
$address
|
||||||
|
),
|
||||||
|
null,
|
||||||
|
' ');
|
||||||
|
?>
|
||||||
|
);
|
||||||
|
<?php endforeach; ?>
|
||||||
|
|
||||||
|
<?php foreach ($this->data['ContactEmail'] AS $email): ?>
|
||||||
|
addDiv('email-entry-id', 'email', 'emails', false, <?php
|
||||||
|
echo FormatHelper::phpVarToJavascript(contactMethodDiv($this,
|
||||||
|
'email',
|
||||||
|
'Email Address',
|
||||||
|
$email
|
||||||
|
),
|
||||||
|
null,
|
||||||
|
' ');
|
||||||
|
?>
|
||||||
|
);
|
||||||
|
<?php endforeach; ?>
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function switchMethodSource(id, type, source) {
|
||||||
|
$("."+type+"-"+id+"-div")
|
||||||
|
.slideUp();
|
||||||
|
|
||||||
|
$("#"+type+"-"+id+"-"+source+"-div")
|
||||||
|
.slideDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(function(){
|
||||||
|
resetForm();
|
||||||
|
});
|
||||||
|
|
||||||
|
--></script>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
; // alignment
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
* Contact Edit
|
||||||
|
*/
|
||||||
|
|
||||||
|
echo '<div class="contact edit">' . "\n";
|
||||||
|
|
||||||
|
echo $form->create('Contact', array('action' => 'edit')) . "\n";
|
||||||
|
echo $form->input('id') . "\n";
|
||||||
|
|
||||||
|
echo($this->element
|
||||||
|
('form_table',
|
||||||
|
array('class' => 'item contact detail',
|
||||||
|
'caption' => isset($this->data['Contact']) ? 'Edit Contact' : 'New Contact',
|
||||||
|
'fields' => array
|
||||||
|
('first_name' => true,
|
||||||
|
'last_name' => true,
|
||||||
|
'middle_name' => true,
|
||||||
|
'display_name' => true,
|
||||||
|
'company_name' => array('name' => 'Company'),
|
||||||
|
'id_federal' => array('name' => 'SSN'),
|
||||||
|
'id_local' => array('name' => 'ID #'),
|
||||||
|
'id_local_state' => array('name' => 'ID State'),
|
||||||
|
/* 'id_local_exp' => array('name' => 'ID Expiration', */
|
||||||
|
/* 'opts' => array('empty' => true)), */
|
||||||
|
'comment' => true,
|
||||||
|
))) . "\n");
|
||||||
|
|
||||||
|
echo $form->submit('Update') . "\n";
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div CLASS="dynamic-set">
|
||||||
|
<fieldset CLASS="phone superset">
|
||||||
|
<legend>Phone Numbers</legend>
|
||||||
|
<input type="hidden" id="phone-entry-id" value="0">
|
||||||
|
<div id="phones"></div>
|
||||||
|
<fieldset> <legend>
|
||||||
|
<a href="#" onClick="addPhone(true); return false;">Add a Phone Number</a>
|
||||||
|
</legend> </fieldset>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div CLASS="dynamic-set">
|
||||||
|
<fieldset CLASS="address superset">
|
||||||
|
<legend>Mailing Addresses</legend>
|
||||||
|
<input type="hidden" id="address-entry-id" value="0">
|
||||||
|
<div id="addresses"></div>
|
||||||
|
<fieldset> <legend>
|
||||||
|
<a href="#" onClick="addAddress(true); return false;">Add a Mailing Address</a>
|
||||||
|
</legend> </fieldset>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div CLASS="dynamic-set">
|
||||||
|
<fieldset CLASS="email superset">
|
||||||
|
<legend>Email Addresses</legend>
|
||||||
|
<input type="hidden" id="email-entry-id" value="0">
|
||||||
|
<div id="emails"></div>
|
||||||
|
<fieldset> <legend>
|
||||||
|
<a href="#" onClick="addEmail(true); return false;">Add an Email Address</a>
|
||||||
|
</legend> </fieldset>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
; // Alignment
|
||||||
|
|
||||||
|
echo $form->submit('Update') . "\n";
|
||||||
|
echo $form->submit('Cancel', array('name' => 'cancel')) . "\n";
|
||||||
|
echo $form->end() . "\n";
|
||||||
|
echo '</div>' . "\n";
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
<div class="contacts index">
|
|
||||||
<?php echo $this->element('contacts', array('heading' => '<h2>'.$heading.'</h2>')) ?>
|
|
||||||
</div>
|
|
||||||
@@ -1,63 +1,55 @@
|
|||||||
<?php /* -*- mode:PHP -*- */ ?>
|
<?php /* -*- mode:PHP -*- */
|
||||||
|
|
||||||
<div class="contacts view">
|
echo '<div class="contact view">' . "\n";
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
function currency($number) {
|
|
||||||
if ($number < 0)
|
|
||||||
return "($ " . number_format(-1*$number, 2) . ")";
|
|
||||||
else
|
|
||||||
return "$ " . number_format($number, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
function phone($phone) {
|
|
||||||
$phone = preg_replace("/\D/", "", $phone);
|
|
||||||
if(strlen($phone) == 7)
|
|
||||||
return preg_replace("/(\d{3})(\d{4})/", "$1-$2", $phone);
|
|
||||||
elseif(strlen($phone) == 10)
|
|
||||||
return preg_replace("/(\d{3})(\d{3})(\d{4})/", "$1-$2-$3", $phone);
|
|
||||||
else
|
|
||||||
return $phone;
|
|
||||||
}
|
|
||||||
|
|
||||||
function datefmt($date) {
|
|
||||||
$date_fmt = 'm/d/Y';
|
|
||||||
return ($date
|
|
||||||
? date_format(date_create($date), $date_fmt)
|
|
||||||
: null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* Tenant Info
|
**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
* Contact Detail Main Section
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$rows = array(array('Name', $contact['Contact']['display_name']),
|
$rows = array(array('First Name', $contact['Contact']['first_name']),
|
||||||
array('Company', $contact['Contact']['company_name']),
|
array('Middle Name', $contact['Contact']['middle_name']),
|
||||||
array('SSN', $contact['Contact']['id_federal']),
|
array('Last Name', $contact['Contact']['last_name']),
|
||||||
array('ID', ($contact['Contact']['id_num']
|
array('Company', $contact['Contact']['company_name']),
|
||||||
. ($contact['Contact']['id_state']
|
array('SSN', $contact['Contact']['id_federal']),
|
||||||
? " - ".$contact['Contact']['id_state']
|
array('ID', ($contact['Contact']['id_local']
|
||||||
: ""))),
|
. ($contact['Contact']['id_local']
|
||||||
array('Comment', $contact['Contact']['comment']));
|
? " - ".$contact['Contact']['id_local_state']
|
||||||
|
: ""))),
|
||||||
|
array('Comment', $contact['Contact']['comment']));
|
||||||
|
|
||||||
echo $this->element('table',
|
echo $this->element('table',
|
||||||
array('class' => 'item contact detail',
|
array('class' => 'item contact detail',
|
||||||
'caption' => 'Tenant Info',
|
'caption' => 'Contact Details',
|
||||||
'rows' => $rows,
|
'rows' => $rows,
|
||||||
'column_class' => array('field', 'value')));
|
'column_class' => array('field', 'value')));
|
||||||
|
|
||||||
|
|
||||||
?>
|
/**********************************************************************
|
||||||
<DIV CLASS="infobox contact">
|
* Contact Info Box
|
||||||
<DIV CLASS="summary grand deposit">
|
*/
|
||||||
Security Deposit: <?php echo currency($outstandingDeposit); ?>
|
|
||||||
</DIV>
|
echo '<div class="infobox">' . "\n";
|
||||||
<DIV CLASS="summary grand balance">
|
$rows = array();
|
||||||
Balance: <?php echo currency($outstandingBalance); ?>
|
echo $this->element('table',
|
||||||
</DIV>
|
array('class' => 'summary',
|
||||||
</DIV>
|
'rows' => $rows,
|
||||||
<?php
|
'column_class' => array('field', 'value'),
|
||||||
|
'suppress_alternate_rows' => true,
|
||||||
|
));
|
||||||
|
echo '</div>' . "\n";
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
* Supporting Elements Section
|
||||||
|
*/
|
||||||
|
|
||||||
|
echo '<div CLASS="detail supporting">' . "\n";
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
@@ -66,7 +58,7 @@ echo $this->element('table',
|
|||||||
$headers = array('Phone', 'Preference', 'Comment');
|
$headers = array('Phone', 'Preference', 'Comment');
|
||||||
$rows = array();
|
$rows = array();
|
||||||
foreach($contact['ContactPhone'] AS $phone) {
|
foreach($contact['ContactPhone'] AS $phone) {
|
||||||
$rows[] = array(phone($phone['phone']) .
|
$rows[] = array(FormatHelper::phone($phone['phone']) .
|
||||||
($phone['ext'] ? " x".$phone['ext'] : ""),
|
($phone['ext'] ? " x".$phone['ext'] : ""),
|
||||||
$phone['ContactsMethod']['preference'] . " / " .
|
$phone['ContactsMethod']['preference'] . " / " .
|
||||||
$phone['ContactsMethod']['type'] . " / " .
|
$phone['ContactsMethod']['type'] . " / " .
|
||||||
@@ -82,26 +74,6 @@ echo $this->element('table',
|
|||||||
'column_class' => $headers));
|
'column_class' => $headers));
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
|
||||||
* Emails
|
|
||||||
*/
|
|
||||||
$headers = array('Email', 'Preference', 'Comment');
|
|
||||||
$rows = array();
|
|
||||||
foreach($contact['ContactEmail'] AS $email) {
|
|
||||||
$rows[] = array($email['email'],
|
|
||||||
$email['ContactsMethod']['preference'] . " / " .
|
|
||||||
$email['ContactsMethod']['type'],
|
|
||||||
$email['comment']);
|
|
||||||
}
|
|
||||||
|
|
||||||
echo $this->element('table',
|
|
||||||
array('class' => 'item email list',
|
|
||||||
'caption' => 'Email',
|
|
||||||
'headers' => $headers,
|
|
||||||
'rows' => $rows,
|
|
||||||
'column_class' => $headers));
|
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* Addresses
|
* Addresses
|
||||||
*/
|
*/
|
||||||
@@ -127,77 +99,38 @@ echo $this->element('table',
|
|||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* Lease History
|
* Emails
|
||||||
*/
|
*/
|
||||||
$headers = array('Lease', 'Unit', 'Signed', 'Move-In', 'Move-Out', 'Rent', 'Deposit', 'Comment');
|
$headers = array('Email', 'Preference', 'Comment');
|
||||||
$rows = array();
|
$rows = array();
|
||||||
foreach($contact['Lease'] AS $lease) {
|
foreach($contact['ContactEmail'] AS $email) {
|
||||||
$rows[] = array('#'.$lease['number'],
|
$rows[] = array($email['email'],
|
||||||
$html->link($lease['Unit']['name'],
|
$email['ContactsMethod']['preference'] . " / " .
|
||||||
array('controller' => 'units',
|
$email['ContactsMethod']['type'],
|
||||||
'action' => 'view',
|
$email['comment']);
|
||||||
$lease['Unit']['id'])),
|
|
||||||
datefmt($lease['lease_date']),
|
|
||||||
datefmt($lease['movein_date']),
|
|
||||||
datefmt($lease['moveout_date']),
|
|
||||||
$lease['amount'],
|
|
||||||
$lease['deposit'],
|
|
||||||
$lease['comment']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
echo $this->element('table',
|
echo $this->element('table',
|
||||||
array('class' => 'item lease list',
|
array('class' => 'item email list',
|
||||||
'caption' => 'Lease History',
|
'caption' => 'Email',
|
||||||
'headers' => $headers,
|
'headers' => $headers,
|
||||||
'rows' => $rows,
|
'rows' => $rows,
|
||||||
'column_class' => $headers));
|
'column_class' => $headers));
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* Ledger History
|
* Customers
|
||||||
*/
|
*/
|
||||||
foreach($contact['Lease'] AS $lease) {
|
|
||||||
$headers = array(/*'Charge/Receipt'*/'Charge', 'Date', 'Through', 'Type', 'Comment', 'Amount', 'Balance', 'Total');
|
|
||||||
|
|
||||||
$rows = array();
|
echo $this->element('customers', array
|
||||||
$row_class = array();
|
('config' => array
|
||||||
$running_total = 0;
|
('caption' => 'Related Customers',
|
||||||
$odd = 0;
|
'rows' => $contact['Customer'],
|
||||||
foreach($lease['Charge'] AS $charge) {
|
)));
|
||||||
$amount = $charge['total'];
|
|
||||||
|
|
||||||
$balance = $amount;
|
|
||||||
foreach ($charge['Receipt'] AS $receipt)
|
|
||||||
$balance -= $receipt['ChargesReceipt']['amount'];
|
|
||||||
|
|
||||||
$running_total += $balance;
|
/* End "detail supporting" div */
|
||||||
|
echo '</div>' . "\n";
|
||||||
|
|
||||||
$rows[] = array($html->link('#'.$charge['id'],
|
/* End page div */
|
||||||
array('controller' => 'charges',
|
echo '</div>' . "\n";
|
||||||
'action' => 'view',
|
|
||||||
$charge['id'])),
|
|
||||||
datefmt($charge['charge_date']),
|
|
||||||
datefmt($charge['charge_to_date']),
|
|
||||||
$charge['ChargeType']['name'],
|
|
||||||
$charge['comment'],
|
|
||||||
currency($amount),
|
|
||||||
currency($balance),
|
|
||||||
//currency($amount - $paid));
|
|
||||||
currency($running_total));
|
|
||||||
|
|
||||||
$row_class[] = array('charge', (++$odd % 2) ? 'oddrow' : 'evnrow');
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
echo $this->element('table',
|
|
||||||
array('class' => 'item ledger list',
|
|
||||||
'caption' => 'Lease #'.$lease['number'].' (Unit: '.$lease['Unit']['name'].')',
|
|
||||||
'suppress_alternate_rows' => true,
|
|
||||||
'headers' => $headers,
|
|
||||||
'rows' => $rows,
|
|
||||||
'row_class' => $row_class,
|
|
||||||
'column_class' => $headers));
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|||||||
274
site/views/customers/edit.ctp
Normal file
274
site/views/customers/edit.ctp
Normal file
@@ -0,0 +1,274 @@
|
|||||||
|
<?php /* -*- mode:PHP -*- */
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* Because we make use of functions here,
|
||||||
|
* we need to put our top level variables somewhere
|
||||||
|
* we can access them.
|
||||||
|
*/
|
||||||
|
$this->varstore = compact('contactTypes', 'contacts');
|
||||||
|
|
||||||
|
//pr($this->data);
|
||||||
|
/**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
* Javascript
|
||||||
|
*/
|
||||||
|
|
||||||
|
function customerContactDiv($obj, $values = null, $primary = false) {
|
||||||
|
|
||||||
|
$div =
|
||||||
|
// BEGIN type-div
|
||||||
|
'<DIV>' . "\n" .
|
||||||
|
// BEGIN type-fieldset
|
||||||
|
'<FIELDSET CLASS="contact subset">' . "\n" .
|
||||||
|
'<LEGEND>Contact #%{id} (%{remove})</LEGEND>' . "\n" .
|
||||||
|
|
||||||
|
// BEGIN source-div
|
||||||
|
'<DIV ID="contact-%{id}-source-div">' . "\n" .
|
||||||
|
// BEGIN source-fieldset
|
||||||
|
'<FIELDSET>' . "\n" .
|
||||||
|
//'<LEGEND>Source</LEGEND>' . "\n" .
|
||||||
|
''
|
||||||
|
;
|
||||||
|
|
||||||
|
if (!isset($values)) {
|
||||||
|
foreach (array('Existing', 'New') AS $sname) {
|
||||||
|
$stype = strtolower($sname);
|
||||||
|
$div .=
|
||||||
|
'<INPUT TYPE="radio" ' . "\n" .
|
||||||
|
' NAME="data[Contact][%{id}][source]"' . "\n" .
|
||||||
|
' ONCLICK="switchContactSource(%{id}, '."'{$stype}'".')"' . "\n" .
|
||||||
|
' CLASS="contact-%{id}-source" ' . "\n" .
|
||||||
|
' ID="contact-%{id}-source-'.$stype.'"' . "\n" .
|
||||||
|
' VALUE="'.$stype.'"' . "\n" .
|
||||||
|
//' CHECKED' . "\n" .
|
||||||
|
' />' . "\n" .
|
||||||
|
' <LABEL FOR="contact-%{id}-source-'.$stype.'">'.$sname.'</LABEL>' . "\n" .
|
||||||
|
' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$div .= "\n";
|
||||||
|
|
||||||
|
if (isset($values)) {
|
||||||
|
$div .= customerContactTypeDiv($obj, 'show', $values);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$div .= customerContactTypeDiv($obj, 'existing');
|
||||||
|
$div .= customerContactTypeDiv($obj, 'new');
|
||||||
|
}
|
||||||
|
|
||||||
|
$div .=
|
||||||
|
// END source-fieldset
|
||||||
|
'</FIELDSET>' . "\n" .
|
||||||
|
// END source-div
|
||||||
|
'</DIV>' . "\n" .
|
||||||
|
|
||||||
|
// BEGIN contact-div
|
||||||
|
'<div id="contact-%{id}-contact-div"' . "\n" .
|
||||||
|
|
||||||
|
$obj->element
|
||||||
|
('form_table',
|
||||||
|
array('class' => "item contact entry",
|
||||||
|
'field_prefix' => 'Contact.%{id}.ContactsCustomer',
|
||||||
|
'fields' => array
|
||||||
|
(
|
||||||
|
'Customer.primary_contact_entry' => array
|
||||||
|
('name' => 'Primary Contact',
|
||||||
|
'no_prefix' => true,
|
||||||
|
'opts' => array
|
||||||
|
('type' => 'radio',
|
||||||
|
'options' => array('%{id}' => false),
|
||||||
|
'value' => ($primary ? '%{id}' : 'bogus-value-to-suppress-hidden-input'),
|
||||||
|
)),
|
||||||
|
|
||||||
|
'type' => array
|
||||||
|
('opts' => array
|
||||||
|
('options' => $obj->varstore['contactTypes'],
|
||||||
|
'selected' => (isset($values) ? $values['ContactsCustomer']['type'] : null),
|
||||||
|
)),
|
||||||
|
|
||||||
|
'comment' => array
|
||||||
|
('opts' => array
|
||||||
|
('value' => (isset($values) ? $values['ContactsCustomer']['comment'] : null),
|
||||||
|
)),
|
||||||
|
|
||||||
|
))) . "\n" .
|
||||||
|
|
||||||
|
// END contact-div
|
||||||
|
'</div>' . "\n" .
|
||||||
|
|
||||||
|
// END type-fieldset
|
||||||
|
'</FIELDSET>' . "\n" .
|
||||||
|
// END type-div
|
||||||
|
'</DIV>'
|
||||||
|
;
|
||||||
|
|
||||||
|
return $div;
|
||||||
|
}
|
||||||
|
|
||||||
|
function customerContactTypeDiv($obj, $stype, $values = null) {
|
||||||
|
|
||||||
|
$element = 'form_table';
|
||||||
|
$class = $stype;
|
||||||
|
|
||||||
|
if ($stype === 'existing') {
|
||||||
|
$fields = array
|
||||||
|
('id' => array('name' => 'Contact',
|
||||||
|
'opts' => array('options' => $obj->varstore['contacts'])),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
elseif ($stype === 'new') {
|
||||||
|
$fields = array
|
||||||
|
('first_name' => true,
|
||||||
|
'last_name' => true,
|
||||||
|
'middle_name' => true,
|
||||||
|
'display_name' => true,
|
||||||
|
'company_name' => array('name' => 'Company'),
|
||||||
|
'id_federal' => array('name' => 'SSN'),
|
||||||
|
'id_local' => array('name' => 'ID #'),
|
||||||
|
'id_local_state' => array('name' => 'ID State'),
|
||||||
|
/* 'id_local_exp' => array('name' => 'ID Expiration', */
|
||||||
|
/* 'opts' => array('empty' => true)), */
|
||||||
|
'comment' => true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
elseif ($stype === 'show') {
|
||||||
|
$element = 'table';
|
||||||
|
$class = 'detail';
|
||||||
|
$column_class = array('field', 'value');
|
||||||
|
$rows = array(array('First Name', $values['first_name']),
|
||||||
|
array('Last Name', $values['last_name']),
|
||||||
|
array('Company', $values['company_name']),
|
||||||
|
array('Comment', $values['comment']));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
die("\n\nInvalid stype ($stype)\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
// BEGIN sourcetype-div
|
||||||
|
'<div ' . "\n" .
|
||||||
|
' class="contact-%{id}-div"' . "\n" .
|
||||||
|
' id="contact-%{id}-'.$stype.'-div"' . "\n" .
|
||||||
|
(isset($values) ? '' : ' STYLE="display:none;"' . "\n") .
|
||||||
|
'>' . "\n" .
|
||||||
|
|
||||||
|
$obj->element
|
||||||
|
($element,
|
||||||
|
array('class' => "item contact {$class}",
|
||||||
|
'field_prefix' => 'Contact.%{id}')
|
||||||
|
+ compact('rows', 'fields', 'column_class')) .
|
||||||
|
|
||||||
|
($stype === 'show'
|
||||||
|
? '<input type="hidden" name="data[Contact][%{id}][id]" value="'.$values['id'].'"/>' . "\n"
|
||||||
|
: '') .
|
||||||
|
|
||||||
|
// END sourcetype-div
|
||||||
|
'</div>' . "\n" .
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<script type="text/javascript"><!--
|
||||||
|
|
||||||
|
function addContact(flash) {
|
||||||
|
addDiv('contact-entry-id', 'contact', 'contacts', flash, <?php
|
||||||
|
echo FormatHelper::phpVarToJavascript
|
||||||
|
(customerContactDiv($this),
|
||||||
|
null,
|
||||||
|
' ');
|
||||||
|
?>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the form
|
||||||
|
function resetForm() {
|
||||||
|
$('#contacts').html('');
|
||||||
|
$('#contact-entry-id').val(1);
|
||||||
|
|
||||||
|
<?php foreach ($this->data['Contact'] AS $contact): ?>
|
||||||
|
addDiv('contact-entry-id', 'contact', 'contacts', false, <?php
|
||||||
|
echo FormatHelper::phpVarToJavascript
|
||||||
|
(customerContactDiv($this,
|
||||||
|
$contact,
|
||||||
|
$contact['id'] == $this->data['Customer']['primary_contact_id']
|
||||||
|
),
|
||||||
|
null,
|
||||||
|
' ');
|
||||||
|
?>
|
||||||
|
);
|
||||||
|
<?php endforeach; ?>
|
||||||
|
|
||||||
|
if ($("#contact-entry-id").val() == 1) {
|
||||||
|
addDiv('contact-entry-id', 'contact', 'contacts', false, <?php
|
||||||
|
echo FormatHelper::phpVarToJavascript
|
||||||
|
(customerContactDiv($this, null, true),
|
||||||
|
null,
|
||||||
|
' ');
|
||||||
|
?>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function switchContactSource(id, source) {
|
||||||
|
$(".contact-"+id+"-div")
|
||||||
|
.slideUp();
|
||||||
|
|
||||||
|
$("#contact-"+id+"-"+source+"-div")
|
||||||
|
.slideDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(function(){
|
||||||
|
resetForm();
|
||||||
|
});
|
||||||
|
|
||||||
|
--></script>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
; // alignment
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
* Customer Edit
|
||||||
|
*/
|
||||||
|
|
||||||
|
echo '<div class="customer edit">' . "\n";
|
||||||
|
|
||||||
|
echo $form->create('Customer', array('action' => 'edit')) . "\n";
|
||||||
|
echo $form->input('id') . "\n";
|
||||||
|
|
||||||
|
echo($this->element
|
||||||
|
('form_table',
|
||||||
|
array('class' => 'item customer detail',
|
||||||
|
'caption' => isset($this->data['Customer']) ? 'Edit Customer' : 'New Customer',
|
||||||
|
'fields' => array
|
||||||
|
('name' => true,
|
||||||
|
'comment' => true,
|
||||||
|
))) . "\n");
|
||||||
|
|
||||||
|
echo $form->submit('Update') . "\n";
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div CLASS="dynamic-set">
|
||||||
|
<fieldset CLASS="contact superset">
|
||||||
|
<legend>Contacts</legend>
|
||||||
|
<input type="hidden" id="contact-entry-id" value="0">
|
||||||
|
<div id="contacts"></div>
|
||||||
|
<fieldset> <legend>
|
||||||
|
<a href="#" onClick="addContact(true); return false;">Add a Contact</a>
|
||||||
|
</legend> </fieldset>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
; // Alignment
|
||||||
|
|
||||||
|
echo $form->submit('Update') . "\n";
|
||||||
|
echo $form->submit('Cancel', array('name' => 'cancel')) . "\n";
|
||||||
|
echo $form->end() . "\n";
|
||||||
|
echo '</div>' . "\n";
|
||||||
453
site/views/customers/receipt.ctp
Normal file
453
site/views/customers/receipt.ctp
Normal file
@@ -0,0 +1,453 @@
|
|||||||
|
<?php /* -*- mode:PHP -*- */ ?>
|
||||||
|
|
||||||
|
<div class="receipt input">
|
||||||
|
<?php
|
||||||
|
; // Editor alignment
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
**********************************************************************
|
||||||
|
* Javascript
|
||||||
|
*/
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<script type="text/javascript"><!--
|
||||||
|
|
||||||
|
// prepare the form when the DOM is ready
|
||||||
|
$(document).ready(function() {
|
||||||
|
var options = {
|
||||||
|
target: '#output-debug', // target element(s) to be updated with server response
|
||||||
|
beforeSubmit: verifyRequest, // pre-submit callback
|
||||||
|
success: showResponse, // post-submit callback
|
||||||
|
|
||||||
|
// other available options:
|
||||||
|
//url: url, // override for form's 'action' attribute
|
||||||
|
//type: 'get', // 'get' or 'post', override for form's 'method' attribute
|
||||||
|
//dataType: null, // 'xml', 'script', or 'json' (expected server response type)
|
||||||
|
//clearForm: true, // clear all form fields after successful submit
|
||||||
|
//resetForm: true, // reset the form after successful submit
|
||||||
|
|
||||||
|
// $.ajax options can be used here too, for example:
|
||||||
|
//timeout: 3000,
|
||||||
|
};
|
||||||
|
|
||||||
|
// bind form using 'ajaxForm'
|
||||||
|
$('#receipt-form').ajaxForm(options);
|
||||||
|
});
|
||||||
|
|
||||||
|
// pre-submit callback
|
||||||
|
function verifyRequest(formData, jqForm, options) {
|
||||||
|
// formData is an array; here we use $.param to convert it to a string to display it
|
||||||
|
// but the form plugin does this for you automatically when it submits the data
|
||||||
|
//var_dump(formData);
|
||||||
|
//$('#request-debug').html('<PRE>'+dump(formData)+'</PRE>');
|
||||||
|
$('#request-debug').html('Ommitted');
|
||||||
|
//return false;
|
||||||
|
|
||||||
|
$('#response-debug').html('Loading <BLINK>...</BLINK>');
|
||||||
|
$('#output-debug').html('Loading <BLINK>...</BLINK>');
|
||||||
|
|
||||||
|
// here we could return false to prevent the form from being submitted;
|
||||||
|
// returning anything other than false will allow the form submit to continue
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// post-submit callback
|
||||||
|
function showResponse(responseText, statusText) {
|
||||||
|
// for normal html responses, the first argument to the success callback
|
||||||
|
// is the XMLHttpRequest object's responseText property
|
||||||
|
|
||||||
|
// if the ajaxForm method was passed an Options Object with the dataType
|
||||||
|
// property set to 'xml' then the first argument to the success callback
|
||||||
|
// is the XMLHttpRequest object's responseXML property
|
||||||
|
|
||||||
|
// if the ajaxForm method was passed an Options Object with the dataType
|
||||||
|
// property set to 'json' then the first argument to the success callback
|
||||||
|
// is the json data object returned by the server
|
||||||
|
|
||||||
|
if (statusText == 'success') {
|
||||||
|
// get a clean slate
|
||||||
|
//resetForm();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
alert('not successful??');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$('#response-debug').html('<PRE>'+dump(statusText)+'</PRE>');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the form
|
||||||
|
function resetForm() {
|
||||||
|
$('#payment-entry-id').val(1);
|
||||||
|
$('#payments').html('');
|
||||||
|
|
||||||
|
$("#receipt-customer-id").html("INTERNAL ERROR");
|
||||||
|
$("#receipt-customer-name").html("INTERNAL ERROR");
|
||||||
|
$("#receipt-balance").html("INTERNAL ERROR");
|
||||||
|
$("#receipt-charges-caption").html("Outstanding Charges");
|
||||||
|
|
||||||
|
addPaymentSource(false);
|
||||||
|
datepickerNow('TransactionStamp');
|
||||||
|
}
|
||||||
|
|
||||||
|
function onRowSelect(grid_id, customer_id) {
|
||||||
|
// Set the customer id that will be returned with the form
|
||||||
|
$("#customer-id").val(customer_id);
|
||||||
|
|
||||||
|
// Get the item names from the grid
|
||||||
|
//$("#receipt-customer-id").html($(grid_id).getCell(customer_id, 'Customer-id'));
|
||||||
|
// REVISIT <AP>: 20090708
|
||||||
|
// This is not intended as a long term solution,
|
||||||
|
// but I need a way to enter data and then view
|
||||||
|
// the results. This link will help.
|
||||||
|
$("#receipt-customer-id").html('<A HREF="/pmgr/site/customers/view/' +
|
||||||
|
$(grid_id).getCell(customer_id, 'Customer-id').replace(/^#/,'') +
|
||||||
|
'">' +
|
||||||
|
$(grid_id).getCell(customer_id, 'Customer-id') +
|
||||||
|
'</A>');
|
||||||
|
$("#receipt-customer-name").html($(grid_id).getCell(customer_id, 'Customer-name'));
|
||||||
|
$("#receipt-balance").html("Calculating...");
|
||||||
|
$("#receipt-charges-caption").html("Please Wait...");
|
||||||
|
|
||||||
|
// Hide the "no customer" message and show the current customer
|
||||||
|
$(".customer-selection-invalid").hide();
|
||||||
|
$(".customer-selection-valid").show();
|
||||||
|
|
||||||
|
// Update the charges grid to reflect this customer
|
||||||
|
updateCharges(customer_id);
|
||||||
|
|
||||||
|
// Collapse the grid now that the user has selected
|
||||||
|
$("#customers-list .HeaderButton").click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onGridState(grid_id, state) {
|
||||||
|
if (state == 'visible') {
|
||||||
|
$(".customer-selection-invalid").hide();
|
||||||
|
$(".customer-selection-valid").hide();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ($("#customer-id").val() > 0) {
|
||||||
|
$(".customer-selection-valid").show();
|
||||||
|
$(".customer-selection-invalid").hide();
|
||||||
|
} else {
|
||||||
|
$(".customer-selection-valid").hide();
|
||||||
|
$(".customer-selection-invalid").show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addPaymentSource(flash) {
|
||||||
|
addDiv('payment-entry-id', 'payment', 'payments', flash,
|
||||||
|
// HTML section
|
||||||
|
'<FIELDSET CLASS="payment subset">' +
|
||||||
|
'<LEGEND>Payment #%{id} (%{remove})</LEGEND>' +
|
||||||
|
|
||||||
|
'<DIV ID="payment-div-%{id}">' +
|
||||||
|
<?php
|
||||||
|
echo FormatHelper::phpVarToJavascript
|
||||||
|
($form->input('LedgerEntry.%{id}.account_id',
|
||||||
|
array('type' => 'radio',
|
||||||
|
'separator' => '<BR>',
|
||||||
|
'onclick' => ('switchPaymentType(' .
|
||||||
|
'\\\'payment-type-div\\\', ' .
|
||||||
|
'%{id}, ' .
|
||||||
|
'$(this).attr("id")' .
|
||||||
|
')' .
|
||||||
|
//' return false;'
|
||||||
|
''
|
||||||
|
),
|
||||||
|
'legend' => false,
|
||||||
|
'value' => $defaultAccount,
|
||||||
|
'options' => $paymentAccounts))) . "+\n";
|
||||||
|
?>
|
||||||
|
'</DIV>' +
|
||||||
|
|
||||||
|
'<DIV ID="payment-amount-div-%{id}" CLASS="input text required">' +
|
||||||
|
' <LABEL FOR="payment-amount-%{id}">Amount</LABEL>' +
|
||||||
|
' <INPUT TYPE="text" SIZE="20"' +
|
||||||
|
' NAME="data[LedgerEntry][%{id}][amount]"' +
|
||||||
|
' ID="payment-amount-%{id}" />' +
|
||||||
|
'</DIV>' +
|
||||||
|
|
||||||
|
<?php
|
||||||
|
foreach ($paymentAccounts AS $account_id => $name) {
|
||||||
|
$div = '<DIV';
|
||||||
|
$div .= ' ID="payment-type-div-%{id}-'.$account_id.'"';
|
||||||
|
$div .= ' CLASS="payment-type-div-%{id}"';
|
||||||
|
$div .= ' STYLE="display:none;">';
|
||||||
|
|
||||||
|
if ($name == 'Check') {
|
||||||
|
$div .= '<DIV CLASS="input text required">';
|
||||||
|
$div .= ' <LABEL FOR="payment-check-number-%{id}">Check Number</LABEL>';
|
||||||
|
$div .= ' <INPUT TYPE="text" SIZE="6" NAME="data[LedgerEntry][%{id}][acct]['.$account_id.'][data1]"';
|
||||||
|
$div .= ' ID="payment-check-number-%{id}" />';
|
||||||
|
$div .= '</DIV>';
|
||||||
|
}
|
||||||
|
elseif ($name == 'Money Order') {
|
||||||
|
$div .= '<DIV CLASS="input text required">';
|
||||||
|
$div .= ' <LABEL FOR="payment-moneyorder-number-%{id}">Money Order Number</LABEL>';
|
||||||
|
$div .= ' <INPUT TYPE="text" SIZE="6" NAME="data[LedgerEntry][%{id}][acct]['.$account_id.'][data1]"';
|
||||||
|
$div .= ' ID="payment-moneyorder-number-%{id}" />';
|
||||||
|
$div .= '</DIV>';
|
||||||
|
}
|
||||||
|
elseif ($name == 'ACH') {
|
||||||
|
$div .= '<DIV CLASS="input text required">';
|
||||||
|
$div .= ' <LABEL FOR="payment-ach-routing-%{id}">Routing Number</LABEL>';
|
||||||
|
$div .= ' <INPUT TYPE="text" SIZE="9" NAME="data[LedgerEntry][%{id}][acct]['.$account_id.'][data1]"';
|
||||||
|
$div .= ' ID="payment-ach-routing-%{id}" />';
|
||||||
|
$div .= '</DIV>';
|
||||||
|
|
||||||
|
$div .= '<DIV CLASS="input text required">';
|
||||||
|
$div .= ' <LABEL FOR="payment-ach-account-%{id}">Account Number</LABEL>';
|
||||||
|
$div .= ' <INPUT TYPE="text" SIZE="17" NAME="data[LedgerEntry][%{id}][acct]['.$account_id.'][data2]"';
|
||||||
|
$div .= ' ID="payment-ach-account-%{id}" />';
|
||||||
|
$div .= '</DIV>';
|
||||||
|
}
|
||||||
|
elseif ($name == 'Credit Card') {
|
||||||
|
$div .= '<DIV CLASS="input text required">';
|
||||||
|
$div .= ' <LABEL FOR="payment-creditcard-account-%{id}">Account Number</LABEL>';
|
||||||
|
$div .= ' <INPUT TYPE="text" SIZE="16" NAME="data[LedgerEntry][%{id}][acct]['.$account_id.'][data1]"';
|
||||||
|
$div .= ' ID="payment-creditcard-account-%{id}" />';
|
||||||
|
$div .= '</DIV>';
|
||||||
|
|
||||||
|
$div .= '<DIV CLASS="input text required">';
|
||||||
|
$div .= ' <LABEL FOR="payment-creditcard-expiration-%{id}">Expiration Date</LABEL>';
|
||||||
|
$div .= ' <INPUT TYPE="text" SIZE="10" NAME="data[LedgerEntry][%{id}][acct]['.$account_id.'][data2]"';
|
||||||
|
$div .= ' ID="payment-creditcard-expiration-%{id}" />';
|
||||||
|
$div .= ' </DIV>';
|
||||||
|
|
||||||
|
$div .= '<DIV CLASS="input text required">';
|
||||||
|
$div .= ' <LABEL FOR="payment-creditcard-cvv2-%{id}">CVV2 Code</LABEL>';
|
||||||
|
$div .= ' <INPUT TYPE="text" SIZE="10" NAME="data[LedgerEntry][%{id}][acct]['.$account_id.'][data3]"';
|
||||||
|
$div .= ' ID="payment-creditcard-cvv2-%{id}" />';
|
||||||
|
$div .= '</DIV>';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$div .= '</DIV>';
|
||||||
|
echo "'$div' +\n";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
'</FIELDSET>'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function switchPaymentType(paymentid_base, paymentid, radioid) {
|
||||||
|
$("."+paymentid_base+"-"+paymentid).slideUp();
|
||||||
|
var account_id = $("#"+radioid).val();
|
||||||
|
$("#"+paymentid_base+"-"+paymentid+"-"+account_id).slideDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function updateChargesGrid(idlist) {
|
||||||
|
$('#charge-entries-jqGrid').setPostDataItem('idlist', serialize(idlist));
|
||||||
|
$('#charge-entries-jqGrid')
|
||||||
|
.setGridParam({ page: 1 })
|
||||||
|
.trigger("reloadGrid");
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateCharges(id) {
|
||||||
|
var url = '<?php echo ($html->url(array("controller" => $this->params["controller"],
|
||||||
|
"action" => "unreconciled"))); ?>';
|
||||||
|
url += '/'+id;
|
||||||
|
|
||||||
|
$('#charge-entries-jqGrid').clearGridData();
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: "GET",
|
||||||
|
url: url,
|
||||||
|
dataType: "xml",
|
||||||
|
success: function(xml) {
|
||||||
|
var ids = new Array();
|
||||||
|
$('entry',xml).each(function(i){
|
||||||
|
ids.push($(this).attr('id'));
|
||||||
|
});
|
||||||
|
$('#receipt-balance').html(fmtCurrency($('entries',xml).attr('balance')));
|
||||||
|
$("#receipt-charges-caption").html("Outstanding Charges");
|
||||||
|
updateChargesGrid(ids);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
--></script>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
; // align
|
||||||
|
//echo '<DIV ID="dialog">' . "\n";
|
||||||
|
|
||||||
|
echo $this->element('customers', array
|
||||||
|
('config' => array
|
||||||
|
('grid_div_id' => 'customers-list',
|
||||||
|
'grid_div_class' => 'text-below',
|
||||||
|
'caption' => ('<A HREF="#" ONCLICK="$(\'#customers-list .HeaderButton\').click();'.
|
||||||
|
' return false;">Select Customer</A>'),
|
||||||
|
'grid_setup' => array('hiddengrid' => isset($customer['id'])),
|
||||||
|
'grid_events' => array('onSelectRow' =>
|
||||||
|
array('ids' =>
|
||||||
|
'if (ids != null){onRowSelect("#"+$(this).attr("id"), ids);}'),
|
||||||
|
'onHeaderClick' =>
|
||||||
|
array('gridstate' =>
|
||||||
|
'onGridState("#"+$(this).attr("id"), gridstate)'),
|
||||||
|
),
|
||||||
|
'nolinks' => true,
|
||||||
|
'limit' => 10,
|
||||||
|
)));
|
||||||
|
|
||||||
|
echo ('<DIV CLASS="receipt grid-selection-text">' .
|
||||||
|
|
||||||
|
'<DIV CLASS="customer-selection-valid" style="display:none">' .
|
||||||
|
'Customer <SPAN id="receipt-customer-id"></SPAN>' .
|
||||||
|
': <SPAN id="receipt-customer-name"></SPAN>' .
|
||||||
|
|
||||||
|
/* '<DIV CLASS="supporting">' . */
|
||||||
|
/* '<TABLE>' . */
|
||||||
|
/* '<TR><TD CLASS="field">Balance:</TD><TD CLASS="value"><SPAN id="receipt-balance"></SPAN></TD></TR>' . */
|
||||||
|
/* '</TABLE>' . */
|
||||||
|
/* '</DIV>' . */
|
||||||
|
|
||||||
|
'</DIV>' . // END customer-selection-valid
|
||||||
|
|
||||||
|
'<DIV CLASS="customer-selection-invalid" style="display:none">' .
|
||||||
|
'Please select customer' .
|
||||||
|
'</DIV>' .
|
||||||
|
|
||||||
|
'</DIV>' . "\n");
|
||||||
|
|
||||||
|
|
||||||
|
echo $this->element('ledger_entries', array
|
||||||
|
(// Element configuration
|
||||||
|
'account_ftype' => 'credit',
|
||||||
|
'limit' => 8,
|
||||||
|
|
||||||
|
// Grid configuration
|
||||||
|
'config' => array
|
||||||
|
(
|
||||||
|
'grid_div_id' => 'charge-entries',
|
||||||
|
'grid_div_class' => 'text-below',
|
||||||
|
'caption' => '<SPAN id="receipt-charges-caption"></SPAN>',
|
||||||
|
'rows' => $charges['entry'],
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
echo('<DIV CLASS="receipt grid-selection-text">' .
|
||||||
|
'<DIV CLASS="customer-selection-valid" style="display:none">' .
|
||||||
|
|
||||||
|
//'<DIV CLASS="supporting">' .
|
||||||
|
'<TABLE ID="supporting-table">' .
|
||||||
|
'<TR><TD CLASS="field">Balance:</TD><TD CLASS="value"><SPAN id="receipt-balance"></SPAN></TD></TR>' .
|
||||||
|
'</TABLE>' .
|
||||||
|
//'</DIV>' .
|
||||||
|
|
||||||
|
'</DIV>' . // END customer-selection-valid
|
||||||
|
'</DIV>' .
|
||||||
|
"\n");
|
||||||
|
|
||||||
|
echo $form->create(null, array('id' => 'receipt-form',
|
||||||
|
'url' => array('controller' => 'transactions',
|
||||||
|
'action' => 'postReceipt')));
|
||||||
|
|
||||||
|
|
||||||
|
echo $form->input("id",
|
||||||
|
array('id' => 'customer-id',
|
||||||
|
'type' => 'hidden',
|
||||||
|
'value' => 0));
|
||||||
|
|
||||||
|
echo $this->element('form_table',
|
||||||
|
array('class' => "item receipt transaction entry",
|
||||||
|
//'with_name_after' => ':',
|
||||||
|
'field_prefix' => 'Transaction',
|
||||||
|
'fields' => array
|
||||||
|
("stamp" => array('opts' => array('type' => 'text'),
|
||||||
|
'between' => '<A HREF="#" ONCLICK="datepickerNow(\'TransactionStamp\'); return false;">Now</A>',
|
||||||
|
),
|
||||||
|
"comment" => array('opts' => array('size' => 50),
|
||||||
|
),
|
||||||
|
)));
|
||||||
|
|
||||||
|
echo $form->submit('Generate Receipt') . "\n";
|
||||||
|
?>
|
||||||
|
|
||||||
|
<fieldset CLASS="payment superset">
|
||||||
|
<legend>Payments</legend>
|
||||||
|
<input type="hidden" id="payment-entry-id" value="0">
|
||||||
|
<div id="payments"></div>
|
||||||
|
<fieldset> <legend>
|
||||||
|
<a href="#" onClick="addPaymentSource(true); return false;">Add Another Payment</a>
|
||||||
|
</legend> </fieldset>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<?php echo $form->end('Generate Receipt'); ?>
|
||||||
|
|
||||||
|
<?php /* echo '</DIV>' . "\n"; // End of the dialog DIV */ ?>
|
||||||
|
|
||||||
|
<div><H4>Request</H4><div id="request-debug"></div></div>
|
||||||
|
<div><H4>Response</H4><div id="response-debug"></div></div>
|
||||||
|
<div><H4>Output</H4><div id="output-debug"></div></div>
|
||||||
|
|
||||||
|
<script type="text/javascript"><!--
|
||||||
|
$(document).ready(function(){
|
||||||
|
$("#TransactionStamp")
|
||||||
|
.attr('autocomplete', 'off')
|
||||||
|
.datepicker({ constrainInput: true,
|
||||||
|
numberOfMonths: [1, 1],
|
||||||
|
showCurrentAtPos: 0,
|
||||||
|
dateFormat: 'mm/dd/yy' });
|
||||||
|
|
||||||
|
resetForm();
|
||||||
|
|
||||||
|
<?php if (isset($customer['id'])): ?>
|
||||||
|
$("#customer-id").val(<?php echo $customer['id']; ?>);
|
||||||
|
//$("#receipt-customer-id").html("<?php echo '#'.$customer['id']; ?>");
|
||||||
|
$("#receipt-customer-id").html('<A HREF="/pmgr/site/customers/view/' +
|
||||||
|
"<?php echo $customer['id']; ?>" +
|
||||||
|
'">#' +
|
||||||
|
"<?php echo $customer['id']; ?>" +
|
||||||
|
'</A>');
|
||||||
|
$("#receipt-customer-name").html("<?php echo $customer['name']; ?>");
|
||||||
|
$("#receipt-balance").html(fmtCurrency("<?php echo $charges['balance']; ?>"));
|
||||||
|
onGridState(null, 'hidden');
|
||||||
|
<?php else: ?>
|
||||||
|
onGridState(null, 'visible');
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* $("#dialog").dialog({ */
|
||||||
|
/* bgiframe: true, */
|
||||||
|
/* autoOpen: false, */
|
||||||
|
/* height: 500, */
|
||||||
|
/* width: 600, */
|
||||||
|
/* modal: true, */
|
||||||
|
/* buttons: { */
|
||||||
|
/* 'Post a Payment': function() { */
|
||||||
|
/* var bValid = true; */
|
||||||
|
/* if (bValid) { */
|
||||||
|
/* $('#debug').append('<H2>POSTED!</H2>'); */
|
||||||
|
/* $(this).dialog('close'); */
|
||||||
|
/* } */
|
||||||
|
/* }, */
|
||||||
|
/* Cancel: function() { */
|
||||||
|
/* $(this).dialog('close'); */
|
||||||
|
/* } */
|
||||||
|
/* }, */
|
||||||
|
/* close: function() { */
|
||||||
|
/* } */
|
||||||
|
/* }); */
|
||||||
|
|
||||||
|
/* $('#post-payment').click(function() { */
|
||||||
|
/* $('#dialog').dialog('open'); */
|
||||||
|
/* }); */
|
||||||
|
|
||||||
|
});
|
||||||
|
--></script>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a href="#" onClick="$('#debug').html(''); return false;">Clear Debug Output</a>
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user