Compare commits

...

87 Commits

Author SHA1 Message Date
abijah
1b790334fd Releasing v0.2.4 to fix problem with zero dollar SURPLUS items
git-svn-id: file:///svn-source/pmgr/tags/v0.2.4@983 97e9348a-65ac-dc4b-aefc-98561f571b83
2010-04-02 13:21:09 +00:00
abijah
2b2ebc55c0 Fixed bug caused by floating point math. Sometimes, SURPLUS entries were being left with zero amounts.
git-svn-id: file:///svn-source/pmgr/branches/v0.2_work@981 97e9348a-65ac-dc4b-aefc-98561f571b83
2010-04-02 13:04:02 +00:00
abijah
f49a23b2fd Brought all notes to a top level directory, and got rid of the VSS database sql file. It has moved to its own repository: /svn/vss
git-svn-id: file:///svn-source/pmgr/branches/v0.2_work@967 97e9348a-65ac-dc4b-aefc-98561f571b83
2010-03-12 04:24:38 +00:00
abijah
48631cffee Fixed a bug that was causing some lease charge_through_date fields to be NULL, which in turn caused additional charges to be added in error when assessing charges. The problem was that we were looking for statement entry charges that were not followed by other statement entries the next month. The intention was to locate rent charges that were not matched by a rent charge the following month, but we were looking for any type of statement entry. The presently visible problem was with a disbursement the next month on Lease #21, leaving NO last charge, not even just the wrong date. However, the issue could even be as simple as a Cleaning charge the next month, so we now filter not only for charges, but rent charges.
git-svn-id: file:///svn-source/pmgr/branches/v0.2_work@963 97e9348a-65ac-dc4b-aefc-98561f571b83
2010-03-12 03:48:03 +00:00
abijah
0a594bb5a9 Merge in db changes from the v0.2.0 release
git-svn-id: file:///svn-source/pmgr/branches/v0.2_work@947 97e9348a-65ac-dc4b-aefc-98561f571b83
2010-03-02 18:44:56 +00:00
abijah
b3d43d754b Fixed a bug with customer lease counts after editing the customer.
git-svn-id: file:///svn-source/pmgr/branches/v0.2_work@946 97e9348a-65ac-dc4b-aefc-98561f571b83
2010-03-02 18:35:09 +00:00
abijah
a47d5d54b4 Fixed bug which was kicking us out of the dev/sandbox when editing a customer. Actually, seems like more of a workaround for a CakePHP bug, but it's not certain.
git-svn-id: file:///svn-source/pmgr/branches/v0.2_work@945 97e9348a-65ac-dc4b-aefc-98561f571b83
2010-03-02 18:05:37 +00:00
abijah
8f5c3031fc Renamed the work branch, since it will be used for bugfix revs as well.
git-svn-id: file:///svn-source/pmgr/branches/v0.2_work@943 97e9348a-65ac-dc4b-aefc-98561f571b83
2010-03-02 18:03:11 +00:00
abijah
83bfb8d32d As the database has grown, the statement entry page query has finally ground to a halt. The query was kludged as simple as possible, and it now operates much quicker. A cleaner solution would be nice...
git-svn-id: file:///svn-source/pmgr/branches/v0.2.0_work@936 97e9348a-65ac-dc4b-aefc-98561f571b83
2010-03-02 03:10:54 +00:00
abijah
28817cea38 Removed buttons from the print media
git-svn-id: file:///svn-source/pmgr/branches/v0.2.0_work@914 97e9348a-65ac-dc4b-aefc-98561f571b83
2010-01-15 01:27:44 +00:00
abijah
3dca204ac6 Added the Deposit row to all tenders, not just those that have been deposited. This helps avoid confusion when looking at a non-deposited tender, since one may be trying to figure out whether or not it has been deposited and yet not remember if this is the appropriate screen.
git-svn-id: file:///svn-source/pmgr/branches/v0.2.0_work@900 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-12-09 18:02:00 +00:00
abijah
2fb2e6f5aa Update todo to reflect newly implemented features.
git-svn-id: file:///svn-source/pmgr/branches/v0.2.0_work@875 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-10-09 23:53:39 +00:00
abijah
44def81c81 Merge in from v0.1.0
git-svn-id: file:///svn-source/pmgr/branches/v0.2.0_work@874 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-10-09 23:51:45 +00:00
abijah
03da3afb98 More things to do based on how it's been going at VSS
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@873 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-10-09 23:46:18 +00:00
abijah
3b885e2686 Fixed the problem of client side lease selection breaking the automated rent invoicing tools.
git-svn-id: file:///svn-source/pmgr/branches/v0.2.0_work@872 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-10-09 23:17:46 +00:00
abijah
e162d35d56 Added a more automated mechanism for adding multiple rent charges to an invoice. Also included is a proration tool. This needs more work though, since it relies on server side data from the lease. Selecting a new lease on the client side will cause this change to fail, and so we'll need to add a column for charged-through. Finally, error messages for invoice and receipt were improved slightly to better explain the error.
git-svn-id: file:///svn-source/pmgr/branches/v0.2.0_work@871 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-10-09 22:48:37 +00:00
abijah
3b3ed7a264 Branch to add minor enhancements to v0.1.0
git-svn-id: file:///svn-source/pmgr/branches/v0.2.0_work@870 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-10-09 19:58:50 +00:00
cron
3b5aa78a47 property_manager database backup as of 2009_10_09_0113
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@869 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-10-09 08:13:46 +00:00
cron
721faa129b property_manager database backup as of 2009_10_08_0117
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@868 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-10-08 08:18:30 +00:00
cron
78806de606 property_manager database backup as of 2009_10_06_0124
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@867 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-10-06 08:24:25 +00:00
cron
d4ea5eea1f property_manager database backup as of 2009_10_03_0123
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@866 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-10-03 08:24:03 +00:00
cron
9213c1c21d property_manager database backup as of 2009_10_02_0905
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@865 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-10-02 16:06:14 +00:00
abijah
9674812e78 Merge in from the v0.1.0 tag, which is a bit of a botch. The intention was to make the change to trunk, then re-label as v0.1.1. However, due to a mixup, this was put directly as the v0.1.0 tag. It isn't good, but the change is small enough we'll live with it this time.
git-svn-id: file:///svn-source/pmgr/trunk@864 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-10-02 15:54:00 +00:00
abijah
8bda7c2cb0 Added the updateLeaseCount call to the customer update function. Most of the time it will not be necessary, but the purpose of update() is to ensure the customer info is current, so we're obligated to call it.
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@863 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-10-02 15:40:54 +00:00
cron
375d63485c property_manager database backup as of 2009_10_02_0116
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@862 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-10-02 08:16:34 +00:00
cron
26045a3db7 property_manager database backup as of 2009_10_01_0103
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@861 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-10-01 08:03:28 +00:00
cron
04ac012754 property_manager database backup as of 2009_09_29_0120
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@860 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-29 08:20:23 +00:00
cron
e6f662f0a1 property_manager database backup as of 2009_09_26_0113
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@859 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-26 08:13:58 +00:00
cron
04b3c06cda property_manager database backup as of 2009_09_25_0129
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@858 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-25 08:30:15 +00:00
cron
24da6d75b5 property_manager database backup as of 2009_09_24_0120
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@857 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-24 08:20:57 +00:00
cron
542ae17afd property_manager database backup as of 2009_09_23_0114
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@856 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-23 08:14:54 +00:00
cron
97fffaa610 property_manager database backup as of 2009_09_20_0118
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@855 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-20 08:18:46 +00:00
cron
3eb5139b62 property_manager database backup as of 2009_09_19_0125
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@854 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-19 08:26:07 +00:00
cron
5245393a04 property_manager database backup as of 2009_09_18_0104
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@853 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-18 08:04:33 +00:00
cron
e59df1dffb property_manager database backup as of 2009_09_16_0122
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@852 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-16 08:23:11 +00:00
cron
61da97974b property_manager database backup as of 2009_09_15_0112
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@851 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-15 08:12:24 +00:00
cron
6482cfd4cc property_manager database backup as of 2009_09_14_1953
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@850 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-15 02:53:36 +00:00
abijah
c3e51a7a6b Tagging first official release: v0.1.0
git-svn-id: file:///svn-source/pmgr/tags/v0.1.0@849 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-15 02:47:55 +00:00
abijah
de069ef186 Updated the todo items
git-svn-id: file:///svn-source/pmgr/trunk@848 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-15 02:42:32 +00:00
abijah
5047abba6a Merge in from pre_0.1 branch
git-svn-id: file:///svn-source/pmgr/trunk@847 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-15 02:38:28 +00:00
abijah
4e8426fd79 Move the Charge Assessment link to the operations area, and updated the Transaction Destroy link to the admin menu and gave it a reasonable redirect instead of the view not found message (since it's no longer a dev function
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@846 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-15 02:32:56 +00:00
abijah
6630cdfcd6 Part of the final effort to bring the information current, ready to be live.
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@845 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-15 02:30:20 +00:00
abijah
48d332f40f Part of the final effort to bring the information current, ready to be live.
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@844 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-15 02:30:05 +00:00
abijah
3ede96dad9 Fixed the map titles on IE.
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@843 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-14 17:03:56 +00:00
abijah
3e3dff31a8 I believe the bug Shirley has been seeing is finally fixed. The problem is that an extra comma at the end of a javascript object literal blows up in IE7. FF and IE8 both handle it fine, which is why we hadn't noticed. Hopefully, this change includes all areas which had the extra comma.
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@842 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-07 17:04:34 +00:00
abijah
3642724b5e ajax logging is not working on site. The log message is now added as part of the post. However, it is added by using jQuery, so it may not work. Consequently, there is a default value to help narrow down the problem.
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@841 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-07 05:30:08 +00:00
abijah
0ad68f4d6a Added util function to allow us to capture client side logging, and utilize it in the invoice view to find out why the app is not working on site. Also, since everything depends so heavily on jQuery, added an internal error if jQuery fails to load.
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@840 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-06 15:32:41 +00:00
abijah
2628edfbdd Merge in single site support for both the sandbox and a development box as well.
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@839 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-06 04:32:55 +00:00
abijah
740bcbedc0 Integrated sandbox functionality directly into the application so that there is no need for two independent applications for both the normal and sandbox version.
git-svn-id: file:///svn-source/pmgr/branches/single_site_sandbox_20090905@838 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-06 04:28:29 +00:00
abijah
2f3046294d Missed the transaction controller change as part of r835. Also, added check to see that customer/unit have been selected at movein.
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@837 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-06 04:25:27 +00:00
abijah
7a2034aea0 D:\bin\svnbranch.pl: Branch from /branches/pre_0.1_work_20090819 to /branches/single_site_sandbox_20090905
git-svn-id: file:///svn-source/pmgr/branches/single_site_sandbox_20090905@836 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-06 04:16:52 +00:00
abijah
bb4046e1da Changes to allow invoices and receipts to work without ajax, since it may be the ajaxForm that is creating problems for Shirley on-site. Added debug prints to the invoice page as well, to get feedback on what exactly is breaking.
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@835 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-05 15:15:24 +00:00
abijah
f717713842 Moved out Cathy Conway
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@834 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-03 18:20:51 +00:00
abijah
5008452089 Added separation to request logging
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@833 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-01 04:48:38 +00:00
abijah
68a1397ad6 Added request log mechanism
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@832 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-09-01 04:43:24 +00:00
abijah
ef64644536 Added move in/out selection verification before submit
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@831 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-31 15:10:45 +00:00
abijah
72ea84ad88 Modified the internal error to capture to the log.
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@830 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-31 14:43:03 +00:00
abijah
0f3aa42f57 Last tweak for now to size reduction.
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@829 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-30 15:28:13 +00:00
abijah
fb23b7ffaa Another minor tweak, so the formatter functions don't fall directly into the first grid area (but just above).
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@828 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-30 15:23:12 +00:00
abijah
b731ee6165 Reduced the amount of data sent to the client.
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@827 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-30 15:19:39 +00:00
abijah
34dcbd8b43 Made all grids the same width, which is much more pleasing than when they were variable. This width is a bit too large for 800x600, but has been tested at 1024x768 with no problem. It works great on the Acer netbook.
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@826 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-29 21:29:23 +00:00
abijah
87a2ea5cd6 Decided the Creation menu isn't worth it at the moment, and moved New Deposit back into the Actions menu. Removed Add Customer, since this can and probably will happen directly from the Move-In page. Created an entirely separate Sandbox menu area, since it is of particular interest to the customer.
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@825 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-29 20:59:29 +00:00
abijah
6492cd8b22 Removed the Add Deposit link from the actions menu. It is easy to find after Navigating to Deposits.
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@824 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-29 20:46:33 +00:00
abijah
f6a18cbb6c Thought margin would be picked up from the previous ui-jqgrid-title rules, but apparently not.
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@823 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-29 20:31:44 +00:00
abijah
7198d7e6f4 Changes to have the software function without the presence of jquery-ui (which may not be complete). Also, brought the jquery libraries to the server, instead of using them as hosted from google. Some browser configurations may have an issue with what they deem to be cross site scripting.
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@822 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-29 20:27:12 +00:00
abijah
d79077e279 Removed the debug prints, and got back to the original r5 of hoverintent, except for my change to handle mouseenter and mouseleave
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@821 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-29 18:43:48 +00:00
abijah
cea9332ac6 Using version r5 of hoverIntent. It doesn't work as an event like the original code did, so I had to doctor it up a bit. It works OK with firefox, but not with IE. I have a possible patch to apply after I check this in.
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@820 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-29 18:14:18 +00:00
abijah
bf8aaea041 Modified the dump function, and fixed several places that needed to declare variables using var. Changed the pmgr.jquery.js file to jquery.hoverIntent.js. Fixed a bug causing no ordered lists, since padding and margin were set to 0 for all elements.
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@819 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-29 17:24:06 +00:00
abijah
63704682fa Keeping actions for now
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@818 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-28 22:19:07 +00:00
abijah
63de5641a0 Temporary fix for last minute bug
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@817 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-28 22:11:18 +00:00
abijah
5f6a9ed53f Fixed the http/https problem
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@816 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-28 21:44:39 +00:00
abijah
328d0f8f51 Modified the rebuild_sandbox action to redirect instead of dumping debug output.
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@815 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-28 21:38:23 +00:00
abijah
aee6832374 Fixed the sandbox/unsandbox URLs. I'd like to make this a route... I'll look into it.
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@814 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-28 21:22:50 +00:00
abijah
63e22ec9bf Added more sandbox functionality, including a script to generate the sandbox on the fly from the absolute latest data.
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@813 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-28 21:06:20 +00:00
abijah
fde8923814 Added a utility controller, for calling actions that really aren't related to any other controller (we've been using accounts up to this point).
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@809 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-28 20:46:10 +00:00
abijah
696017a82a Fixed cut/paste bug
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@808 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-28 20:45:11 +00:00
abijah
7bcee943a5 Theme work, and a sandbox function for a consistent point to check whether we're sandboxed or not.
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@807 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-28 19:57:30 +00:00
abijah
0c9b945f7b Added pre-submit data verification for invoice and receipt. The checking is pretty thin, but it's a start. I don't want to do more, as I'm sure there are lots of data validation tools out there and would prefer to go that route.
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@806 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-28 18:22:13 +00:00
abijah
5b5707df5e Fixed a bug with deposit, which prevented update to the deposited tenders. Added INTERNAL_ERROR when an error occurs. Since the module and callers make no effort to roll back changes when an error occurs, it's probably best to just halt. We may need to remove some of these checks, especially in the verifyTransaction function, which is intended to catch errors before they create a problem in the database.
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@805 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-28 16:41:17 +00:00
abijah
c21cdcd9a2 Added server request vars, mostly to include the referer. Added timestamps and tweaked formatting slightly.
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@804 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-28 16:34:01 +00:00
abijah
a79adbce2d Moved the creation actions into the CONTROLLER menu. Minor cleanup of deposit_slip. Minor tweaking to views.
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@803 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-28 16:32:21 +00:00
abijah
a3b376544c Replaced the hardcoded 'level' checks, and incorporated (as a first pass) the new permission mechanism
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@802 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-28 07:11:14 +00:00
abijah
43c957baa2 Added users and groups and a couple basic options (dev & admin) for testing. Since dev/admin is now a database option, the special routing mechanism has been removed.
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@801 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-28 04:47:33 +00:00
abijah
a66024c889 Fixed the build script; updated users schema to no longer hold password information and to not require contact information; added a set of users and groups for VSS
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@800 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-28 04:25:53 +00:00
abijah
aed090fbe2 Added rollup sql code to bring the current database up to speed with the option / permission changes.
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@799 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-28 04:03:19 +00:00
abijah
7904372dff Added support for permissions. Next is to implement some.
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@798 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-28 03:32:07 +00:00
abijah
1d4dcbd2b0 Made changes to the database and added models to support options. Next is permissions
git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@797 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-08-28 01:42:29 +00:00
109 changed files with 2932 additions and 7024 deletions

View File

@@ -1,3 +0,0 @@
@echo off
mysql --user=pmgr --password=pmgruser < %~dp0\db\property_manager.sql
echo Done!

File diff suppressed because it is too large Load Diff

View File

@@ -25,9 +25,9 @@
-- REVISIT <AP>: 20090511
-- By not specifying the database, the script can
-- make the determination of which one to use.
-- DROP DATABASE IF EXISTS `property_manager`;
-- CREATE DATABASE `property_manager`;
-- USE `property_manager`;
DROP DATABASE IF EXISTS `property_manager`;
CREATE DATABASE `property_manager`;
USE `property_manager`;
-- ######################################################################
@@ -241,7 +241,7 @@ CREATE TABLE `pmgr_contacts_methods` (
-- ######################################################################
-- ######################################################################
-- ##
-- ## GROUPS
-- ## GROUPS / USERS
-- ##
@@ -256,59 +256,15 @@ CREATE TABLE `pmgr_groups` (
-- code may not be userful
`code` VARCHAR(12) NOT NULL, -- User style "id"
`name` VARCHAR(80) NOT NULL,
-- Lower ranks are given higher priority
`rank` SMALLINT UNSIGNED NOT NULL DEFAULT 100,
`comment` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- ----------------------------------------------------------------------
-- ----------------------------------------------------------------------
-- TABLE pmgr_group_options
DROP TABLE IF EXISTS `pmgr_group_options`;
CREATE TABLE `pmgr_group_options` (
`group_id` INT(10) UNSIGNED NOT NULL,
`name` VARCHAR(50) NOT NULL,
`value` VARCHAR(255) NOT NULL,
`comment` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`group_id`, `name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- ----------------------------------------------------------------------
-- ----------------------------------------------------------------------
-- TABLE pmgr_group_permissions
DROP TABLE IF EXISTS `pmgr_group_permissions`;
CREATE TABLE `pmgr_group_permissions` (
`group_id` INT(10) UNSIGNED NOT NULL,
`name` CHAR(30) NOT NULL,
`access` ENUM('ALLOWED',
'DENIED',
'FORCED')
NOT NULL DEFAULT 'ALLOWED',
`comment` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`group_id`, `name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- ######################################################################
-- ######################################################################
-- ######################################################################
-- ######################################################################
-- ######################################################################
-- ######################################################################
-- ######################################################################
-- ######################################################################
-- ######################################################################
-- ##
-- ## USERS
-- ##
-- ----------------------------------------------------------------------
-- ----------------------------------------------------------------------
@@ -318,14 +274,10 @@ DROP TABLE IF EXISTS `pmgr_users`;
CREATE TABLE `pmgr_users` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`code` VARCHAR(12) NOT NULL, -- User style "id"
-- Login details. Passwords are not yet used (and so NULL).
`login` VARCHAR(30) NOT NULL,
`salt` CHAR(12) DEFAULT NULL,
`passhash` VARCHAR(255) DEFAULT NULL,
`login` VARCHAR(30) NOT NULL,
-- Contact information for this user
`contact_id` INT(10) UNSIGNED NOT NULL,
`contact_id` INT(10) UNSIGNED DEFAULT NULL,
-- Specific comments
`comment` VARCHAR(255) DEFAULT NULL,
@@ -334,18 +286,208 @@ CREATE TABLE `pmgr_users` (
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- ######################################################################
-- ######################################################################
-- ######################################################################
-- ######################################################################
-- ######################################################################
-- ######################################################################
-- ######################################################################
-- ######################################################################
-- ######################################################################
-- ##
-- ## OPTIONS
-- ##
-- ----------------------------------------------------------------------
-- ----------------------------------------------------------------------
-- TABLE pmgr_options
DROP TABLE IF EXISTS `pmgr_options`;
CREATE TABLE `pmgr_options` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
`comment` VARCHAR(255) DEFAULT NULL,
UNIQUE KEY `name_key` (`name`),
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- ----------------------------------------------------------------------
-- ----------------------------------------------------------------------
-- TABLE pmgr_option_values
DROP TABLE IF EXISTS `pmgr_option_values`;
CREATE TABLE `pmgr_option_values` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`option_id` INT(10) UNSIGNED NOT NULL,
`value` VARCHAR(255) NOT NULL,
`comment` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- ----------------------------------------------------------------------
-- ----------------------------------------------------------------------
-- TABLE pmgr_default_options
DROP TABLE IF EXISTS `pmgr_default_options`;
CREATE TABLE `pmgr_default_options` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`option_value_id` INT(10) UNSIGNED NOT NULL,
`comment` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- ----------------------------------------------------------------------
-- ----------------------------------------------------------------------
-- TABLE pmgr_group_options
DROP TABLE IF EXISTS `pmgr_group_options`;
CREATE TABLE `pmgr_group_options` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`group_id` INT(10) UNSIGNED NOT NULL,
`option_value_id` INT(10) UNSIGNED NOT NULL,
`comment` VARCHAR(255) DEFAULT NULL,
KEY `group_key` (`group_id`),
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- ----------------------------------------------------------------------
-- ----------------------------------------------------------------------
-- TABLE pmgr_user_options
DROP TABLE IF EXISTS `pmgr_user_options`;
CREATE TABLE `pmgr_user_options` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` INT(10) UNSIGNED NOT NULL,
`name` VARCHAR(50) NOT NULL,
`value` VARCHAR(255) NOT NULL,
`option_value_id` INT(10) UNSIGNED NOT NULL,
`comment` VARCHAR(255) DEFAULT NULL,
KEY `user_key` (`user_id`),
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
PRIMARY KEY (`user_id`, `name`)
-- ----------------------------------------------------------------------
-- ----------------------------------------------------------------------
-- TABLE pmgr_site_options
DROP TABLE IF EXISTS `pmgr_site_options`;
CREATE TABLE `pmgr_site_options` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`site_id` INT(10) UNSIGNED NOT NULL,
`option_value_id` INT(10) UNSIGNED NOT NULL,
`comment` VARCHAR(255) DEFAULT NULL,
KEY `site_key` (`site_id`),
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- ######################################################################
-- ######################################################################
-- ######################################################################
-- ######################################################################
-- ######################################################################
-- ######################################################################
-- ######################################################################
-- ######################################################################
-- ######################################################################
-- ##
-- ## PERMISSIONS
-- ##
-- ----------------------------------------------------------------------
-- ----------------------------------------------------------------------
-- TABLE pmgr_permissions
DROP TABLE IF EXISTS `pmgr_permissions`;
CREATE TABLE `pmgr_permissions` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
`comment` VARCHAR(255) DEFAULT NULL,
UNIQUE KEY `name_key` (`name`),
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- ----------------------------------------------------------------------
-- ----------------------------------------------------------------------
-- TABLE pmgr_permission_values
DROP TABLE IF EXISTS `pmgr_permission_values`;
CREATE TABLE `pmgr_permission_values` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`permission_id` INT(10) UNSIGNED NOT NULL,
`access` ENUM('ALLOW',
'DENY')
NOT NULL DEFAULT 'DENY',
`level` SMALLINT UNSIGNED DEFAULT NULL,
`comment` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- ----------------------------------------------------------------------
-- ----------------------------------------------------------------------
-- TABLE pmgr_default_permissions
DROP TABLE IF EXISTS `pmgr_default_permissions`;
CREATE TABLE `pmgr_default_permissions` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`permission_value_id` INT(10) UNSIGNED NOT NULL,
`comment` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- ----------------------------------------------------------------------
-- ----------------------------------------------------------------------
-- TABLE pmgr_group_permissions
DROP TABLE IF EXISTS `pmgr_group_permissions`;
CREATE TABLE `pmgr_group_permissions` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`group_id` INT(10) UNSIGNED NOT NULL,
`permission_value_id` INT(10) UNSIGNED NOT NULL,
`comment` VARCHAR(255) DEFAULT NULL,
KEY `group_key` (`group_id`),
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- ----------------------------------------------------------------------
-- ----------------------------------------------------------------------
-- TABLE pmgr_user_permissions
DROP TABLE IF EXISTS `pmgr_user_permissions`;
CREATE TABLE `pmgr_user_permissions` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` INT(10) UNSIGNED NOT NULL,
`permission_value_id` INT(10) UNSIGNED NOT NULL,
`comment` VARCHAR(255) DEFAULT NULL,
KEY `user_key` (`user_id`),
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- ----------------------------------------------------------------------
-- ----------------------------------------------------------------------
-- TABLE pmgr_site_permissions
DROP TABLE IF EXISTS `pmgr_site_permissions`;
CREATE TABLE `pmgr_site_permissions` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`site_id` INT(10) UNSIGNED NOT NULL,
`permission_value_id` INT(10) UNSIGNED NOT NULL,
`comment` VARCHAR(255) DEFAULT NULL,
KEY `site_key` (`site_id`),
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
@@ -380,46 +522,6 @@ CREATE TABLE `pmgr_sites` (
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- ----------------------------------------------------------------------
-- ----------------------------------------------------------------------
-- TABLE pmgr_site_options
DROP TABLE IF EXISTS `pmgr_site_options`;
CREATE TABLE `pmgr_site_options` (
`site_id` INT(10) UNSIGNED NOT NULL,
`name` VARCHAR(50) NOT NULL,
`value` VARCHAR(255) NOT NULL,
`comment` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`site_id`, `name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- ----------------------------------------------------------------------
-- ----------------------------------------------------------------------
-- TABLE pmgr_site_memberships
--
-- Which users are allowed to access which sites,
-- and under which set of group permissions (possibly multiple)
-- SELECT U.id, P.name, MAX(P.access)
-- FROM pmgr_users U
-- LEFT JOIN pmgr_site_membership M ON M.user_id = U.id
-- LEFT JOIN pmgr_groups G ON G.id = M.group_id
-- LEFT JOIN pmgr_group_permissions P ON P.group_id = G.id
-- GROUP BY U.id, P.name
DROP TABLE IF EXISTS `pmgr_site_memberships`;
CREATE TABLE `pmgr_site_memberships` (
`site_id` INT(10) UNSIGNED NOT NULL,
`user_id` INT(10) UNSIGNED NOT NULL,
`group_id` INT(10) UNSIGNED NOT NULL,
`comment` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`site_id`, `user_id`, `group_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- ----------------------------------------------------------------------
-- ----------------------------------------------------------------------
-- TABLE pmgr_site_areas
@@ -437,6 +539,38 @@ CREATE TABLE `pmgr_site_areas` (
-- ######################################################################
-- ######################################################################
-- ######################################################################
-- ######################################################################
-- ######################################################################
-- ######################################################################
-- ######################################################################
-- ######################################################################
-- ######################################################################
-- ##
-- ## MEMBERSHIPS
-- ##
-- ----------------------------------------------------------------------
-- ----------------------------------------------------------------------
-- TABLE pmgr_memberships
--
-- Which users are allowed to access which sites,
-- and under which set of group permissions (possibly multiple)
DROP TABLE IF EXISTS `pmgr_memberships`;
CREATE TABLE `pmgr_memberships` (
`site_id` INT(10) UNSIGNED NOT NULL,
`user_id` INT(10) UNSIGNED NOT NULL,
`group_id` INT(10) UNSIGNED NOT NULL,
`comment` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`site_id`, `user_id`, `group_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- ######################################################################
-- ######################################################################
-- ######################################################################

View File

@@ -1,159 +0,0 @@
-- Delete bad transaction(s)
DELETE M
FROM
pmgr_ledger_entries LE,
pmgr_tenders M
WHERE
M.ledger_entry_id = LE.id AND
LE.transaction_id
IN (467);
DELETE LE
FROM
pmgr_ledger_entries LE
WHERE
LE.transaction_id
IN (467);
DELETE SE
FROM
pmgr_statement_entries SE
WHERE
SE.transaction_id
IN (467);
DELETE T
FROM
pmgr_transactions T
WHERE
T.id
IN (467);
-- Delete bad transaction, one variable setting
SET @tid = 467;
DELETE M FROM pmgr_ledger_entries LE, pmgr_tenders M
WHERE M.ledger_entry_id = LE.id AND LE.transaction_id = @tid;
DELETE LE FROM pmgr_ledger_entries LE
WHERE LE.transaction_id = @tid;
DELETE SE FROM pmgr_statement_entries SE
WHERE SE.transaction_id = @tid;
DELETE T FROM pmgr_transactions T
WHERE T.id = @tid;
-- Delete all but one customer
SET @cid = 6;
-- DELETE T FROM pmgr_transactions T
-- LEFT JOIN pmgr_customers C ON C.id = T.customer_id
-- WHERE C.id IS NOT NULL AND C.id <> @cid;
DELETE C FROM pmgr_customers C
WHERE C.id <> @cid;
DELETE L FROM pmgr_leases L
LEFT JOIN pmgr_customers C ON C.id = L.customer_id
WHERE C.id IS NULL;
DELETE T FROM pmgr_transactions T
LEFT JOIN pmgr_customers C ON C.id = T.customer_id
WHERE C.id IS NULL;
DELETE SE FROM pmgr_statement_entries SE
LEFT JOIN pmgr_customers C ON C.id = SE.customer_id
WHERE C.id IS NULL;
DELETE LE FROM pmgr_ledger_entries LE
LEFT JOIN pmgr_transactions T ON T.id = LE.transaction_id
WHERE T.id IS NULL;
DELETE M FROM pmgr_tenders M
LEFT JOIN pmgr_ledger_entries LE ON M.ledger_entry_id = LE.id
WHERE LE.id IS NULL;
DELETE DE FROM pmgr_double_entries DE
LEFT JOIN pmgr_ledger_entries LE ON LE.id = DE.debit_entry_id
WHERE LE.id IS NULL;
DELETE DE FROM pmgr_double_entries DE
LEFT JOIN pmgr_ledger_entries LE ON LE.id = DE.credit_entry_id
WHERE LE.id IS NULL;
UPDATE pmgr_ledger_entries LE, pmgr_ledgers L, pmgr_accounts A
SET LE.ledger_id = L.id
WHERE A.id = LE.account_id AND L.account_id = A.id AND L.sequence = 1;
DELETE FROM pmgr_ledgers WHERE sequence > 1;
UPDATE pmgr_ledgers SET prior_ledger_id = NULL, close_transaction_id = NULL;
-- Delete a ledger entry, associated double entry, and matching ledger_entry
SET @leid = 1365;
DELETE FROM pmgr_ledger_entries WHERE id = @leid;
DELETE DE FROM pmgr_double_entries DE
LEFT JOIN pmgr_ledger_entries LE ON LE.id = DE.debit_entry_id
WHERE LE.id IS NULL;
DELETE DE FROM pmgr_double_entries DE
LEFT JOIN pmgr_ledger_entries LE ON LE.id = DE.credit_entry_id
WHERE LE.id IS NULL;
DELETE LE FROM pmgr_ledger_entries LE
LEFT JOIN pmgr_double_entries DE
ON DE.credit_entry_id = LE.id OR DE.debit_entry_id = LE.id
WHERE DE.id IS NULL;
-- Add and update every Tender.ledger_entry_id (for rolling up old databases)
-- Takes a while to complete (~30s at time of writing)
ALTER TABLE `pmgr_tenders`
ADD `deposit_ledger_entry_id` INT UNSIGNED DEFAULT NULL
AFTER `nsf_ledger_entry_id`;
UPDATE
pmgr_tenders Tnd
JOIN pmgr_tender_types TndT ON TndT.id = Tnd.tender_type_id
JOIN pmgr_transactions T ON T.id = Tnd.deposit_transaction_id
JOIN pmgr_ledger_entries LE ON LE.transaction_id = T.id AND LE.account_id = TndT.account_id
JOIN pmgr_double_entries DE ON DE.debit_entry_id = LE.id OR DE.credit_entry_id = LE.id
JOIN pmgr_ledger_entries LEd ON (DE.debit_entry_id = LEd.id OR DE.credit_entry_id = LEd.id)
AND LEd.id <> LE.id
SET Tnd.deposit_ledger_entry_id = LEd.id;
-- Add auto_deposit and deposit_account_id to tenders
ALTER TABLE `pmgr_tender_types`
ADD `auto_deposit` TINYINT(1) UNSIGNED DEFAULT '0' NOT NULL
AFTER `tillable`;
ALTER TABLE `pmgr_tender_types`
ADD `deposit_account_id` INTEGER(10) UNSIGNED DEFAULT NULL
AFTER `account_id`;
-- Determine economic conditions
SELECT `status`, COUNT(id), SUM(rent) FROM pmgr_units
GROUP BY `status` WITH ROLLUP;
-- Check that transaction totals add up correctly
SELECT T.id, T.type, T.amount,
-- T.type, A.type, E.crdr,
SUM(IF(E.account_id = T.account_id,
IF(A.type IN ('ASSET','EXPENSE') XOR E.crdr='DEBIT',-1,1),0)
*E.amount) AS Tamt,
SUM(IF(E.account_id = T.account_id,
0,IF(A.type IN ('ASSET','EXPENSE') XOR E.crdr='DEBIT',-1,1))
*E.amount) AS Oamt,
COUNT(E.id) AS Ecnt
FROM pmgr_transactions T
-- LEFT JOIN pmgr_statement_entries E ON E.transaction_id = T.id
LEFT JOIN pmgr_ledger_entries E ON E.transaction_id = T.id
LEFT JOIN pmgr_accounts A ON A.id = T.account_id -- E.account_id
-- WHERE
-- E.account_id != T.account_id
GROUP BY T.id
HAVING
(T.type = 'INVOICE' AND Tamt <> T.amount)
OR
(T.type <> 'INVOICE' AND Oamt <> T.amount)
OR
(Tamt * -1 <> Oamt)
-- Verify that statement entries all have the correct type
SELECT SE.id, SE.type, T.id, T.type
FROM pmgr_statement_entries SE
LEFT JOIN pmgr_transactions T ON T.id = SE.transaction_id
WHERE
((T.type = 'RECEIPT' OR T.type = 'CREDIT_NOTE') AND
SE.type NOT IN ('DISBURSEMENT', 'WAIVER', 'REVERSAL', 'WRITEOFF', 'SURPLUS')
)
OR
((T.type = 'INVOICE' OR T.type = 'PAYMENT') AND
SE.type NOT IN ('CHARGE', 'PAYMENT', 'REFUND')
)
-- catch other types not considered in this query
OR T.type NOT IN ('RECEIPT', 'CREDIT_NOTE', 'INVOICE', 'PAYMENT')

View File

@@ -1,68 +0,0 @@
N - GATE
N - ACH / CREDIT CARD PROCESSING
Y - CREDIT CARD ENTRY
Y - ACH ENTRY
P - INVENTORY TRACKING / POS
Y - UNIT TYPES
Y - UNIT SIZES
Y - UNITS
Y - MOVE IN / OUT
Y - UNIT TRANSFERS
Y - LEASE TRACKING (PDF Generation)
Y - LETTERS (PDF Generation)
Y - REMINDERS
Y - MULTIPLE LATE RENT SCHEDULES (Tenant A vs Tenant B)
Y - ACCOUNTING (assign charges to accounts)
Y - DETAILED REPORTING (HTML & PDF)
Y - SITE MAP; HOT CLICKABLE
P - PROSPECTIVE TENANTS
Y - MARKETING
P - RESERVATIONS
P - MOVE OUT NOTICES
P - MULTI-SITE (One database, multiple sites)
Y - GENERATE GEOGRAPHIC MAP OF CUSTOMERS USING GOOGLE!
- Major advantage here... MapPoint only choice with competitors
Y - WEB BASED
Y - CUSTOMER VIEW / MANAGER VIEW
Y - CUSTOMERS CAN CREATE ACCOUNTS, VIEW HISTORY
Y - CUSTOMERS CAN SIGN UP FOR AUTO PAY
----------------------------------------------------------------------
----------------------------------------------------------------------
Operations to be functional
'X' marks functionality sufficiently completed
X - Create Customer ID/Account
X - Add Contact information to Customer
X - Move Customer into Unit
X - Enter Rent Concessions given
X - Asses Rent Charges
X - Asses Late Charges
X - Asses Security Deposits
X - Receive and record Checks
X - Receive and record Money Orders
X - Receive and record Cash
X - Receive and record ACH Deposits
? - Reverse rent charges (early moveout on prepaid occupancy)
X - Handle NSF checks
X - Assess NSF Fees
X - Determine Lease Paid-Through status
X - Report: List of customers overdue
X - Flag unit as overlocked
X - Flag unit as evicting
X - Flag unit as normal status
X - Flag unit as dirty
- Enter notes when communicating with Customer
X - Accept pre-payments
X - Record Customer Move-Out from Unit
X - Record utilization of Security Deposit
X - Record issuing of a refund
- Record Deposit into Petty Cash
- Record Payment from Petty Cash to expenses
X - Record Petty Cash to refund.
X - Write Off Bad Debt
X - Perform a Deposit
X - Close the Books (nightly / weekly, etc)
X - Determine Rents Collected for a given period.

View File

@@ -10,9 +10,9 @@ deny from all
# Now allow local access
# Localhost
allow from 127.0.0
# allow from 127.0.0
# Local subnet
allow from 192.168.7
# allow from 192.168.7
# Provide a mechanism for user authentication
AuthType Digest

View File

@@ -35,10 +35,11 @@
* @subpackage cake.app
*/
class AppController extends Controller {
var $uses = array('Option', 'Permission');
var $helpers = array('Html', 'Form', 'Javascript', 'Format', 'Time', 'Grid');
var $components = array('DebugKit.Toolbar');
var $sidemenu = array('areas' => array('SITE' => false, 'CONTROLLER' => false, 'ACTION' => false));
var $sidemenu = array('areas' => array('SITE' => false, 'CONTROLLER' => false, 'ACTION' => false, 'SANDBOX' => false));
var $std_area = 10;
var $admin_area = 20;
var $dev_area = 30;
@@ -70,6 +71,8 @@ class AppController extends Controller {
$name = Inflector::humanize($this->params['controller']);
elseif ($area == 'ACTION')
$name = Inflector::humanize(Inflector::singularize($this->params['controller']));
elseif ($area == 'SANDBOX')
$name = 'Sandbox';
if (empty($this->sidemenu['areas'][$area]))
$this->sidemenu['areas'][$area]
@@ -196,7 +199,6 @@ class AppController extends Controller {
array('controller' => 'transactions', 'action' => 'deposit'), null,
'SITE');
$this->addSideMenuLink('Accounts',
array('controller' => 'accounts', 'action' => 'index'), null,
'SITE', $this->admin_area);
@@ -218,10 +220,6 @@ class AppController extends Controller {
$this->addSideMenuLink('Stmt Entries',
array('controller' => 'statement_entries', 'action' => 'index'), null,
'SITE', $this->admin_area);
$this->addSideMenuLink('Assess Charges',
array('controller' => 'leases', 'action' => 'assess_all'), null,
'SITE', $this->admin_area);
$this->addSideMenuLink('Un-Nuke',
'#', array('htmlAttributes' =>
@@ -236,22 +234,50 @@ class AppController extends Controller {
$this->addSideMenuLink('New Receipt',
array('controller' => 'customers', 'action' => 'receipt'), null,
'SITE', $this->op_area);
$this->addSideMenuLink('New Invoice',
array('controller' => 'leases', 'action' => 'invoice'), null,
'SITE', $this->op_area);
$this->addSideMenuLink('Move-In',
array('controller' => 'customers', 'action' => 'move_in'), null,
'SITE', $this->op_area);
$this->addSideMenuLink('Move-Out',
array('controller' => 'leases', 'action' => 'move_out'), null,
'SITE', $this->op_area);
$this->addSideMenuLink('New Deposit',
array('controller' => 'tenders', 'action' => 'deposit'), null,
'SITE', $this->op_area);
if (!empty($this->params['admin']))
$this->addSideMenuLink('Assess Charges',
array('controller' => 'leases', 'action' => 'assess_all'), null,
'SITE', $this->op_area);
$url_components = array('plugin', 'controller', 'action', 'named');
if (devbox()) {
/* $sources = ConnectionManager::sourceList(); */
/* $db = ConnectionManager::getDataSource($sources[0])->config['database']; */
/* $this->sideMenuAreaName($db, 'SANDBOX', $this->std_area); */
$this->sideMenuAreaName('DevBox', 'SANDBOX', $this->std_area);
$this->addSideMenuLink('Rebuild DevBox',
array('controller' => 'util', 'action' => 'rebuild_devbox'), null,
'SANDBOX');
}
elseif (sandbox()) {
$this->addSideMenuLink('Rebuild Sandbox',
array('controller' => 'util', 'action' => 'rebuild_sandbox'), null,
'SANDBOX');
$this->addSideMenuLink('Leave Sandbox',
array('sand_route' => false)
+ array_intersect_key($this->params, array_flip($url_components))
+ $this->params['pass'],
null, 'SANDBOX');
}
else {
$this->addSideMenuLink('Enter Sandbox',
array('sand_route' => true)
+ array_intersect_key($this->params, array_flip($url_components))
+ $this->params['pass'],
null, 'SANDBOX');
}
// REVISIT <AP>: 20090824
// Depending on preference, we may put this into the gridView
@@ -278,16 +304,18 @@ class AppController extends Controller {
*/
function beforeFilter() {
$this->params['dev'] =
(!empty($this->params['dev_route']));
$this->params['admin'] =
(!empty($this->params['admin_route']) || !empty($this->params['dev_route']));
$this->params['user'] = $this->Permission->User->currentUser();
$this->params['admin'] = $this->Option->enabled('admin');
$this->params['dev'] = devbox();
if ($this->params['dev'] && !$this->Option->enabled('dev'))
$this->redirect("/");
if (!$this->params['dev'])
Configure::write('debug', '0');
$this->addDefaultSideMenuLinks();
$this->sideMenuEnable('SITE', $this->op_area, false);
//$this->sideMenuEnable('SITE', $this->op_area, false);
foreach ($this->sidemenu['areas'] AS $area_name => $area) {
if (empty($this->params['dev']))
@@ -295,6 +323,13 @@ class AppController extends Controller {
if (empty($this->params['admin']))
$this->sideMenuEnable($area_name, $this->admin_area, false);
}
$this->authorize("controller.{$this->params['controller']}");
$this->authorize("action.{$this->params['controller']}.{$this->params['action']}");
$this->log('----------------------------------------------------------------------', 'request');
$this->log('----------------------------------------------------------------------', 'request');
$this->log($this->params, 'request');
}
@@ -345,7 +380,7 @@ class AppController extends Controller {
unset($area);
// Activate a default section (unless already specified)
foreach (array_reverse($this->sidemenu['areas']) AS $area_name => $area) {
foreach (array_reverse(array_diff_key($this->sidemenu['areas'], array('SANDBOX'=>1))) AS $area_name => $area) {
if (empty($area))
continue;
@@ -394,36 +429,6 @@ class AppController extends Controller {
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: reset_data
* - Development function. TO BE DELETED
*/
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);
}
/**************************************************************************
**************************************************************************
**************************************************************************
@@ -595,8 +600,8 @@ class AppController extends Controller {
// Grouping (which would not be typical)
$query['group'] = $this->gridDataCountGroup($params, $model);
// DEBUG PURPOSES ONLY!
$params['count_query'] = $query;
if ($params['debug'])
$params['count_query'] = $query;
// Get the number of records prior to pagination
return $this->gridDataCountExecute($params, $model, $query);
@@ -852,8 +857,8 @@ class AppController extends Controller {
isset($params['sidx']) ? $params['sidx'] : null,
isset($params['sord']) ? $params['sord'] : null);
// DEBUG PURPOSES ONLY!
$params['query'] = $query;
if ($params['debug'])
$params['query'] = $query;
return $this->gridDataRecordsExecute($params, $model, $query);
}
@@ -976,6 +981,7 @@ class AppController extends Controller {
$this->gridDataPostProcessLinks($params, $model, $records, array());
// DEBUG PURPOSES ONLY!
//if ($params['debug'])
//$params['records'] = $records;
}
@@ -1053,6 +1059,7 @@ class AppController extends Controller {
continue;
// DEBUG PURPOSES ONLY!
//if ($params['debug'])
//$params['linkrecord'][] = compact('table', 'field', 'id', 'controller', 'record');
$record[$table][$field] =
'<A HREF="' .
@@ -1147,14 +1154,26 @@ class AppController extends Controller {
echo " <cell><![CDATA[$data]]></cell>\n";
}
function authorize($name) {
if ($this->Permission->deny($name))
$this->UNAUTHORIZED("Unauthorized: $name");
}
function UNAUTHORIZED($msg) {
//$this->redirect('controller' => '???', 'action' => 'login');
//$this->render('/unauthorized');
$this->set('message', '<H2>' . $msg . '</H2>');
$this->render_empty();
}
function INTERNAL_ERROR($msg, $depth = 0) {
INTERNAL_ERROR($msg, false, $depth+1);
$this->render_empty();
$this->_stop();
}
function render_empty() {
$this->render('/empty');
echo $this->render('/empty');
$this->_stop();
}
}

View File

@@ -39,7 +39,7 @@ App::import('Core', 'Helper');
class AppHelper extends Helper {
function url($url = null, $full = false) {
foreach(array('admin_route', 'dev_route') AS $mod) {
foreach(array('sand_route', 'dev_route') AS $mod) {
if (isset($this->params[$mod]) && is_array($url) && !isset($url[$mod]))
$url[$mod] = $this->params[$mod];
}

View File

@@ -42,6 +42,10 @@ class AppModel extends Model {
var $useNullForEmpty = true;
var $formatDateFields = true;
// Loaded related models with no association
var $knows = array();
var $app_knows = array('Option');
// Default Log Level, if not specified at the function level
var $default_log_level = 5;
@@ -58,16 +62,35 @@ class AppModel extends Model {
var $max_log_level;
// REVISIT <AP>: 20090730
// Why is this constructor crashing?
// Clearly it's in some sort of infinite
// loop, but it seems the correct way
// to have a constructor call the parent...
/**************************************************************************
**************************************************************************
**************************************************************************
* function: __construct
*/
function __construct($id = false, $table = null, $ds = null) {
parent::__construct($id, $table, $ds);
$this->knows = array_merge($this->app_knows, $this->knows);
//$this->pr(1, array('knows' => $this->knows));
foreach ($this->knows as $alias => $modelName) {
if (is_numeric($alias)) {
$alias = $modelName;
}
// Don't overwrite any existing alias
if (!empty($this->{$alias}) || get_class($this) == $alias)
continue;
$model = array('class' => $modelName, 'alias' => $alias);
if (PHP5) {
$this->{$alias} = ClassRegistry::init($model);
} else {
$this->{$alias} =& ClassRegistry::init($model);
}
}
}
/* function __construct() { */
/* parent::__construct(); */
/* $this->prClassLevel(5, 'Model'); */
/* } */
/**************************************************************************
**************************************************************************
@@ -81,7 +104,8 @@ class AppModel extends Model {
$caller = array_shift($trace);
$caller = array_shift($trace);
if (empty($class))
$class = $caller['class'];
$class = get_class($this);
$this->pr(50, compact('class', 'level'));
$this->class_log_level[$class] = $level;
}
@@ -90,9 +114,10 @@ class AppModel extends Model {
$caller = array_shift($trace);
$caller = array_shift($trace);
if (empty($class))
$class = $caller['class'];
$class = get_class($this);
if (empty($function))
$function = $caller['function'];
$this->pr(50, compact('class', 'function', 'level'));
$this->function_log_level["{$class}-{$function}"] = $level;
}
@@ -280,7 +305,9 @@ class AppModel extends Model {
if (preg_match("/^_/", $name) && !$all)
unset($vars[$name]);
}
pr($vars);
//$vars['class'] = get_class_vars(get_class($this));
$this->pr(1, $vars);
}
@@ -480,9 +507,9 @@ class AppModel extends Model {
return date('Y-m-d', strtotime($dateString));
}
function INTERNAL_ERROR($msg, $depth = 0) {
INTERNAL_ERROR($msg, false, $depth+1);
echo $this->requestAction(array('controller' => 'accounts',
function INTERNAL_ERROR($msg, $depth = 0, $force_stop = false) {
INTERNAL_ERROR($msg, $force_stop, $depth+1);
echo $this->requestAction(array('controller' => 'util',
'action' => 'render_empty'),
array('return', 'bare' => false)
);

5
site/build_devbox.cmd Normal file
View File

@@ -0,0 +1,5 @@
@echo off
mysqldump --user=pmgr --password=pmgruser --opt property_manager > H:\pmgr_dev.sql
mysql --user=pmgr --password=pmgruser --database=pmgr_dev < H:\pmgr_dev.sql
del H:\pmgr_dev.sql
echo Build Complete!

5
site/build_sandbox.cmd Normal file
View File

@@ -0,0 +1,5 @@
@echo off
mysqldump --user=pmgr --password=pmgruser --opt property_manager > H:\pmgr_sand.sql
mysql --user=pmgr --password=pmgruser --database=pmgr_sand < H:\pmgr_sand.sql
del H:\pmgr_sand.sql
echo Build Complete!

View File

@@ -32,7 +32,36 @@
*
*/
function _box($type) {
static $box = array('type' => null, 'test' => array());
if (!isset($box['type']) && !isset($box['test'][$type])) {
$r = Router::requestRoute();
/* if (!preg_match("/gridData/", $_SERVER['REQUEST_URI'])) { */
/* print("<PRE>Route:\n");print_r($r);print("\n</PRE>\n"); */
/* } */
$box['test'][$type] = !empty($r[3]["${type}_route"]);
if ($box['test'][$type])
$box['type'] = $type;
}
return $box['type'] == $type;
}
function sandbox() { return _box('sand'); }
function devbox() { return _box('dev'); }
function server_request_var($var) {
if (preg_match("/^HTTP_ACCEPT|REMOTE_PORT/", $var))
return false;
return (preg_match("/^HTTP|REQUEST|REMOTE/", $var));
}
function INTERNAL_ERROR($message, $exit = true, $drop = 0) {
$O = new Object();
for ($i=0; $i<3; ++$i) {
$O->log(str_repeat("\\", 80));
$O->log(str_repeat("/", 80));
}
$O->log("INTERNAL ERROR: $message");
echo '<DIV class="internal-error" style="color:#000; background:#c22; padding:0.5em 1.5em 0.5em 1.5em;">' . "\n";
echo '<H1 style="color:#000; margin-bottom:0.2em; font-size:2em;">INTERNAL ERROR:</H1>' . "\n";
echo '<H2 style="color:#000; margin-top:0; margin-left:1.5em; font-size:1.5em">' . $message . '</H2>' . "\n";
@@ -40,8 +69,10 @@ function INTERNAL_ERROR($message, $exit = true, $drop = 0) {
echo '<BR>It is a problem within the application itself and should be reported to the administrator.</H4>' . "\n";
// Print out the entire stack trace
$O->log(str_repeat("-", 30));
$O->log("Stack:");
echo '<HR style="margin-top:1.0em; margin-bottom:0.5em;">' . "\nStack Trace:\n";
echo '<OL style="margin-left:1.5em";>' . "\n";
echo '<OL style="margin-top:0.5em; margin-left:0.0em";>' . "\n";
$trace = array_slice(debug_backtrace(false), $drop);
for ($i = 0; $i < count($trace); ++$i) {
$bline = $trace[$i]['line'];
@@ -57,14 +88,36 @@ function INTERNAL_ERROR($message, $exit = true, $drop = 0) {
$bclas = null;
}
$O->log(" $bfile:$bline (" . ($bclas ? "$bclas::$bfunc" : "entry point") . ")");
echo("<LI>$bfile:$bline (" . ($bclas ? "$bclas::$bfunc" : "entry point") . ")</LI>\n");
}
echo "</OL>\n";
$O->log(str_repeat("-", 30));
$O->log("HTTP Request:");
echo '<HR style="margin-top:1.0em; margin-bottom:0.5em;">' . "\nHTTP Request:\n";
echo '<P><PRE style="color:#000; background:#c22;">' . "\n";
print_r($_REQUEST);
echo "\n</PRE>\n";
echo '<UL style="margin-top:0.5em; margin-left:0.0em";>' . "\n";
foreach($_REQUEST AS $k => $v) {
$O->log(sprintf(" %-20s => %s", $k, $v));
echo("<LI>$k =&gt; $v</LI>\n");
}
echo "</UL>\n";
$O->log(str_repeat("-", 30));
$O->log("Server:");
$SRV = array_intersect_key($_SERVER, array_flip(array_filter(array_keys($_SERVER), 'server_request_var')));
echo '<HR style="margin-top:1.0em; margin-bottom:0.5em;">' . "\nServer:\n";
echo '<UL style="margin-top:0.5em; margin-left:0.0em";>' . "\n";
foreach($SRV AS $k => $v) {
if ($k == 'REQUEST_TIME')
$v = date('c', $v);
$O->log(sprintf(" %-20s => %s", $k, $v));
echo("<LI>$k =&gt; $v</LI>\n");
}
echo "</UL>\n";
echo '<HR style="margin-top:1.0em; margin-bottom:0.5em;">' . "\n";
echo date('c') . "<BR>\n";
echo '</DIV>';
if ($exit)

View File

@@ -12,7 +12,9 @@ class DATABASE_CONFIG {
);
function __construct() {
if (preg_match("%^/[^/]*sand/%", $_SERVER['REQUEST_URI']))
if (devbox())
$this->default['database'] = 'pmgr_dev';
if (sandbox())
$this->default['database'] = 'pmgr_sand';
}
}

View File

@@ -37,19 +37,39 @@ $default_path = array('controller' => 'maps', 'action' => 'view', '1');
Router::connect('/', $default_path);
/*
* Route for admin functionality
* Route for sandbox functionality
*/
Router::connect('/admin',
array('admin_route' => true) + $default_path);
Router::connect('/admin/:controller/:action/*',
array('admin_route' => true, 'action' => null));
Router::connect('/sand',
array('sand_route' => true) + $default_path);
Router::connect('/sand/:controller/:action/*',
array('sand_route' => true, 'action' => null));
/* Unfortunately, for some reason we need an extra route to solve
* a bug with form generation. When $this->data is set by the
* controller, and a URL is generated by the FormHelper, this
* route is required to ensure the form action is correct. An
* example of a broken page is for /customers/edit/XX. It appears
* the page location uses the route above, it's only URL generation
* that seems to be broken.
*/
Router::connect('/sand/:controller/:action/:id/*',
array('sand_route' => true,'action' => null, 'id'=>null));
/*
* Route for development functionality
* Route for developement functionality
*/
Router::connect('/dev',
array('dev_route' => true) + $default_path);
Router::connect('/dev/:controller/:action/*',
array('dev_route' => true, 'action' => null));
/* Unfortunately, for some reason we need an extra route to solve
* a bug with form generation. When $this->data is set by the
* controller, and a URL is generated by the FormHelper, this
* route is required to ensure the form action is correct. An
* example of a broken page is for /customers/edit/XX. It appears
* the page location uses the route above, it's only URL generation
* that seems to be broken.
*/
Router::connect('/dev/:controller/:action/:id/*',
array('dev_route' => true,'action' => null, 'id'=>null));
?>

View File

@@ -2,8 +2,6 @@
class AccountsController extends AppController {
var $uses = array('Account', 'LedgerEntry');
/**************************************************************************
**************************************************************************
@@ -100,9 +98,8 @@ class AccountsController extends AppController {
$conditions[] = array('Account.type' => strtoupper($params['action']));
}
// REVISIT <AP>: 20090811
// No security issues have been worked out yet
$conditions[] = array('Account.level >=' => 10);
$conditions[] = array('Account.level >=' =>
$this->Permission->level('controller.accounts'));
return $conditions;
}
@@ -183,9 +180,8 @@ class AccountsController extends AppController {
('order' => array('CloseTransaction.stamp' => 'DESC'))),
),
'conditions' => array(array('Account.id' => $id),
// REVISIT <AP>: 20090811
// No security issues have been worked out yet
array('Account.level >=' => 10),
array('Account.level >=' =>
$this->Permission->level('controller.accounts')),
),
)
);

View File

@@ -2,6 +2,12 @@
class CustomersController extends AppController {
// DEBUG FUNCTION ONLY!
// Call without id to update ALL customers
function force_update($id = null) {
$this->Customer->update($id);
$this->redirect(array('action'=>'index'));
}
/**************************************************************************
**************************************************************************
@@ -23,9 +29,9 @@ class CustomersController extends AppController {
array('controller' => 'customers', 'action' => 'all'), null,
'CONTROLLER');
$this->addSideMenuLink('New Customer',
array('controller' => 'customers', 'action' => 'add'), null,
'ACTION', $this->new_area);
/* $this->addSideMenuLink('New Customer', */
/* array('controller' => 'customers', 'action' => 'add'), null, */
/* 'CONTROLLER', $this->new_area); */
}

View File

@@ -34,6 +34,9 @@ class DoubleEntriesController extends AppController {
array('contain' => array('Ledger' => array('Account')),
'conditions' => array('DebitEntry.id' => $entry['DebitEntry']['id']),
));
$entry['Ledger']['link'] =
$entry['Ledger']['Account']['level'] >=
$this->Permission->level('controller.accounts');
$entry['DebitLedger'] = $entry['Ledger'];
unset($entry['Ledger']);
@@ -42,6 +45,9 @@ class DoubleEntriesController extends AppController {
array('contain' => array('Ledger' => array('Account')),
'conditions' => array('CreditEntry.id' => $entry['CreditEntry']['id']),
));
$entry['Ledger']['link'] =
$entry['Ledger']['Account']['level'] >=
$this->Permission->level('controller.accounts');
$entry['CreditLedger'] = $entry['Ledger'];
unset($entry['Ledger']);

View File

@@ -394,6 +394,10 @@ class LeasesController extends AppController {
$this->set(compact('default_late'));
if ($type === 'move-in') {
// Make sure we have a valid lease that we're moving in
if (empty($lease))
$this->redirect(array('action' => 'index'));
$movein = array();
$movein['time'] = strtotime($lease['Lease']['movein_date']);
$movein['effective_time'] = strtotime($lease['Lease']['movein_date']);

View File

@@ -117,8 +117,12 @@ class LedgerEntriesController extends AppController {
function gridDataPostProcessLinks(&$params, &$model, &$records, $links) {
$links['LedgerEntry'] = array('id');
$links['Transaction'] = array('id');
$links['Ledger'] = array('id');
$links['Account'] = array('controller' => 'accounts', 'name');
// REVISIT <AP>: 20090827
// Need to take 'level' into account
if ($this->Permission->allow('controller.accounts')) {
$links['Ledger'] = array('id');
$links['Account'] = array('name');
}
$links['Tender'] = array('name');
return parent::gridDataPostProcessLinks($params, $model, $records, $links);
}
@@ -144,12 +148,8 @@ class LedgerEntriesController extends AppController {
array('fields' => array('id', 'sequence', 'name'),
'Account' =>
array('fields' => array('id', 'name', 'type'),
'conditions' =>
// REVISIT <AP>: 20090811
// No security issues have been worked out yet
array('Account.level >=' => 5),
),
),
),
),
'Tender' =>
array('fields' => array('id', 'name'),

View File

@@ -86,9 +86,8 @@ class LedgersController extends AppController {
$conditions[] = array('Ledger.close_transaction_id !=' => null);
}
// REVISIT <AP>: 20090811
// No security issues have been worked out yet
$conditions[] = array('Account.level >=' => 10);
$conditions[] = array('Account.level >=' =>
$this->Permission->level('controller.accounts'));
return $conditions;
}
@@ -107,8 +106,12 @@ class LedgersController extends AppController {
}
function gridDataPostProcessLinks(&$params, &$model, &$records, $links) {
$links['Ledger'] = array('name');
$links['Account'] = array('name');
// REVISIT <AP>: 20090827
// Need to take 'level' into account
if ($this->Permission->allow('controller.accounts')) {
$links['Ledger'] = array('sequence');
$links['Account'] = array('name');
}
return parent::gridDataPostProcessLinks($params, $model, $records, $links);
}
@@ -128,9 +131,8 @@ class LedgersController extends AppController {
'Account',
),
'conditions' => array(array('Ledger.id' => $id),
// REVISIT <AP>: 20090811
// No security issues have been worked out yet
array('Account.level >=' => 10),
array('Account.level >=' =>
$this->Permission->level('controller.accounts')),
),
)
);

View File

@@ -47,7 +47,17 @@ class StatementEntriesController extends AppController {
if (!empty($params['post']['custom']['statement_entry_id'])) {
$link['ChargeEntry'] = array();
$link['DisbursementEntry'] = array();
// This query actually represents a union...
// Unpaid Charge/Surplus: ChargeID - NULL; DisbursementID - NULL
// Paid Charge/Refund: ChargeID - NULL; DisbursementID - !NULL
// Disbursement/Reversal: ChargeID - !NULL; DisbursementID - NULL
// <EMPTY SET>: ChargeID - !NULL; DisbursementID - !NULL
//
// The query is really slow unless we add the `id` condition to the join.
// A cleaner query would be nice, but we must work within the Cake framework.
$link['DisbursementEntry'] = array('conditions' =>
'`DisbursementEntry`.`id` = '
. $params['post']['custom']['statement_entry_id']);
}
return array('link' => $link);
@@ -108,11 +118,10 @@ class StatementEntriesController extends AppController {
if (isset($customer_id))
$conditions[] = array('StatementEntry.customer_id' => $customer_id);
if (isset($statement_entry_id)) {
if (isset($statement_entry_id))
$conditions[] = array('OR' =>
array(array('ChargeEntry.id' => $statement_entry_id),
array('DisbursementEntry.id' => $statement_entry_id)));
}
if ($params['action'] === 'unreconciled') {
$query = array('conditions' => $conditions);
@@ -132,7 +141,10 @@ class StatementEntriesController extends AppController {
function gridDataPostProcessLinks(&$params, &$model, &$records, $links) {
$links['StatementEntry'] = array('id');
$links['Transaction'] = array('id');
$links['Account'] = array('name');
// REVISIT <AP>: 20090827
// Need to take 'level' into account
if ($this->Permission->allow('controller.accounts'))
$links['Account'] = array('name');
$links['Customer'] = array('name');
$links['Lease'] = array('number');
$links['Unit'] = array('name');
@@ -253,15 +265,12 @@ class StatementEntriesController extends AppController {
('first',
array('contain' => array
('Transaction' => array('fields' => array('id', 'type', 'stamp')),
'Account' => array('id', 'name', 'type'),
'Account' => array('id', 'name', 'type', 'level'),
'Customer' => array('fields' => array('id', 'name')),
'Lease' => array('fields' => array('id', 'number')),
),
'conditions' => array(array('StatementEntry.id' => $id),
// REVISIT <AP>: 20090811
// No security issues have been worked out yet
array('Account.level >=' => 5)
),
));
@@ -270,6 +279,10 @@ class StatementEntriesController extends AppController {
$this->redirect(array('controller' => 'accounts', 'action'=>'index'));
}
$entry['Account']['link'] =
$entry['Account']['level'] >=
$this->Permission->level('controller.accounts');
$stats = $this->StatementEntry->stats($id);
if (in_array(strtoupper($entry['StatementEntry']['type']), $this->StatementEntry->debitTypes()))

View File

@@ -62,7 +62,7 @@ class TendersController extends AppController {
function gridDataPostProcessLinks(&$params, &$model, &$records, $links) {
$links['Tender'] = array('name', 'id');
$links['Customer'] = array('name');
$links['TenderType'] = array('name');
//$links['TenderType'] = array('name');
return parent::gridDataPostProcessLinks($params, $model, $records, $links);
}

View File

@@ -48,9 +48,9 @@ class TransactionsController extends AppController {
function invoice() { $this->gridView('Invoices'); }
function receipt() { $this->gridView('Receipts'); }
function deposit() {
$this->addSideMenuLink('New Deposit',
array('controller' => 'tenders', 'action' => 'deposit'), null,
'ACTION', $this->new_area);
/* $this->addSideMenuLink('New Deposit', */
/* array('controller' => 'tenders', 'action' => 'deposit'), null, */
/* 'CONTROLLER', $this->new_area); */
$this->gridView('Deposits');
}
@@ -95,10 +95,6 @@ class TransactionsController extends AppController {
if (in_array($params['action'], array('invoice', 'receipt', 'deposit')))
$conditions[] = array('Transaction.type' => strtoupper($params['action']));
// REVISIT <AP>: 20090811
// No security issues have been worked out yet
$conditions[] = array('Account.level >=' => 5);
return $conditions;
}
@@ -116,7 +112,7 @@ class TransactionsController extends AppController {
* - handles the creation of a charge invoice
*/
function postInvoice() {
function postInvoice($redirect = true) {
if (!$this->RequestHandler->isPost()) {
echo('<H2>THIS IS NOT A POST FOR SOME REASON</H2>');
return;
@@ -131,6 +127,17 @@ class TransactionsController extends AppController {
die("<H1>INVOICE FAILED</H1>");
}
if ($redirect) {
if (!empty($this->data['Customer']['id']))
$this->redirect(array('controller' => 'customers',
'action' => 'receipt',
$this->data['Customer']['id']));
else
$this->redirect(array('controller' => 'leases',
'action' => 'view',
$this->data['Lease']['id']));
}
$this->layout = null;
$this->autoLayout = false;
$this->autoRender = false;
@@ -144,7 +151,7 @@ class TransactionsController extends AppController {
* - handles the creation of a receipt
*/
function postReceipt() {
function postReceipt($redirect = true) {
if (!$this->RequestHandler->isPost()) {
echo('<H2>THIS IS NOT A POST FOR SOME REASON</H2>');
return;
@@ -168,6 +175,11 @@ class TransactionsController extends AppController {
die("<H1>RECEIPT FAILED</H1>");
}
if ($redirect)
$this->redirect(array('controller' => 'customers',
'action' => 'view',
$this->data['Customer']['id']));
$this->layout = null;
$this->autoLayout = false;
$this->autoRender = false;
@@ -280,7 +292,7 @@ class TransactionsController extends AppController {
$this->Session->setFlash(__('Unable to Create Deposit', true));
$this->redirect(array('controller' => 'tenders', 'action'=>'deposit'));
}
// Present the deposit slip to the user
$this->redirect(array('controller' => 'transactions',
'action' => 'deposit_slip',
@@ -381,9 +393,11 @@ class TransactionsController extends AppController {
* irreversibly destroys the data. It is not for normal use.
*/
function destroy($id = null) {
function destroy($id) {
$this->Transaction->id = $id;
$customer_id = $this->Transaction->field('customer_id');
$this->Transaction->destroy($id);
//$this->redirect(array('action' => 'index'));
$this->redirect(array('controller' => 'customers', 'action' => 'view', $customer_id));
}
@@ -399,28 +413,23 @@ class TransactionsController extends AppController {
('first',
array('contain' =>
array(// Models
'Account(id,name)',
'Account(id,name,level)',
'Ledger(id,sequence)',
'NsfTender(id,name)',
),
'conditions' => array(array('Transaction.id' => $id),
// REVISIT <AP>: 20090811
// No security issues have been worked out yet
array('OR' =>
array(array('Account.level >=' => 5),
array('Account.id' => null))),
),
));
// REVISIT <AP>: 20090815
// for debug purposes only (pr output)
$this->Transaction->stats($id);
if (empty($transaction)) {
$this->Session->setFlash(__('Invalid Item.', true));
$this->redirect(array('action'=>'index'));
}
$transaction['Account']['link'] =
$transaction['Account']['level'] >=
$this->Permission->level('controller.accounts');
if ($transaction['Transaction']['type'] === 'DEPOSIT')
$this->addSideMenuLink('View Slip',
array('action' => 'deposit_slip', $id), null,
@@ -432,7 +441,7 @@ class TransactionsController extends AppController {
"This may leave the database in an unstable state." .
" Do NOT do this unless you know what you're doing." .
" Proceed anyway?"),
'ACTION', $this->dev_area);
'ACTION', $this->admin_area);
// OK, prepare to render.
$title = 'Transaction #' . $transaction['Transaction']['id'];
@@ -449,15 +458,12 @@ class TransactionsController extends AppController {
*/
function deposit_slip($id) {
// Build a container for the deposit slip data
$deposit = array('types' => array());
$this->id = $id;
$deposit +=
$this->Transaction->find('first', array('contain' => false));
// Find the deposit transaction
$this->Transaction->id = $id;
$deposit = $this->Transaction->find('first', array('contain' => false));
// Get a summary of all forms of tender in the deposit
$result = $this->Transaction->find
$tenders = $this->Transaction->find
('all',
array('link' => array('DepositTender' =>
array('fields' => array(),
@@ -472,16 +478,17 @@ class TransactionsController extends AppController {
'group' => 'TenderType.id',
));
if (empty($result)) {
die();
// Verify the deposit exists, and that something was actually deposited
if (empty($deposit) || empty($tenders)) {
$this->Session->setFlash(__('Invalid Deposit.', true));
$this->redirect(array('action'=>'deposit'));
}
// Add the summary to our deposit slip data container
foreach ($result AS $type) {
$deposit['types'][$type['TenderType']['id']] =
$type['TenderType'] + $type[0];
$deposit['types'] = array();
foreach ($tenders AS $tender) {
$deposit['types'][$tender['TenderType']['id']] =
$tender['TenderType'] + $tender[0];
}
$deposit_total = 0;

View File

@@ -0,0 +1,76 @@
<?php
class UtilController extends AppController {
var $uses = array();
/**************************************************************************
**************************************************************************
**************************************************************************
* function: reset_data
* - Development function. TO BE DELETED
*/
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";
$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);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: rebuild_box
*/
function rebuild_box($type) {
$this->layout = null;
$this->autoLayout = false;
$this->autoRender = false;
Configure::write('debug', '0');
$script = preg_replace('%/webroot/index.php$%',
'/build_'.$type.'box.cmd',
$_SERVER['SCRIPT_FILENAME']);
// REVISIT <AP>: 20090828
// Just use system call
$handle = popen($script . ' 2>&1', 'r');
while (($read = fread($handle, 2096))) {
// Do nothing
}
pclose($handle);
$url = $_SERVER['HTTP_REFERER'];
if (empty($url))
$url = "/";
$this->redirect($url);
}
function rebuild_sandbox() { $this->rebuild_box('sand'); }
function rebuild_devbox() { $this->rebuild_box('dev'); }
/**************************************************************************
**************************************************************************
**************************************************************************
* function: logmsg
* - action to allow posting log message data
*/
function logmsg() {
}
}

View File

@@ -192,6 +192,13 @@ class Customer extends AppModel {
}
$id = $this->id;
// Appears that $this->save() "helpfully" choses to add in
// any missing data fields, populated with default values.
// So, after saving is complete, the fields 'lease_count',
// 'past_lease_count', and 'current_lease_count' have all
// been reset to zero. Gee, thanks Cake...
$this->update($id);
// Remove all associated Customer Contacts, as it ensures
// any entries deleted by the user actually get deleted
// in the system. We'll recreate the needed ones anyway.
@@ -247,10 +254,10 @@ class Customer extends AppModel {
return;
}
// REVISIT <AP>: 20090812
// updateLeaseCount is handled directly when needed.
// Should we simplify by just doing it anyway?
//$this->updateLeaseCount($id);
// updateLeaseCount is typically handled directly when needed.
// However, this function is used to _ensure_ customer info is
// current, so we're obligated to call it anyway.
$this->updateLeaseCount($id);
$current_leases =
$this->find('all',

View File

@@ -0,0 +1,21 @@
<?php
class DefaultOption extends AppModel {
var $belongsTo =
array('OptionValue',
);
function values($name = null) {
$this->prEnter(compact('name'));
$query = array();
$this->queryInit($query);
$query['link']['DefaultOption'] = array();
$query['link']['DefaultOption']['type'] = 'INNER';
$query['link']['DefaultOption']['fields'] = array();
return $this->prReturn($this->OptionValue->values($name, $query));
}
}

View File

@@ -0,0 +1,21 @@
<?php
class DefaultPermission extends AppModel {
var $belongsTo =
array('PermissionValue',
);
function values($name = null) {
$this->prEnter(compact('name'));
$query = array();
$this->queryInit($query);
$query['link']['DefaultPermission'] = array();
$query['link']['DefaultPermission']['type'] = 'INNER';
$query['link']['DefaultPermission']['fields'] = array();
return $this->prReturn($this->PermissionValue->values($name, $query));
}
}

38
site/models/group.php Normal file
View File

@@ -0,0 +1,38 @@
<?php
class Group extends AppModel {
var $hasMany =
array('GroupOption',
'Membership',
);
var $knows =
array('User',
'Site',
);
static $current_group_ids;
function currentGroupIds() {
if (empty(self::$current_group_ids))
self::$current_group_ids = $this->groupIds();
if (empty(self::$current_group_ids))
// We must force a stop here, since this is typically
// called very early on, and so will cause a recursive
// crash as we try to render the internal error and
// again stumble on this problem.
$this->INTERNAL_ERROR('INVALID MEMBERSHIP', 0, true);
return self::$current_group_ids;
}
function groupIds($user_id = null, $site_id = null) {
if (empty($user_id))
$user_id = $this->User->currentUserId();
if (empty($site_id))
$site_id = $this->Site->currentSiteId();
return $this->Membership->memberGroups($user_id, $site_id);
}
}

View File

@@ -0,0 +1,25 @@
<?php
class GroupOption extends AppModel {
var $belongsTo =
array('Group',
'OptionValue',
);
function values($ids, $name = null) {
$this->prEnter(compact('id', 'name'));
$query = array();
$this->queryInit($query);
$query['link']['GroupOption'] = array();
$query['link']['GroupOption']['fields'] = array();
$query['link']['GroupOption']['Group'] = array();
$query['link']['GroupOption']['Group']['fields'] = array();
$query['conditions'][] = array('Group.id' => $ids);
$query['order'][] = 'Group.rank';
return $this->prReturn($this->OptionValue->values($name, $query));
}
}

View File

@@ -0,0 +1,25 @@
<?php
class GroupPermission extends AppModel {
var $belongsTo =
array('Group',
'PermissionValue',
);
function values($ids, $name = null) {
$this->prEnter(compact('id', 'name'));
$query = array();
$this->queryInit($query);
$query['link']['GroupPermission'] = array();
$query['link']['GroupPermission']['fields'] = array();
$query['link']['GroupPermission']['Group'] = array();
$query['link']['GroupPermission']['Group']['fields'] = array();
$query['conditions'][] = array('Group.id' => $ids);
$query['order'][] = 'Group.rank';
return $this->prReturn($this->PermissionValue->values($name, $query));
}
}

View File

@@ -148,9 +148,11 @@ class Lease extends AppModel {
array('class' => 'StatementEntry',
'fields' => array(),
'conditions' => array
('SEx.effective_date = DATE_ADD(StatementEntry.through_date, INTERVAL 1 day)',
'SEx.lease_id = StatementEntry.lease_id',
('SEx.lease_id = StatementEntry.lease_id',
'SEx.type' => 'CHARGE',
'SEx.account_id' => $rent_account_id,
'SEx.reverse_transaction_id IS NULL',
'SEx.effective_date = DATE_ADD(StatementEntry.through_date, INTERVAL 1 day)',
),
),
),

View File

@@ -0,0 +1,37 @@
<?php
class Membership extends AppModel {
var $belongsTo =
array('User',
'Site',
'Group'
);
function memberGroups($user_id, $site_id) {
$this->prEnter(compact('user_id', 'site_id'));
$this->cacheQueries = true;
$groups = $this->find('all', array
('recursive' => -1,
'fields' => array('group_id'),
'conditions' => array(array('user_id' => $user_id),
array('site_id' => $site_id)),
));
$this->cacheQueries = false;
if (empty($groups))
return $this->prReturn(null);
$group_ids = array();
foreach ($groups AS $group)
$group_ids[] = $group['Membership']['group_id'];
return $this->prReturn($group_ids);
}
function memberOf($user_id, $site_id) {
$groups = $this->memberGroups($user_id, $site_id);
return (!empty($groups));
}
}

76
site/models/option.php Normal file
View File

@@ -0,0 +1,76 @@
<?php
class Option extends AppModel {
var $hasMany =
array('OptionValue',
);
var $knows =
array('User', 'Site', 'Group');
static $option_set = array();
function getAll($name, $force = false) {
/* $this->prClassLevel(30); */
/* //$this->OptionValue->prClassLevel(30); */
/* $this->Group->Membership->prClassLevel(30); */
/* $this->OptionValue->SiteOption->prClassLevel(30); */
/* $this->OptionValue->UserOption->prClassLevel(30); */
/* $this->OptionValue->GroupOption->prClassLevel(30); */
/* $this->OptionValue->DefaultOption->prClassLevel(30); */
$this->prEnter(compact('name'));
if (!empty(self::$option_set[$name]) && !$force)
return $this->prReturn(self::$option_set[$name]);
self::$option_set[$name] = array();
$site_id = $this->Site->currentSiteId();
$user_id = $this->User->currentUserId();
$group_ids = $this->Group->currentGroupIds();
/* $site_id = 2; */
/* $user_id = 4; */
/* $group_ids = $this->Group->groupIds($user_id, $site_id); */
if (!empty($site_id))
self::$option_set[$name] =
array_merge(self::$option_set[$name],
$this->OptionValue->SiteOption->values($site_id, $name));
if (!empty($user_id))
self::$option_set[$name] =
array_merge(self::$option_set[$name],
$this->OptionValue->UserOption->values($user_id, $name));
if (!empty($group_ids))
self::$option_set[$name] =
array_merge(self::$option_set[$name],
$this->OptionValue->GroupOption->values($group_ids, $name));
self::$option_set[$name] =
array_merge(self::$option_set[$name],
$this->OptionValue->DefaultOption->values($name));
return $this->prReturn(self::$option_set[$name]);
}
function get($name) {
$this->prEnter(compact('name'));
$values = $this->getAll($name);
if (empty($values))
return null;
return $this->prReturn($values[0]);
}
function enabled($name) {
$val = $this->get($name);
return (!empty($val));
}
function disabled($name) {
return (!$this->enabled($name));
}
}

View File

@@ -0,0 +1,35 @@
<?php
class OptionValue extends AppModel {
var $belongsTo =
array('Option',
);
var $hasMany =
array('UserOption',
'SiteOption',
'GroupOption',
'DefaultOption',
);
function values($name = null, $query = null) {
$this->prEnter(compact('name', 'query'));
$this->queryInit($query);
$query['link']['Option'] = array();
if (!empty($name)) {
$query['conditions'][] = array('Option.name' => $name);
$query['link']['Option']['fields'] = array();
}
$this->cacheQueries = true;
$values = array();
foreach ($this->find('all', $query) AS $result)
$values[] = $result['OptionValue']['value'];
$this->cacheQueries = false;
return $this->prReturn($values);
}
}

105
site/models/permission.php Normal file
View File

@@ -0,0 +1,105 @@
<?php
class Permission extends AppModel {
var $hasMany =
array('PermissionValue',
);
var $knows =
array('User', 'Site', 'Group');
static $permission_set = array();
function getAll($name, $force = false) {
/* $this->prClassLevel(30); */
/* $this->PermissionValue->prClassLevel(30); */
/* $this->Group->Membership->prClassLevel(30); */
/* $this->PermissionValue->SitePermission->prClassLevel(30); */
/* $this->PermissionValue->UserPermission->prClassLevel(30); */
/* $this->PermissionValue->GroupPermission->prClassLevel(30); */
/* $this->PermissionValue->DefaultPermission->prClassLevel(30); */
$this->prEnter(compact('name'));
if (!empty(self::$permission_set[$name]) && !$force)
return $this->prReturn(self::$permission_set[$name]);
self::$permission_set[$name] = array();
$site_id = $this->Site->currentSiteId();
$user_id = $this->User->currentUserId();
$group_ids = $this->Group->currentGroupIds();
/* $site_id = 1; */
/* $user_id = 2; */
/* $group_ids = $this->Group->groupIds($user_id, $site_id); */
if (empty($group_ids)) {
self::$permission_set[$name][$name][] = array('access' => 'DENY', 'level' => null);
$site_id = null;
$user_id = null;
}
if (!empty($site_id))
self::$permission_set[$name] =
array_merge(self::$permission_set[$name],
$this->PermissionValue->SitePermission->values($site_id, $name));
if (!empty($user_id))
self::$permission_set[$name] =
array_merge(self::$permission_set[$name],
$this->PermissionValue->UserPermission->values($user_id, $name));
if (!empty($group_ids)) {
self::$permission_set[$name] =
array_merge(self::$permission_set[$name],
$this->PermissionValue->GroupPermission->values($group_ids, $name));
self::$permission_set[$name] =
array_merge(self::$permission_set[$name],
$this->PermissionValue->DefaultPermission->values($name));
self::$permission_set[$name][] = array('access' => 'ALLOW', 'level' => null);
}
return $this->prReturn(self::$permission_set[$name]);
}
function get($name) {
$this->prEnter(compact('name'));
// REVISIT <AP>: 20090827
// This is a pretty crappy algorithm. How do we decide whether DENY really
// means DENY, or whether an ALLOW has priority.
// Oh well, it works for now...
$values = $this->getAll($name);
$result = array_shift($values);
foreach ($values AS $value)
if (empty($result['level']) || (!empty($value['level']) && $value['level'] < $result['level']))
$result['level'] = $value['level'];
if ($result['access'] !== 'ALLOW')
$result['level'] = 9999999;
return $this->prReturn($result);
}
function allow($name) {
$this->prEnter(compact('name'));
$result = $this->get($name);
return $this->prReturn($result['access'] === 'ALLOW');
}
function deny($name) {
$this->prEnter(compact('name'));
return $this->prReturn(!$this->allow($name));
}
function level($name) {
$this->prEnter(compact('name'));
$result = $this->get($name);
return $this->prReturn($result['level']);
}
}

View File

@@ -0,0 +1,36 @@
<?php
class PermissionValue extends AppModel {
var $belongsTo =
array('Permission',
);
var $hasMany =
array('UserPermission',
'SitePermission',
'GroupPermission',
'DefaultPermission',
);
function values($name = null, $query = null) {
$this->prEnter(compact('name', 'query'));
$this->queryInit($query);
$query['link']['Permission'] = array();
if (!empty($name)) {
$query['conditions'][] = array('Permission.name' => $name);
$query['link']['Permission']['fields'] = array();
}
$this->cacheQueries = true;
$values = array();
foreach ($this->find('all', $query) AS $result)
$values[] = array('access' => $result['PermissionValue']['access'],
'level' => $result['PermissionValue']['level']);
$this->cacheQueries = false;
return $this->prReturn($values);
}
}

View File

@@ -1,16 +1,37 @@
<?php
class Site extends AppModel {
var $name = 'Site';
var $validate = array(
'id' => array('numeric'),
'name' => array('notempty')
);
var $hasMany =
array('SiteArea',
'SiteOption',
'Membership',
);
var $hasMany = array(
'SiteArea',
'SiteOption',
);
static $current_site_id;
function currentSiteId() {
if (!empty(self::$current_site_id))
return self::$current_site_id;
// REVISIT <AP>: 20090827
// Must get the actual site
$code = 'VSS';
$site = $this->find
('first',
array('recursive' => -1,
'conditions' => compact('code')));
if (!empty($site['Site']['id']))
self::$current_site_id = $site['Site']['id'];
else
// We must force a stop here, since this is typically
// called very early on, and so will cause a recursive
// crash as we try to render the internal error and
// again stumble on this problem.
$this->INTERNAL_ERROR('UNKNOWN SITE', 0, true);
return self::$current_site_id;
}
}
?>

View File

@@ -0,0 +1,24 @@
<?php
class SiteOption extends AppModel {
var $belongsTo =
array('Site',
'OptionValue',
);
function values($id, $name = null) {
$this->prEnter(compact('id', 'name'));
$query = array();
$this->queryInit($query);
$query['link']['SiteOption'] = array();
$query['link']['SiteOption']['fields'] = array();
$query['link']['SiteOption']['Site'] = array();
$query['link']['SiteOption']['Site']['fields'] = array();
$query['conditions'][] = array('Site.id' => $id);
return $this->prReturn($this->OptionValue->values($name, $query));
}
}

View File

@@ -0,0 +1,24 @@
<?php
class SitePermission extends AppModel {
var $belongsTo =
array('Site',
'PermissionValue',
);
function values($id, $name = null) {
$this->prEnter(compact('id', 'name'));
$query = array();
$this->queryInit($query);
$query['link']['SitePermission'] = array();
$query['link']['SitePermission']['fields'] = array();
$query['link']['SitePermission']['Site'] = array();
$query['link']['SitePermission']['Site']['fields'] = array();
$query['conditions'][] = array('Site.id' => $id);
return $this->prReturn($this->PermissionValue->values($name, $query));
}
}

View File

@@ -294,7 +294,7 @@ class StatementEntry extends AppModel {
}
return $this->prReturn(array('entries' => $resultset,
'summary' => $this->stats(null, $query)));
'summary' => $this->stats(null, $query)));
}
@@ -483,14 +483,14 @@ class StatementEntry extends AppModel {
// Set the disbursement amount to the maximum amount
// possible without exceeding the charge or credit balance
$disbursement_amount = min($charge['balance'], $credit['balance']);
$disbursement_amount = round(min($charge['balance'], $credit['balance']), 2);
if (!isset($credit['applied']))
$credit['applied'] = 0;
$credit['applied'] += $disbursement_amount;
$credit['balance'] -= $disbursement_amount;
$credit['applied'] = round($credit['applied'] + $disbursement_amount, 2);
$credit['balance'] = round($credit['balance'] - $disbursement_amount, 2);
$this->pr(20, compact('credit'),
$this->pr(20, compact('credit', 'disbursement_amount'),
($credit['balance'] > 0 ? 'Utilized' : 'Exhausted') .
(empty($credit['receipt']) ? ' Credit' : ' Receipt'));
@@ -555,12 +555,12 @@ class StatementEntry extends AppModel {
}
// Adjust the charge balance to reflect the new disbursement
$charge['balance'] -= $disbursement_amount;
$charge['balance'] = round($charge['balance'] - $disbursement_amount, 2);
$this->pr(20, compact('charge', 'disbursement_amount'),
($charge['balance'] > 0 ? 'Unfinished' : 'Fully Paid') . ' Charge');
if ($charge['balance'] < 0)
die("HOW DID WE GET A NEGATIVE CHARGE AMOUNT?");
if ($charge['balance'] <= 0)
$this->pr(20, 'Fully Paid Charge');
}
// Break the $credit reference to avoid future problems
unset($credit);

View File

@@ -350,10 +350,14 @@ class Transaction extends AppModel {
if (isset($ids['transaction_id']))
$ids['deposit_id'] = $ids['transaction_id'];
if (!empty($ids['deposit_id']) && !empty($control['update_tender'])) {
$this->pr(21, array_intersect_key($ids, array('deposit_id'=>1))
+ array_intersect_key($data['control'], array('update_tender'=>1)));
if (!empty($ids['deposit_id']) && !empty($data['control']['update_tender'])) {
$this->pr(21, compact('tender_groups'));
foreach ($tender_groups AS $group => $tender_ids) {
$entry_id = $ids['entries'][$group]['DoubleEntry']['Entry2']['ledger_entry_id'];
$this->pr(10, compact('group', 'tender_ids', 'entry_id'));
$this->pr(19, compact('group', 'tender_ids', 'entry_id'));
$this->LedgerEntry->Tender->updateAll
(array('Tender.deposit_transaction_id' => $ids['deposit_id'],
'Tender.deposit_ledger_entry_id' => $entry_id),
@@ -530,6 +534,8 @@ class Transaction extends AppModel {
(in_array($transaction['type'], array('INVOICE', 'RECEIPT'))
&& empty($transaction['customer_id']))
) {
// REVISIT <AP>: 20090828; Callers are not yet able to handle errors
$this->INTERNAL_ERROR('Transaction verification failed');
return $this->prReturn(false);
}
@@ -545,6 +551,8 @@ class Transaction extends AppModel {
}
if (!empty($se) &&
!$this->StatementEntry->verifyStatementEntry($se)) {
// REVISIT <AP>: 20090828; Callers are not yet able to handle errors
$this->INTERNAL_ERROR('Transaction entry verification failed');
return $this->prReturn(false);
}
}
@@ -584,8 +592,11 @@ class Transaction extends AppModel {
// Save transaction to the database
$this->create();
if (!$this->save($transaction))
if (!$this->save($transaction)) {
// REVISIT <AP>: 20090828; Callers are not yet able to handle errors
$this->INTERNAL_ERROR('Failed to save Transaction');
return $this->prReturn(array('error' => true) + $ret);
}
$ret['transaction_id'] = $transaction['id'] = $this->id;
// Add the entries
@@ -661,6 +672,11 @@ class Transaction extends AppModel {
if (!empty($transaction['customer_id'])) {
$this->Customer->update($transaction['customer_id']);
}
if (!empty($ret['error']))
// REVISIT <AP>: 20090828; Callers are not yet able to handle errors
$this->INTERNAL_ERROR('Failed to save Transaction');
return $this->prReturn($ret);
}
@@ -681,8 +697,11 @@ class Transaction extends AppModel {
$this->prEnter(compact('control', 'transaction', 'entries', 'split'));
// Verify that we have a transaction
if (empty($transaction['id']))
if (empty($transaction['id'])) {
// REVISIT <AP>: 20090828; Callers are not yet able to handle errors
$this->INTERNAL_ERROR('Invalid Transaction ID for adding entries');
return $this->prReturn(array('error' => true));
}
// If the entries are not already split, do so now.
if ($split) {
@@ -742,6 +761,10 @@ class Transaction extends AppModel {
}
}
if (!empty($ret['error']))
// REVISIT <AP>: 20090828; Callers are not yet able to handle errors
$this->INTERNAL_ERROR('Failed to save Transaction Entries');
return $this->prReturn($ret);
}
@@ -762,8 +785,11 @@ class Transaction extends AppModel {
// Verify that we have a transaction and entries
if (empty($transaction) ||
(empty($entries) && empty($control['allow_no_entries'])))
(empty($entries) && empty($control['allow_no_entries']))) {
// REVISIT <AP>: 20090828; Callers are not yet able to handle errors
$this->INTERNAL_ERROR('Split Entries failed to validate');
return $this->prReturn(array('error' => true));
}
// set ledger ID as the current ledger of the specified account
if (empty($transaction['ledger_id']))
@@ -972,8 +998,11 @@ class Transaction extends AppModel {
));
$this->pr(20, compact('nsf_ledger_entry'));
if (!$nsf_ledger_entry)
if (!$nsf_ledger_entry) {
// REVISIT <AP>: 20090828; Callers are not yet able to handle errors
$this->INTERNAL_ERROR('Failed to locate NSF ledger entry');
return $this->prReturn(array('error' => true) + $ret);
}
// Build a transaction to adjust all of the statement entries
$rollback =

39
site/models/user.php Normal file
View File

@@ -0,0 +1,39 @@
<?php
class User extends AppModel {
var $hasMany =
array('UserOption',
'Membership',
);
static $current_user_id;
function currentUser() {
if (!empty($_SERVER['REMOTE_USER']))
return $_SERVER['REMOTE_USER'];
return null;
}
function currentUserId() {
if (!empty(self::$current_user_id))
return self::$current_user_id;
$user = $this->find
('first',
array('recursive' => -1,
'conditions' => array('login' => $this->currentUser())));
if (!empty($user['User']['id']))
self::$current_user_id = $user['User']['id'];
else
// We must force a stop here, since this is typically
// called very early on, and so will cause a recursive
// crash as we try to render the internal error and
// again stumble on this problem.
$this->INTERNAL_ERROR('UNKNOWN USER', 0, true);
return self::$current_user_id;
}
}

View File

@@ -0,0 +1,24 @@
<?php
class UserOption extends AppModel {
var $belongsTo =
array('User',
'OptionValue',
);
function values($id, $name = null) {
$this->prEnter(compact('id', 'name'));
$query = array();
$this->queryInit($query);
$query['link']['UserOption'] = array();
$query['link']['UserOption']['fields'] = array();
$query['link']['UserOption']['User'] = array();
$query['link']['UserOption']['User']['fields'] = array();
$query['conditions'][] = array('User.id' => $id);
return $this->prReturn($this->OptionValue->values($name, $query));
}
}

View File

@@ -0,0 +1,24 @@
<?php
class UserPermission extends AppModel {
var $belongsTo =
array('User',
'PermissionValue',
);
function values($id, $name = null) {
$this->prEnter(compact('id', 'name'));
$query = array();
$this->queryInit($query);
$query['link']['UserPermission'] = array();
$query['link']['UserPermission']['fields'] = array();
$query['link']['UserPermission']['User'] = array();
$query['link']['UserPermission']['User']['fields'] = array();
$query['conditions'][] = array('User.id' => $id);
return $this->prReturn($this->PermissionValue->values($name, $query));
}
}

View File

@@ -178,20 +178,8 @@ echo $this->element('statement_entries', array
<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' });
datepicker('TxFromDate');
datepicker('TxThroughDate');
resetForm();
});
--></script>

View File

@@ -28,17 +28,61 @@ Configure::write('debug', '0');
// other available options:
//clearForm: true, // clear all form fields after successful submit
//resetForm: true, // reset the form after successful submit
url: "<?php echo $html->url(array('controller' => 'transactions',
'action' => 'postReceipt', 0)); ?>"
};
// bind form using 'ajaxForm'
$('#receipt-form').ajaxForm(options);
if ($('#receipt-form').ajaxForm != null)
$('#receipt-form').ajaxForm(options);
else
$('#repeat, label[for=repeat]').remove();
});
// pre-submit callback
function verifyRequest(formData, jqForm, options) {
function verifyRequest(formData, jqForm, options) {
//$("#debug").html('');
for (var i = 0; i < formData.length; ++i) {
//$("#debug").append(i + ') ' + dump(formData[i]) + '<BR>');
if (formData[i]['name'] == "data[Customer][id]" &&
!(formData[i]['value'] > 0)) {
//$("#debug").append('<P>Missing Customer ID');
alert("Please select a customer first.");
return false;
}
if (formData[i]['name'] == "data[Transaction][stamp]" &&
formData[i]['value'] == '') {
//$("#debug").append('<P>Bad Stamp');
if (formData[i]['value'] != '')
alert(formData[i]['value'] + " is not valid date stamp. Please correct it.");
else
alert("Please enter a valid date stamp first.");
return false;
}
// Terrible way to accomplish this...
for (var j = 0; j < 20; ++j) {
if (formData[i]['name'] == "data[Entry]["+j+"][amount]") {
var val = formData[i]['value'].replace(/\$/,'');
//$("#debug").append('<P>Bad Amount');
if (!(val > 0)) {
if (formData[i]['value'] == '')
alert("Please enter an amount first.");
else
alert('"'+formData[i]['value']+'"' + " is not valid amount. Please correct it.");
return false;
}
}
}
}
//$("#debug").append('OK');
//return false;
$('#results').html('Working <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;
}
@@ -363,13 +407,9 @@ Configure::write('debug', '0');
<script type="text/javascript"><!--
$(document).ready(function(){
$("#TransactionStamp")
.attr('autocomplete', 'off')
.datepicker({ constrainInput: true,
numberOfMonths: [1, 1],
showCurrentAtPos: 0,
dateFormat: 'mm/dd/yy' });
datepicker('TransactionStamp');
$("#customer-id").val(0);
$("#receipt-customer-name").html("INTERNAL ERROR");
$("#receipt-balance").html("INTERNAL ERROR");
$("#receipt-charges-caption").html("Outstanding Charges");

View File

@@ -56,14 +56,18 @@ foreach ($ledgers AS $type => $ledger) {
/* array('controller' => 'entries', */
/* 'action' => 'view', */
/* $entries[$type]['id']))); */
$rows[] = array('Account', $html->link($ledger['Account']['name'],
array('controller' => 'accounts',
'action' => 'view',
$ledger['Account']['id'])));
$rows[] = array('Ledger', $html->link('#' . $ledger['sequence'],
array('controller' => 'ledgers',
'action' => 'view',
$ledger['id'])));
$rows[] = array('Account', ($ledger['link']
? $html->link($ledger['Account']['name'],
array('controller' => 'accounts',
'action' => 'view',
$ledger['Account']['id']))
: $ledger['Account']['name']));
$rows[] = array('Ledger', ($ledger['link']
? $html->link('#' . $ledger['sequence'],
array('controller' => 'ledgers',
'action' => 'view',
$ledger['id']))
: '#' . $ledger['sequence']));
$rows[] = array('Amount', FormatHelper::currency($entries[$type]['amount']));
//$rows[] = array('Effect', $ledger['Account']['ftype'] == $type ? 'INCREASE' : 'DECREASE');

View File

@@ -4,8 +4,8 @@
$cols = array();
$cols['Relationship'] = array('index' => 'ContactsCustomer.type', 'formatter' => 'enum');
$cols['Name'] = array('index' => 'Contact.display_name', 'formatter' => 'longname');
$cols['Last Name'] = array('index' => 'Contact.last_name', 'formatter' => 'longname');
$cols['First Name'] = array('index' => 'Contact.first_name', 'formatter' => 'longname');
$cols['Last Name'] = array('index' => 'Contact.last_name', 'formatter' => 'name');
$cols['First Name'] = array('index' => 'Contact.first_name', 'formatter' => 'name');
$cols['Company'] = array('index' => 'Contact.company_name', 'formatter' => 'longname');
$cols['Comment'] = array('index' => 'Contact.comment', 'formatter' => 'comment');

View File

@@ -148,8 +148,14 @@ foreach ($jqGridColumns AS $header => &$col) {
// No special formatting for name
unset($col['formatter']);
}
elseif ($col['formatter'] === 'enum') {
elseif (preg_match("/^(long|short)?enum$/",
$col['formatter'], $matches)) {
$default['width'] = 60;
if (!empty($matches[1]) && $matches[1] === 'long')
$default['width'] *= 1.5;
if (!empty($matches[1]) && $matches[1] === 'short')
$default['width'] *= 0.7;
//$default['align'] = 'right';
// No special formatting for enum
@@ -166,7 +172,8 @@ foreach ($jqGridColumns AS $header => &$col) {
// Just a rough approximation to ensure columns
// are wide enough to fully display their header.
$min_width = strlen($header) * 10;
$min_width = strlen($header) * 7;
$min_width = 0; // REVISIT <AP>: 20090829; if/while jqGrid is fixed width
if ((!isset($default['width']) || $default['width'] < $min_width) && !$default['force'])
$default['width'] = $min_width;
}
@@ -239,6 +246,7 @@ $jqGrid_setup = array_merge
'colNames' => array_keys($jqGridColumns),
'colModel' => array('--special' => $jqGridColumns),
'height' => $height,
'width' => 700,
'rowNum' => $limit,
'rowList' => $limitOptions,
'sortname' => $sortname,
@@ -258,50 +266,46 @@ $jqGrid_setup = array_merge
// to kick this thing off.
?>
<?php if ($first_grid): ?>
<script type="text/javascript"><!--
var currencyFormatter = function(cellval, opts, rowObject) {
if (!cellval)
return "";
return fmtCurrency(cellval);
}
var percentageFormatter = function(cellval, opts, rowObject) {
var precision;
if (typeof(opts.colModel) != 'undefined' &&
typeof(opts.colModel.formatoptions) != 'undefined' &&
typeof(opts.colModel.formatoptions.precision) != 'undefined')
precision = opts.colModel.formatoptions.precision;
else
precision = 0;
amount = cellval.toString().replace(/\%/g,'');
amount = (amount*100).toFixed(precision);
return amount+'%';
}
var idFormatter = function(cellval, opts, rowObject) {
if (!cellval)
return cellval;
return '#'+cellval;
}
--></script>
<?php endif; ?>
<DIV ID="<?php echo $grid_div_id; ?>" CLASS="<?php echo $grid_div_class; ?>">
<table id="<?php echo $grid_id; ?>" class="scroll"></table>
<div id="<?php echo $grid_id; ?>-pager" class="scroll" style="text-align:right"></div>
<script type="text/javascript"><!--
jQuery(document).ready(function(){
currencyFormatter = function(cellval, opts, rowObject) {
if (!cellval)
return "";
return fmtCurrency(cellval);
}
percentageFormatter = function(cellval, opts, rowObject) {
var precision;
if (typeof(opts.colModel) != 'undefined' &&
typeof(opts.colModel.formatoptions) != 'undefined' &&
typeof(opts.colModel.formatoptions.precision) != 'undefined')
precision = opts.colModel.formatoptions.precision;
else
precision = 0;
amount = cellval.toString().replace(/\%/g,'');
amount = (amount*100).toFixed(precision);
return amount+'%';
}
idFormatter = function(cellval, opts, rowObject) {
if (!cellval)
return cellval;
return '#'+cellval;
}
jQuery('#<?php echo $grid_id; ?>').jqGrid(
<?php echo FormatHelper::phpVarToJavascript($jqGrid_setup); ?>
).navGrid('#<?php echo $grid_id; ?>-pager',
{ view:false,
edit:false,
add:false,
del:false,
search:true,
refresh:true});
<?php echo FormatHelper::phpVarToJavascript($jqGrid_setup) . "\n"; ?>
).navGrid('#<?php echo $grid_id; ?>-pager', { view:false,edit:false,add:false,del:false,search:true,refresh:true});
});
--></script>
<?php
if (count($search_fields) > 0) {
echo('<div>Search By:<BR>' . "\n");

View File

@@ -3,22 +3,23 @@
// Define the table columns
$cols = array();
$cols['Lease'] = array('index' => 'Lease.number', 'formatter' => 'id');
$cols['Unit'] = array('index' => 'Unit.name', 'width' => '50', 'align' => 'center');
$cols['Unit'] = array('index' => 'Unit.name', 'formatter' => 'shortname', 'align' => 'center');
$cols['Customer'] = array('index' => 'Customer.name', 'formatter' => 'longname');
$cols['Rent'] = array('index' => 'Lease.rent', 'formatter' => 'currency', 'hiddenz' => true);
$cols['Deposit'] = array('index' => 'Lease.deposit', 'formatter' => 'currency', 'hiddenz' => true);
$cols['Rent'] = array('index' => 'Lease.rent', 'formatter' => 'currency');
$cols['Deposit'] = array('index' => 'Lease.deposit', 'formatter' => 'currency');
$cols['Signed'] = array('index' => 'Lease.lease_date', 'formatter' => 'date');
$cols['Move-In'] = array('index' => 'Lease.movein_date', 'formatter' => 'date');
$cols['Move-Out'] = array('index' => 'Lease.moveout_date', 'formatter' => 'date');
$cols['Closed'] = array('index' => 'Lease.close_date', 'formatter' => 'date');
$cols['Charge-Thru'] = array('index' => 'Lease.charge_through_date', 'formatter' => 'date');
$cols['Paid-Thru'] = array('index' => 'Lease.paid_through_date', 'formatter' => 'date');
$cols['Status'] = array('index' => 'status', 'formatter' => 'enum', 'width' => 100);
$cols['Status'] = array('index' => 'status', 'formatter' => 'longenum');
$cols['Balance'] = array('index' => 'balance', 'formatter' => 'currency');
$cols['Comment'] = array('index' => 'Lease.comment', 'formatter' => 'comment');
if (!empty($this->params['action'])) {
if ($this->params['action'] === 'closed')
$grid->invalidFields(array('Paid-Thru', 'Status'));
$grid->invalidFields(array('Charge-Thru', 'Paid-Thru', 'Status'));
elseif ($this->params['action'] === 'active')
$grid->invalidFields(array('Closed'));
elseif ($this->params['action'] === 'delinquent')
@@ -32,4 +33,4 @@ $grid
->defaultFields(array('Lease'))
->searchFields(array('Customer', 'Unit'))
->render($this, isset($config) ? $config : null,
array_diff(array_keys($cols), array('Signed', 'Status', 'Comment')));
array_diff(array_keys($cols), array('Signed', 'Charge-Thru', 'Status', 'Comment')));

View File

@@ -15,8 +15,8 @@ $cols['Balance'] = array('index' => 'balance', 'formatter' => 'c
// Render the grid
$grid
->columns($cols)
->sortField('Account')
->defaultFields(array('Account', 'Sequence'))
->searchFields(array('Account', 'Comment'))
->sortField('Sequence')
->defaultFields(array('Sequence'))
->searchFields(array('Comment'))
->render($this, isset($config) ? $config : null,
array_diff(array_keys($cols), array('Open Date', 'Comment')));
array_diff(array_keys($cols), array('Account', 'Open Date', 'Comment')));

View File

@@ -70,14 +70,16 @@ echo('</DIV>' . "\n"); // End #sidemenu-container
$javascript->codeBlock(
<<<JSCB
jQuery(document).ready(function(){
jQuery("#sidemenu").accordion
({ fillSpace : true,
event : "click hoverintent",
animated : "bounceslide",
if (jQuery("#sidemenu").accordion != null) {
jQuery("#sidemenu").accordion
({ fillSpace : true,
event : "click hoverintent",
animated : "bounceslide"
JSCB
. (isset($active_section) ? "\tactive : $active_section,\n" : '') .
. (isset($active_section) ? ",\n\t active : $active_section\n" : '') .
<<<JSCB
});
}
});
JSCB
, array('inline' => false));

View File

@@ -15,7 +15,7 @@ $cols['Unit'] = array('index' => 'Unit.name', 'formatter' =>
$cols['Comment'] = array('index' => 'StatementEntry.comment', 'formatter' => 'comment', 'width'=>150);
$cols['Type'] = array('index' => 'StatementEntry.type', 'formatter' => 'enum', 'width'=>120);
$cols['Type'] = array('index' => 'StatementEntry.type', 'formatter' => 'longenum');
$cols['Account'] = array('index' => 'Account.name', 'formatter' => 'name');
$cols['Debit'] = array('index' => 'charge', 'formatter' => 'currency');
$cols['Credit'] = array('index' => 'disbursement', 'formatter' => 'currency');

View File

@@ -17,4 +17,4 @@ $grid
->defaultFields(array('Date', 'Name', 'Amount'))
->searchFields(array('Name', 'Type'))
->render($this, isset($config) ? $config : null,
array_diff(array_keys($cols), array('Sub-Total')));
array_diff(array_keys($cols), array('Comment', 'Sub-Total')));

View File

@@ -9,7 +9,7 @@ $cols['Size'] = array('index' => 'UnitSize.name', 'formatter' => 'shortname'
$cols['Area'] = array('index' => 'sqft', 'formatter' => 'number');
$cols['Rent'] = array('index' => 'Unit.rent', 'formatter' => 'currency');
$cols['Deposit'] = array('index' => 'Unit.deposit', 'formatter' => 'currency');
$cols['Status'] = array('index' => 'Unit.status', 'formatter' => 'name'); // We have enough real estate
$cols['Status'] = array('index' => 'Unit.status', 'formatter' => 'enum');
$cols['Balance'] = array('index' => 'balance', 'formatter' => 'currency');
$cols['Comment'] = array('index' => 'Unit.comment', 'formatter' => 'comment');

View File

@@ -1,5 +1,3 @@
<?php /* -*- mode:PHP -*- */
if (!empty($message))
echo $message;

View File

@@ -268,14 +268,21 @@ class FormatHelper extends AppHelper {
// Helper function to convert PHP vars to javascript
function phpVarToJavascript($var, $name = '', $depth='', $special = false) {
function phpVarToJavascript($var, $name = '', $depth='', $special = false, $pretty = false) {
// Establish a prefix to use before printing $var
$prefix = $depth;
if ($pretty) {
$prefix = $depth;
$pretty_sp = " ";
$pretty_nl = "\n";
}
else {
$prefix = $pretty_sp = $pretty_nl = '';
}
// If given a name, set it up JS style
if ($name)
$prefix .= $name . ": ";
$prefix .= $name . ":" . $pretty_sp;
if (!isset($var))
return $prefix . 'null';
@@ -328,22 +335,22 @@ class FormatHelper extends AppHelper {
// PHP array indices can be a mix of integer and string based.
// Just guess here, unless flagged as a special case.
if (isset($var[0]) || $special)
return ($prefix . "[\n"
. implode(",\n",
return ($prefix . "[" . $pretty_nl
. implode("," . $pretty_nl,
array_map(array('FormatHelper', 'phpVarToJavascript'),
array_values($var),
array(),
array_fill(0, count($var), $depth.' ')
))
. "\n$depth]");
. ($pretty ? "\n$depth" : '') . "]");
return ($prefix . "{\n"
. implode(",\n",
return ($prefix . "{" . $pretty_nl
. implode("," . $pretty_nl,
array_map(array('FormatHelper', 'phpVarToJavascript'),
array_values($var), array_keys($var),
array_fill(0, count($var), $depth.' ')
))
. "\n$depth}");
. ($pretty ? "\n$depth" : '') . "}");
}
}

View File

@@ -6,6 +6,7 @@ class GridHelper extends AppHelper {
var $included, $invalid;
var $columns;
var $controller;
static $first_grid = true;
function __construct() {
$this->reset();
@@ -218,8 +219,12 @@ class GridHelper extends AppHelper {
if (isset($config))
$this->jqGrid_options = array_merge($this->jqGrid_options, $config);
// Set flag whether or not this is the first grid
$this->jqGrid_options['first_grid'] = self::$first_grid;
//pr(compact('config') + array('jqGrid_options' => $this->jqGrid_options));
echo $view->element('jqGrid', $this->jqGrid_options);
self::$first_grid = false;
// Since we only have one instance of this class
// as a helper, we must assume it could be used

View File

@@ -34,7 +34,11 @@
<head>
<?php echo $html->charset(); ?>
<title>
<?php if (devbox()) echo "*DEVBOX* "; ?>
<?php if (sandbox()) echo "*SANDBOX* "; ?>
Property Manager: <?php echo $title_for_layout; ?>
<?php if (sandbox()) echo " *SANDBOX*"; ?>
<?php if (devbox()) echo " *DEVBOX*"; ?>
</title>
<?php
// Reset the __scripts variable, which has already been dumped to
@@ -48,7 +52,7 @@
// mechanism _additional_ to what Cake has provided :-/
$this->__scripts = array();
if (!empty($_SERVER['HTTPS']))
if (!empty($_SERVER['HTTPS']))
$protocol = 'https://';
else
$protocol = 'http://';
@@ -58,17 +62,42 @@
echo $html->css('layout') . "\n";
echo $html->css('print', null, array('media' => 'print')) . "\n";
echo $html->css('sidemenu') . "\n";
echo $javascript->link($protocol . 'ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js') . "\n";
echo $javascript->link($protocol . 'ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js') . "\n";
//echo $html->css('themes/base/ui.all') . "\n";
//echo $html->css('themes/smoothness/ui.all') . "\n";
//echo $html->css('themes/dotluv/ui.all') . "\n";
echo $html->css('themes/start/ui.all') . "\n";
$theme = 'smoothness';
$theme = 'base';
$theme = 'dotluv';
$theme = 'dark-hive';
$theme = 'start';
if (devbox())
$theme = 'dotluv';
if (sandbox())
$theme = 'darkness';
echo $html->css('themes/'.$theme.'/ui.all') . "\n";
echo $javascript->link('jquery-1.3.2.min') . "\n";
echo $javascript->link('jquery-ui-1.7.2.custom.min') . "\n";
//echo $javascript->link($protocol . 'ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js') . "\n";
//echo $javascript->link($protocol . 'ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.js') . "\n";
//echo $javascript->link($protocol . 'ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js') . "\n";
//echo $javascript->link($protocol . 'ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js') . "\n";
echo $javascript->link('jquery.form') . "\n";
echo $javascript->link('pmgr.jquery') . "\n";
echo $javascript->link('jquery.hoverIntent') . "\n";
echo $javascript->link('pmgr') . "\n";
echo $scripts_for_layout . "\n";
?>
<?php if ($this->params['action'] !== 'INTERNAL_ERROR'): ?>
<script type="text/javascript"><!--
if (typeof(jQuery) == 'undefined') {
window.location.href =
"<?php echo $html->url(array('controller' => 'util',
'action' => 'INTERNAL_ERROR',
'jQuery NOT LOADED!')); ?>";
}
--></script>
<?php endif; ?>
</head>
<body>

View File

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

View File

@@ -34,6 +34,39 @@ function resetForm() {
datepickerNow('LeaseMoveDate', false);
}
// pre-submit callback
function verifyRequest() {
//$("#debug").html('');
<?php if ($move_type === 'out'): ?>
if (!($("#lease-id").val() > 0)) {
//$("#debug").append('<P>Missing Lease ID');
alert("Please select the lease");
return false;
}
<?php else: ?>
if (!($("#customer-id").val() > 0)) {
//$("#debug").append('<P>Missing Customer ID');
alert("Please select the customer");
return false;
}
if (!($("#unit-id").val() > 0)) {
//$("#debug").append('<P>Missing Unit ID');
alert("Please select the unit");
return false;
}
<?php endif; ?>
//$("#debug").append('OK');
//return false;
return true;
}
function onRowSelect(grid_id, item_type, item_id) {
cell_name = item_type.charAt(0).toUpperCase() + item_type.substr(1);
if (item_type == 'lease')
@@ -209,6 +242,7 @@ else {
}
echo $form->create(null, array('id' => 'move-inout-form',
'onsubmit' => 'return verifyRequest();',
'url' => array('controller' => 'leases',
'action' => $move_action)));
@@ -282,13 +316,7 @@ echo $form->end('Perform Move ' . ucfirst($move_type));
<script type="text/javascript"><!--
$(document).ready(function(){
$("#LeaseMoveDate")
.attr('autocomplete', 'off')
.datepicker({ constrainInput: true,
numberOfMonths: [1, 1],
showCurrentAtPos: 0,
dateFormat: 'mm/dd/yy' });
datepicker('LeaseMoveDate');
resetForm();
<?php if ($move_type === 'out') { ?>

View File

@@ -6,6 +6,19 @@
{// for indentation purposes
// Go through each unit, adding a clickable region for the unit
foreach ($info['units'] AS $unit){
$title = ('Unit #' .
$unit['name'] .
(empty($unit['data']['CurrentLease']['id'])
? ''
: ('; ' .
/* 'Lease #' . */
/* $unit['data']['CurrentLease']['id'] . */
/* '; ' . */
$unit['data']['Customer']['name'] .
'; Paid Through ' .
$unit['data']['CurrentLease']['paid_through_date'])
));
echo(' <area shape="rect"' .
' coords="' .
$unit['left'] . ',' .
@@ -16,20 +29,8 @@
$html->url(array('controller' => 'units',
'action' => 'view',
$unit['id'])) .
'" alt="Unit #' .
$unit['name'] .
'" title="Unit #' .
$unit['name'] .
(empty($unit['data']['CurrentLease']['id'])
? ''
: ('; ' .
/* 'Lease #' . */
/* $unit['data']['CurrentLease']['id'] . */
/* '; ' . */
$unit['data']['Customer']['name'] .
'; Paid Through ' .
$unit['data']['CurrentLease']['paid_through_date'])
) .
'" alt="' . $title .
'" title="' . $title .
'">' . "\n");
}
}// for indentation purposes

View File

@@ -60,13 +60,7 @@ function resetForm() {
}
$(document).ready(function(){
$("#TransactionStamp")
.attr('autocomplete', 'off')
.datepicker({ constrainInput: true,
numberOfMonths: [1, 1],
showCurrentAtPos: 0,
dateFormat: 'mm/dd/yy' });
datepicker('TransactionStamp');
resetForm();
});
--></script>

View File

@@ -29,10 +29,12 @@ if (in_array($entry['type'], array('CHARGE', 'PAYMENT')))
$rows[] = array('Through', FormatHelper::date($entry['through_date']));
$rows[] = array('Type', $entry['type']);
$rows[] = array('Amount', FormatHelper::currency($entry['amount']));
$rows[] = array('Account', $html->link($account['name'],
array('controller' => 'accounts',
'action' => 'view',
$account['id'])));
$rows[] = array('Account', ($account['link']
? $html->link($account['name'],
array('controller' => 'accounts',
'action' => 'view',
$account['id']))
: $account['name']));
$rows[] = array('Customer', (isset($customer['name'])
? $html->link($customer['name'],
array('controller' => 'customers',

View File

@@ -60,13 +60,7 @@ function resetForm() {
}
$(document).ready(function(){
$("#TransactionStamp")
.attr('autocomplete', 'off')
.datepicker({ constrainInput: true,
numberOfMonths: [1, 1],
showCurrentAtPos: 0,
dateFormat: 'mm/dd/yy' });
datepicker('TransactionStamp');
resetForm();
});
--></script>

View File

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

View File

@@ -75,13 +75,7 @@ function resetForm() {
}
$(document).ready(function(){
$("#TransactionStamp")
.attr('autocomplete', 'off')
.datepicker({ constrainInput: true,
numberOfMonths: [1, 1],
showCurrentAtPos: 0,
dateFormat: 'mm/dd/yy' });
datepicker('TransactionStamp');
resetForm();
});
--></script>

View File

@@ -92,13 +92,7 @@ function resetForm() {
}
$(document).ready(function(){
$("#TransactionStamp")
.attr('autocomplete', 'off')
.datepicker({ constrainInput: true,
numberOfMonths: [1, 1],
showCurrentAtPos: 0,
dateFormat: 'mm/dd/yy' });
datepicker('TransactionStamp');
resetForm();
});
--></script>

View File

@@ -21,19 +21,19 @@ $rows[] = array('ID', $transaction['id']);
$rows[] = array('Type', str_replace('_', ' ', $transaction['type']));
$rows[] = array('Timestamp', FormatHelper::datetime($transaction['stamp']));
$rows[] = array('Amount', FormatHelper::currency($transaction['amount']));
$rows[] = array('Account', $html->link($account['name'],
array('controller' => 'accounts',
'action' => 'view',
$account['id'])));
$rows[] = array('Ledger', $html->link('#' . $ledger['sequence'],
array('controller' => 'ledgers',
'action' => 'view',
$ledger['id'])));
$rows[] = array('Account', ($account['link']
? $html->link($account['name'],
array('controller' => 'accounts',
'action' => 'view',
$account['id']))
: $account['name']));
if (!empty($nsf_tender['id']))
$rows[] = array('NSF Tender', $html->link($nsf_tender['name'],
array('controller' => 'tenders',
'action' => 'view',
$nsf_tender['id'])));
$rows[] = array('Comment', $transaction['comment']);
echo $this->element('table',

View File

@@ -22,11 +22,6 @@
*/
* {
margin:0;
padding:0;
}
/* Layout */
#container {
text-align: left;

View File

@@ -11,6 +11,7 @@
* Overall page layout
*/
body { padding: 0; margin: 0 }
table#layout { width: 100% }
td#sidecolumn ,
td#pagecolumn { vertical-align: top; }
@@ -277,19 +278,15 @@ span.grid-error {
color: #a00;
}
span.ui-jqgrid-title {
color: #ffb;
font-family:'Gill Sans','lucida grande',helvetica, arial, sans-serif;
font-size: 180%;
margin-bottom: 0.0em;
.ui-jqgrid span.ui-jqgrid-title {
font-size: 160%;
margin: 0;
}
span.ui-jqgrid-title h2 {
color: #ffb;
font-family:'Gill Sans','lucida grande',helvetica, arial, sans-serif;
.ui-jqgrid span.ui-jqgrid-title h2 {
font-weight: bold;
font-size: 140%;
margin-bottom: 0.0em;
margin: 0;
}
@@ -365,45 +362,18 @@ fieldset fieldset div {
/* margin: 0 20px; */
}
/*
* REVISIT <AP>: 20090728
* This "form div" is way too generic, and in fact
* it's screwing up the jqGrid header. I'm commenting
* it out for now, to see if it actually is needed
* anywhere, and hope to delete it in the near future.
*/
/* form div { */
/* clear: both; */
/* /\* margin-bottom: 1em; *\/ */
/* /\* padding: .5em; *\/ */
/* vertical-align: text-top; */
/* } */
form div.input {
color: #444;
}
form div.required {
color: #333;
font-weight: bold;
}
form div.submit {
border: 0;
clear: both;
margin-top: 10px;
/* margin-left: 140px; */
}
/************************************************************
************************************************************
* General Style Info
*/
body {
/* background: #003d4c; */
/* color: #fff; */
font-family:'lucida grande',verdana,helvetica,arial,sans-serif;
font-size:90%;
margin: 0;
}
a {
color: #003d4c;
text-decoration: underline;
@@ -413,35 +383,4 @@ a:hover {
color: #00f;
text-decoration:none;
}
a img {
border:none;
}
h1, h2, h3, h4 {
font-weight: normal;
}
h1 {
color: #003d4c;
font-size: 100%;
margin: 0.1em 0;
}
h2 {
/* color: #e32; */
color: #993;
font-family:'Gill Sans','lucida grande',helvetica, arial, sans-serif;
font-size: 190%;
margin-bottom: 0.3em;
}
h3 {
color: #993;
font-family:'Gill Sans','lucida grande',helvetica, arial, sans-serif;
/* font-size: 165%; */
}
h4 {
color: #993;
font-weight: normal;
padding-top: 0.5em;
}

View File

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

View File

@@ -18,3 +18,4 @@
#sidemenu.ui-accordion .ui-accordion-header { padding: 0 0.5em 0 1.1em; }
#sidemenu.ui-accordion .ui-accordion-content { padding: 0 0.5em 0 1.1em; }
#sidemenu a { font-size: 90%; }

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@@ -0,0 +1,406 @@
/*
* jQuery UI CSS Framework
* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
*/
/* Layout helpers
----------------------------------*/
.ui-helper-hidden { display: none; }
.ui-helper-hidden-accessible { position: absolute; left: -99999999px; }
.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
.ui-helper-clearfix { display: inline-block; }
/* required comment for clearfix to work in Opera \*/
* html .ui-helper-clearfix { height:1%; }
.ui-helper-clearfix { display:block; }
/* end clearfix */
.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
/* Interaction Cues
----------------------------------*/
.ui-state-disabled { cursor: default !important; }
/* Icons
----------------------------------*/
/* states and images */
.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
/* Misc visuals
----------------------------------*/
/* Overlays */
.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
/*
* jQuery UI CSS Framework
* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana,%20Arial,%20sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=6px&bgColorHeader=444444&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=44&borderColorHeader=333333&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=000000&bgTextureContent=14_loop.png&bgImgOpacityContent=25&borderColorContent=555555&fcContent=ffffff&iconColorContent=cccccc&bgColorDefault=222222&bgTextureDefault=03_highlight_soft.png&bgImgOpacityDefault=35&borderColorDefault=444444&fcDefault=eeeeee&iconColorDefault=cccccc&bgColorHover=003147&bgTextureHover=03_highlight_soft.png&bgImgOpacityHover=33&borderColorHover=0b93d5&fcHover=ffffff&iconColorHover=ffffff&bgColorActive=0972a5&bgTextureActive=04_highlight_hard.png&bgImgOpacityActive=20&borderColorActive=26b3f7&fcActive=ffffff&iconColorActive=222222&bgColorHighlight=eeeeee&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=80&borderColorHighlight=cccccc&fcHighlight=2e7db2&iconColorHighlight=4b8e0b&bgColorError=ffc73d&bgTextureError=02_glass.png&bgImgOpacityError=40&borderColorError=ffb73d&fcError=111111&iconColorError=a83300&bgColorOverlay=5c5c5c&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=50&opacityOverlay=80&bgColorShadow=cccccc&bgTextureShadow=01_flat.png&bgImgOpacityShadow=30&opacityShadow=60&thicknessShadow=7px&offsetTopShadow=-7px&offsetLeftShadow=-7px&cornerRadiusShadow=8px
*/
/* Component containers
----------------------------------*/
.ui-widget { font-family: Verdana, Arial, sans-serif; font-size: 1.1em; }
.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana, Arial, sans-serif; font-size: 1em; }
.ui-widget-content { border: 1px solid #555555; background: #000000 url(images/ui-bg_loop_25_000000_21x21.png) 50% 50% repeat; color: #ffffff; }
.ui-widget-content a { color: #ffffff; }
.ui-widget-header { border: 1px solid #333333; background: #444444 url(images/ui-bg_highlight-soft_44_444444_1x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; }
.ui-widget-header a { color: #ffffff; }
/* Interaction states
----------------------------------*/
.ui-state-default, .ui-widget-content .ui-state-default { border: 1px solid #444444; background: #222222 url(images/ui-bg_highlight-soft_35_222222_1x100.png) 50% 50% repeat-x; font-weight: normal; color: #eeeeee; outline: none; }
.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #eeeeee; text-decoration: none; outline: none; }
.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus { border: 1px solid #0b93d5; background: #003147 url(images/ui-bg_highlight-soft_33_003147_1x100.png) 50% 50% repeat-x; font-weight: normal; color: #ffffff; outline: none; }
.ui-state-hover a, .ui-state-hover a:hover { color: #ffffff; text-decoration: none; outline: none; }
.ui-state-active, .ui-widget-content .ui-state-active { border: 1px solid #26b3f7; background: #0972a5 url(images/ui-bg_highlight-hard_20_0972a5_1x100.png) 50% 50% repeat-x; font-weight: normal; color: #ffffff; outline: none; }
.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #ffffff; outline: none; text-decoration: none; }
/* Interaction Cues
----------------------------------*/
.ui-state-highlight, .ui-widget-content .ui-state-highlight {border: 1px solid #cccccc; background: #eeeeee url(images/ui-bg_highlight-soft_80_eeeeee_1x100.png) 50% top repeat-x; color: #2e7db2; }
.ui-state-highlight a, .ui-widget-content .ui-state-highlight a { color: #2e7db2; }
.ui-state-error, .ui-widget-content .ui-state-error {border: 1px solid #ffb73d; background: #ffc73d url(images/ui-bg_glass_40_ffc73d_1x400.png) 50% 50% repeat-x; color: #111111; }
.ui-state-error a, .ui-widget-content .ui-state-error a { color: #111111; }
.ui-state-error-text, .ui-widget-content .ui-state-error-text { color: #111111; }
.ui-state-disabled, .ui-widget-content .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
.ui-priority-primary, .ui-widget-content .ui-priority-primary { font-weight: bold; }
.ui-priority-secondary, .ui-widget-content .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
/* Icons
----------------------------------*/
/* states and images */
.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_cccccc_256x240.png); }
.ui-widget-content .ui-icon {background-image: url(images/ui-icons_cccccc_256x240.png); }
.ui-widget-header .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); }
.ui-state-default .ui-icon { background-image: url(images/ui-icons_cccccc_256x240.png); }
.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); }
.ui-state-active .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_4b8e0b_256x240.png); }
.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_a83300_256x240.png); }
/* positioning */
.ui-icon-carat-1-n { background-position: 0 0; }
.ui-icon-carat-1-ne { background-position: -16px 0; }
.ui-icon-carat-1-e { background-position: -32px 0; }
.ui-icon-carat-1-se { background-position: -48px 0; }
.ui-icon-carat-1-s { background-position: -64px 0; }
.ui-icon-carat-1-sw { background-position: -80px 0; }
.ui-icon-carat-1-w { background-position: -96px 0; }
.ui-icon-carat-1-nw { background-position: -112px 0; }
.ui-icon-carat-2-n-s { background-position: -128px 0; }
.ui-icon-carat-2-e-w { background-position: -144px 0; }
.ui-icon-triangle-1-n { background-position: 0 -16px; }
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
.ui-icon-triangle-1-e { background-position: -32px -16px; }
.ui-icon-triangle-1-se { background-position: -48px -16px; }
.ui-icon-triangle-1-s { background-position: -64px -16px; }
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
.ui-icon-triangle-1-w { background-position: -96px -16px; }
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
.ui-icon-arrow-1-n { background-position: 0 -32px; }
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
.ui-icon-arrow-1-e { background-position: -32px -32px; }
.ui-icon-arrow-1-se { background-position: -48px -32px; }
.ui-icon-arrow-1-s { background-position: -64px -32px; }
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
.ui-icon-arrow-1-w { background-position: -96px -32px; }
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
.ui-icon-arrow-4 { background-position: 0 -80px; }
.ui-icon-arrow-4-diag { background-position: -16px -80px; }
.ui-icon-extlink { background-position: -32px -80px; }
.ui-icon-newwin { background-position: -48px -80px; }
.ui-icon-refresh { background-position: -64px -80px; }
.ui-icon-shuffle { background-position: -80px -80px; }
.ui-icon-transfer-e-w { background-position: -96px -80px; }
.ui-icon-transferthick-e-w { background-position: -112px -80px; }
.ui-icon-folder-collapsed { background-position: 0 -96px; }
.ui-icon-folder-open { background-position: -16px -96px; }
.ui-icon-document { background-position: -32px -96px; }
.ui-icon-document-b { background-position: -48px -96px; }
.ui-icon-note { background-position: -64px -96px; }
.ui-icon-mail-closed { background-position: -80px -96px; }
.ui-icon-mail-open { background-position: -96px -96px; }
.ui-icon-suitcase { background-position: -112px -96px; }
.ui-icon-comment { background-position: -128px -96px; }
.ui-icon-person { background-position: -144px -96px; }
.ui-icon-print { background-position: -160px -96px; }
.ui-icon-trash { background-position: -176px -96px; }
.ui-icon-locked { background-position: -192px -96px; }
.ui-icon-unlocked { background-position: -208px -96px; }
.ui-icon-bookmark { background-position: -224px -96px; }
.ui-icon-tag { background-position: -240px -96px; }
.ui-icon-home { background-position: 0 -112px; }
.ui-icon-flag { background-position: -16px -112px; }
.ui-icon-calendar { background-position: -32px -112px; }
.ui-icon-cart { background-position: -48px -112px; }
.ui-icon-pencil { background-position: -64px -112px; }
.ui-icon-clock { background-position: -80px -112px; }
.ui-icon-disk { background-position: -96px -112px; }
.ui-icon-calculator { background-position: -112px -112px; }
.ui-icon-zoomin { background-position: -128px -112px; }
.ui-icon-zoomout { background-position: -144px -112px; }
.ui-icon-search { background-position: -160px -112px; }
.ui-icon-wrench { background-position: -176px -112px; }
.ui-icon-gear { background-position: -192px -112px; }
.ui-icon-heart { background-position: -208px -112px; }
.ui-icon-star { background-position: -224px -112px; }
.ui-icon-link { background-position: -240px -112px; }
.ui-icon-cancel { background-position: 0 -128px; }
.ui-icon-plus { background-position: -16px -128px; }
.ui-icon-plusthick { background-position: -32px -128px; }
.ui-icon-minus { background-position: -48px -128px; }
.ui-icon-minusthick { background-position: -64px -128px; }
.ui-icon-close { background-position: -80px -128px; }
.ui-icon-closethick { background-position: -96px -128px; }
.ui-icon-key { background-position: -112px -128px; }
.ui-icon-lightbulb { background-position: -128px -128px; }
.ui-icon-scissors { background-position: -144px -128px; }
.ui-icon-clipboard { background-position: -160px -128px; }
.ui-icon-copy { background-position: -176px -128px; }
.ui-icon-contact { background-position: -192px -128px; }
.ui-icon-image { background-position: -208px -128px; }
.ui-icon-video { background-position: -224px -128px; }
.ui-icon-script { background-position: -240px -128px; }
.ui-icon-alert { background-position: 0 -144px; }
.ui-icon-info { background-position: -16px -144px; }
.ui-icon-notice { background-position: -32px -144px; }
.ui-icon-help { background-position: -48px -144px; }
.ui-icon-check { background-position: -64px -144px; }
.ui-icon-bullet { background-position: -80px -144px; }
.ui-icon-radio-off { background-position: -96px -144px; }
.ui-icon-radio-on { background-position: -112px -144px; }
.ui-icon-pin-w { background-position: -128px -144px; }
.ui-icon-pin-s { background-position: -144px -144px; }
.ui-icon-play { background-position: 0 -160px; }
.ui-icon-pause { background-position: -16px -160px; }
.ui-icon-seek-next { background-position: -32px -160px; }
.ui-icon-seek-prev { background-position: -48px -160px; }
.ui-icon-seek-end { background-position: -64px -160px; }
.ui-icon-seek-first { background-position: -80px -160px; }
.ui-icon-stop { background-position: -96px -160px; }
.ui-icon-eject { background-position: -112px -160px; }
.ui-icon-volume-off { background-position: -128px -160px; }
.ui-icon-volume-on { background-position: -144px -160px; }
.ui-icon-power { background-position: 0 -176px; }
.ui-icon-signal-diag { background-position: -16px -176px; }
.ui-icon-signal { background-position: -32px -176px; }
.ui-icon-battery-0 { background-position: -48px -176px; }
.ui-icon-battery-1 { background-position: -64px -176px; }
.ui-icon-battery-2 { background-position: -80px -176px; }
.ui-icon-battery-3 { background-position: -96px -176px; }
.ui-icon-circle-plus { background-position: 0 -192px; }
.ui-icon-circle-minus { background-position: -16px -192px; }
.ui-icon-circle-close { background-position: -32px -192px; }
.ui-icon-circle-triangle-e { background-position: -48px -192px; }
.ui-icon-circle-triangle-s { background-position: -64px -192px; }
.ui-icon-circle-triangle-w { background-position: -80px -192px; }
.ui-icon-circle-triangle-n { background-position: -96px -192px; }
.ui-icon-circle-arrow-e { background-position: -112px -192px; }
.ui-icon-circle-arrow-s { background-position: -128px -192px; }
.ui-icon-circle-arrow-w { background-position: -144px -192px; }
.ui-icon-circle-arrow-n { background-position: -160px -192px; }
.ui-icon-circle-zoomin { background-position: -176px -192px; }
.ui-icon-circle-zoomout { background-position: -192px -192px; }
.ui-icon-circle-check { background-position: -208px -192px; }
.ui-icon-circlesmall-plus { background-position: 0 -208px; }
.ui-icon-circlesmall-minus { background-position: -16px -208px; }
.ui-icon-circlesmall-close { background-position: -32px -208px; }
.ui-icon-squaresmall-plus { background-position: -48px -208px; }
.ui-icon-squaresmall-minus { background-position: -64px -208px; }
.ui-icon-squaresmall-close { background-position: -80px -208px; }
.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
/* Misc visuals
----------------------------------*/
/* Corner radius */
.ui-corner-tl { -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; }
.ui-corner-tr { -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; }
.ui-corner-bl { -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; }
.ui-corner-br { -moz-border-radius-bottomright: 6px; -webkit-border-bottom-right-radius: 6px; }
.ui-corner-top { -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; }
.ui-corner-bottom { -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; -moz-border-radius-bottomright: 6px; -webkit-border-bottom-right-radius: 6px; }
.ui-corner-right { -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; -moz-border-radius-bottomright: 6px; -webkit-border-bottom-right-radius: 6px; }
.ui-corner-left { -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; }
.ui-corner-all { -moz-border-radius: 6px; -webkit-border-radius: 6px; }
/* Overlays */
.ui-widget-overlay { background: #5c5c5c url(images/ui-bg_flat_50_5c5c5c_40x100.png) 50% 50% repeat-x; opacity: .80;filter:Alpha(Opacity=80); }
.ui-widget-shadow { margin: -7px 0 0 -7px; padding: 7px; background: #cccccc url(images/ui-bg_flat_30_cccccc_40x100.png) 50% 50% repeat-x; opacity: .60;filter:Alpha(Opacity=60); -moz-border-radius: 8px; -webkit-border-radius: 8px; }/* Accordion
----------------------------------*/
.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
.ui-accordion .ui-accordion-li-fix { display: inline; }
.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em 2.2em; }
.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; }
.ui-accordion .ui-accordion-content-active { display: block; }/* Datepicker
----------------------------------*/
.ui-datepicker { width: 17em; padding: .2em .2em 0; }
.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
.ui-datepicker .ui-datepicker-prev { left:2px; }
.ui-datepicker .ui-datepicker-next { right:2px; }
.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
.ui-datepicker .ui-datepicker-next-hover { right:1px; }
.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }
.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
.ui-datepicker .ui-datepicker-title select { float:left; font-size:1em; margin:1px 0; }
.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
.ui-datepicker select.ui-datepicker-month,
.ui-datepicker select.ui-datepicker-year { width: 49%;}
.ui-datepicker .ui-datepicker-title select.ui-datepicker-year { float: right; }
.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }
.ui-datepicker td { border: 0; padding: 1px; }
.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
/* with multiple calendars */
.ui-datepicker.ui-datepicker-multi { width:auto; }
.ui-datepicker-multi .ui-datepicker-group { float:left; }
.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
.ui-datepicker-row-break { clear:both; width:100%; }
/* RTL support */
.ui-datepicker-rtl { direction: rtl; }
.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
.ui-datepicker-rtl .ui-datepicker-group { float:right; }
.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
.ui-datepicker-cover {
display: none; /*sorry for IE5*/
display/**/: block; /*sorry for IE5*/
position: absolute; /*must have*/
z-index: -1; /*must have*/
filter: mask(); /*must have*/
top: -4px; /*must have*/
left: -4px; /*must have*/
width: 200px; /*must have*/
height: 200px; /*must have*/
}/* Dialog
----------------------------------*/
.ui-dialog { position: relative; padding: .2em; width: 300px; }
.ui-dialog .ui-dialog-titlebar { padding: .5em .3em .3em 1em; position: relative; }
.ui-dialog .ui-dialog-title { float: left; margin: .1em 0 .2em; }
.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
.ui-dialog .ui-dialog-content { border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
.ui-dialog .ui-dialog-buttonpane button { float: right; margin: .5em .4em .5em 0; cursor: pointer; padding: .2em .6em .3em .6em; line-height: 1.4em; width:auto; overflow:visible; }
.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
.ui-draggable .ui-dialog-titlebar { cursor: move; }
/* Progressbar
----------------------------------*/
.ui-progressbar { height:2em; text-align: left; }
.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }/* Resizable
----------------------------------*/
.ui-resizable { position: relative;}
.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0px; }
.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0px; }
.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0px; height: 100%; }
.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0px; height: 100%; }
.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* Slider
----------------------------------*/
.ui-slider { position: relative; text-align: left; }
.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; }
.ui-slider-horizontal { height: .8em; }
.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
.ui-slider-horizontal .ui-slider-range-min { left: 0; }
.ui-slider-horizontal .ui-slider-range-max { right: 0; }
.ui-slider-vertical { width: .8em; height: 100px; }
.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
.ui-slider-vertical .ui-slider-range-max { top: 0; }/* Tabs
----------------------------------*/
.ui-tabs { padding: .2em; zoom: 1; }
.ui-tabs .ui-tabs-nav { list-style: none; position: relative; padding: .2em .2em 0; }
.ui-tabs .ui-tabs-nav li { position: relative; float: left; border-bottom-width: 0 !important; margin: 0 .2em -1px 0; padding: 0; }
.ui-tabs .ui-tabs-nav li a { float: left; text-decoration: none; padding: .5em 1em; }
.ui-tabs .ui-tabs-nav li.ui-tabs-selected { padding-bottom: 1px; border-bottom-width: 0; }
.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
.ui-tabs .ui-tabs-panel { padding: 1em 1.4em; display: block; border-width: 0; background: none; }
.ui-tabs .ui-tabs-hide { display: none !important; }

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Some files were not shown because too many files have changed in this diff Show More