From f3ffa3c079dedd31077a9fb3cd3f00e4e6f9ade1 Mon Sep 17 00:00:00 2001 From: abijah Date: Sat, 6 Jun 2009 20:18:56 +0000 Subject: [PATCH] I'm still in the middle of moving onto a ledger based system. However, I'm am now changing how transactions and entries relate back to the customer. I'll be using a ledger for each lease (for rent, late charges, security deposits, etc), and a ledger for each customer (for POS, non-specific deposits such as reservations or covering mulitple units, bad debt writeoff, and possibly customer credits, when not obviously lease specific). This coming change might not be in the right direction, so I want to capture the work as is right now. This change set is not fully functional. Many operations do work, but there are obviously transaction problems with units and customers. git-svn-id: file:///svn-source/pmgr/branches/ledger_transactions_20090605@71 97e9348a-65ac-dc4b-aefc-98561f571b83 --- db/schema.sql | 546 +++++------- scripts/sitelink2pmgr.pl | 809 ++++++++++-------- site/app_model.php | 46 +- site/controllers/accounts_controller.php | 265 ++++++ site/controllers/accounts_controller.php.bak | 244 ++++++ site/controllers/contacts_controller.php | 52 +- site/controllers/customers_controller.php | 177 ++++ .../controllers/ledger_entries_controller.php | 55 ++ site/controllers/ledgers_controller.php | 188 ++++ site/controllers/payments_controller.php | 118 --- site/controllers/receipts_controller.php | 131 --- ...roller.php => transactions_controller.php} | 66 +- site/controllers/units_controller.php | 81 +- site/models/account.php | 23 +- site/models/behaviors/linkable.php | 85 +- site/models/charge.php | 53 -- site/models/charge_type.php | 39 - site/models/contact.php | 8 +- site/models/customer.php | 58 ++ site/models/lease.php | 39 +- site/models/ledger.php | 65 ++ site/models/ledger_entry.php | 43 + site/models/monetary_source.php | 28 + .../{payment_type.php => monetary_type.php} | 11 +- site/models/payment.php | 31 - site/models/receipt.php | 46 - site/models/transaction.php | 37 + site/models/unit.php | 7 + site/views/accounts/index.ctp | 3 + site/views/accounts/view.ctp | 95 ++ site/views/charges/index.ctp | 3 - site/views/charges/view.ctp | 87 -- site/views/contacts/view.ctp | 113 +-- site/views/customers/index.ctp | 3 + site/views/customers/view.ctp | 189 ++++ site/views/elements/accounts.ctp | 85 ++ site/views/elements/charges.ctp | 68 -- site/views/elements/contacts.ctp | 57 +- .../elements/{receipts.ctp => customers.ctp} | 41 +- site/views/elements/ledger.ctp | 364 ++------ site/views/elements/ledgers.ctp | 77 ++ site/views/elements/payments.ctp | 67 -- site/views/elements/table.ctp | 4 +- site/views/elements/transactions.ctp | 65 ++ site/views/ledgers/index.ctp | 14 + site/views/ledgers/view.ctp | 98 +++ site/views/payments/index.ctp | 3 - site/views/payments/view.ctp | 43 - site/views/receipts/index.ctp | 3 - site/views/receipts/view.ctp | 116 --- site/views/transactions/index.ctp | 13 + site/views/transactions/view.ctp | 102 +++ site/views/units/view.ctp | 44 +- site/webroot/css/layout.css | 83 +- 54 files changed, 3066 insertions(+), 2125 deletions(-) create mode 100644 site/controllers/accounts_controller.php create mode 100644 site/controllers/accounts_controller.php.bak create mode 100644 site/controllers/customers_controller.php create mode 100644 site/controllers/ledger_entries_controller.php create mode 100644 site/controllers/ledgers_controller.php delete mode 100644 site/controllers/payments_controller.php delete mode 100644 site/controllers/receipts_controller.php rename site/controllers/{charges_controller.php => transactions_controller.php} (65%) delete mode 100644 site/models/charge.php delete mode 100644 site/models/charge_type.php create mode 100644 site/models/customer.php create mode 100644 site/models/ledger.php create mode 100644 site/models/ledger_entry.php create mode 100644 site/models/monetary_source.php rename site/models/{payment_type.php => monetary_type.php} (55%) delete mode 100644 site/models/payment.php delete mode 100644 site/models/receipt.php create mode 100644 site/models/transaction.php create mode 100644 site/views/accounts/index.ctp create mode 100644 site/views/accounts/view.ctp delete mode 100644 site/views/charges/index.ctp delete mode 100644 site/views/charges/view.ctp create mode 100644 site/views/customers/index.ctp create mode 100644 site/views/customers/view.ctp create mode 100644 site/views/elements/accounts.ctp delete mode 100644 site/views/elements/charges.ctp rename site/views/elements/{receipts.ctp => customers.ctp} (53%) create mode 100644 site/views/elements/ledgers.ctp delete mode 100644 site/views/elements/payments.ctp create mode 100644 site/views/elements/transactions.ctp create mode 100644 site/views/ledgers/index.ctp create mode 100644 site/views/ledgers/view.ctp delete mode 100644 site/views/payments/index.ctp delete mode 100644 site/views/payments/view.ctp delete mode 100644 site/views/receipts/index.ctp delete mode 100644 site/views/receipts/view.ctp create mode 100644 site/views/transactions/index.ctp create mode 100644 site/views/transactions/view.ctp diff --git a/db/schema.sql b/db/schema.sql index 52d4f6b..e6b638e 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -448,44 +448,6 @@ CREATE TABLE `pmgr_site_areas` ( -- ## --- ---------------------------------------------------------------------- --- ---------------------------------------------------------------------- --- TABLE pmgr_unit_types - -DROP TABLE IF EXISTS `pmgr_unit_types`; -CREATE TABLE `pmgr_unit_types` ( - `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, - `code` VARCHAR(12) NOT NULL, -- User style "id" - `name` VARCHAR(80) NOT NULL, - `comment` VARCHAR(255) DEFAULT NULL, - - PRIMARY KEY (`id`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - - --- ---------------------------------------------------------------------- --- ---------------------------------------------------------------------- --- TABLE pmgr_unit_sizes - -DROP TABLE IF EXISTS `pmgr_unit_sizes`; -CREATE TABLE `pmgr_unit_sizes` ( - `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, - `unit_type_id` INT(10) UNSIGNED NOT NULL, - `code` VARCHAR(12) NOT NULL, -- User style "id" - `name` VARCHAR(80) NOT NULL, - `width` SMALLINT UNSIGNED NOT NULL, -- inches - `depth` SMALLINT UNSIGNED NOT NULL, -- inches - `height` SMALLINT UNSIGNED DEFAULT NULL, -- inches - `comment` VARCHAR(255) DEFAULT NULL, - - `deposit` FLOAT(12,2) DEFAULT NULL, - `amount` FLOAT(12,2) DEFAULT NULL, - - PRIMARY KEY (`id`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - -- ---------------------------------------------------------------------- -- ---------------------------------------------------------------------- -- TABLE pmgr_units @@ -525,6 +487,44 @@ CREATE TABLE `pmgr_units` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8; +-- ---------------------------------------------------------------------- +-- ---------------------------------------------------------------------- +-- TABLE pmgr_unit_types + +DROP TABLE IF EXISTS `pmgr_unit_types`; +CREATE TABLE `pmgr_unit_types` ( + `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + `code` VARCHAR(12) NOT NULL, -- User style "id" + `name` VARCHAR(80) NOT NULL, + `comment` VARCHAR(255) DEFAULT NULL, + + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + + + +-- ---------------------------------------------------------------------- +-- ---------------------------------------------------------------------- +-- TABLE pmgr_unit_sizes + +DROP TABLE IF EXISTS `pmgr_unit_sizes`; +CREATE TABLE `pmgr_unit_sizes` ( + `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + `unit_type_id` INT(10) UNSIGNED NOT NULL, + `code` VARCHAR(12) NOT NULL, -- User style "id" + `name` VARCHAR(80) NOT NULL, + `width` SMALLINT UNSIGNED NOT NULL, -- inches + `depth` SMALLINT UNSIGNED NOT NULL, -- inches + `height` SMALLINT UNSIGNED DEFAULT NULL, -- inches + `comment` VARCHAR(255) DEFAULT NULL, + + `deposit` FLOAT(12,2) DEFAULT NULL, + `amount` FLOAT(12,2) DEFAULT NULL, + + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + + -- ###################################################################### -- ###################################################################### @@ -619,18 +619,16 @@ CREATE TABLE `pmgr_actions_late_schedules` ( -- ###################################################################### -- ###################################################################### -- ## --- ## LEASES +-- ## CUSTOMERS -- ## - -- ---------------------------------------------------------------------- -- ---------------------------------------------------------------------- --- TABLE pmgr_lease_types +-- TABLE pmgr_customers -DROP TABLE IF EXISTS `pmgr_lease_types`; -CREATE TABLE `pmgr_lease_types` ( +DROP TABLE IF EXISTS `pmgr_customers`; +CREATE TABLE `pmgr_customers` ( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, - `code` VARCHAR(12) NOT NULL, -- User style "id" `name` VARCHAR(80) NOT NULL, `comment` VARCHAR(255) DEFAULT NULL, @@ -638,6 +636,44 @@ CREATE TABLE `pmgr_lease_types` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8; +-- ---------------------------------------------------------------------- +-- ---------------------------------------------------------------------- +-- TABLE pmgr_contacts_customers + +DROP TABLE IF EXISTS `pmgr_contacts_customers`; +CREATE TABLE `pmgr_contacts_customers` ( + `contact_id` INT(10) UNSIGNED NOT NULL, + `customer_id` INT(10) UNSIGNED NOT NULL, + + -- What type of contact is this for the lease? + `type` ENUM('TENANT', -- TENANT + 'ALTERNATE') -- ALTERNATE CONTACT ONLY + NOT NULL DEFAULT 'TENANT', + + -- If the tenant is active as part of the lease + `active` TINYINT DEFAULT 1, + + `comment` VARCHAR(255) DEFAULT NULL, + + PRIMARY KEY (`customer_id`, `contact_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + + + +-- ###################################################################### +-- ###################################################################### +-- ###################################################################### +-- ###################################################################### +-- ###################################################################### +-- ###################################################################### +-- ###################################################################### +-- ###################################################################### +-- ###################################################################### +-- ## +-- ## LEASES +-- ## + + -- ---------------------------------------------------------------------- -- ---------------------------------------------------------------------- -- TABLE pmgr_leases @@ -652,7 +688,7 @@ CREATE TABLE `pmgr_leases` ( `lease_type_id` INT(10) UNSIGNED NOT NULL, `unit_id` INT(10) UNSIGNED NOT NULL, - `primary_contact_id` INT(10) UNSIGNED DEFAULT NULL, -- NOT NULL, + `customer_id` INT(10) UNSIGNED NOT NULL, `late_schedule_id` INT(10) UNSIGNED DEFAULT NULL, `lease_date` DATE NOT NULL, @@ -678,24 +714,16 @@ CREATE TABLE `pmgr_leases` ( -- ---------------------------------------------------------------------- -- ---------------------------------------------------------------------- --- TABLE pmgr_contacts_leases - -DROP TABLE IF EXISTS `pmgr_contacts_leases`; -CREATE TABLE `pmgr_contacts_leases` ( - `lease_id` INT(10) UNSIGNED NOT NULL, - `contact_id` INT(10) UNSIGNED NOT NULL, - - -- What type of contact is this for the lease? - `type` ENUM('TENANT', -- TENANT - 'ALTERNATE') -- ALTERNATE CONTACT ONLY - NOT NULL DEFAULT 'TENANT', - - -- If the tenant is active as part of the lease - `active` TINYINT DEFAULT 1, +-- TABLE pmgr_lease_types +DROP TABLE IF EXISTS `pmgr_lease_types`; +CREATE TABLE `pmgr_lease_types` ( + `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + `code` VARCHAR(12) NOT NULL, -- User style "id" + `name` VARCHAR(80) NOT NULL, `comment` VARCHAR(255) DEFAULT NULL, - PRIMARY KEY (`lease_id`, `contact_id`) + PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; @@ -726,7 +754,7 @@ CREATE TABLE `pmgr_reservations` ( -- If NULL, `id` will be used `number` VARCHAR(20) DEFAULT NULL, - `contact_id` INT(10) UNSIGNED NOT NULL, + `customer_id` INT(10) UNSIGNED NOT NULL, `deposit` FLOAT(12,2) DEFAULT NULL, `reservation_date` DATE NOT NULL, @@ -784,125 +812,166 @@ DROP TABLE IF EXISTS `pmgr_accounts`; CREATE TABLE `pmgr_accounts` ( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + `type` ENUM('ASSET', + 'LIABILITY', + 'EQUITY', + 'INCOME', + 'EXPENSE') + NOT NULL DEFAULT 'ASSET', + + -- Security Level + `level` INT UNSIGNED DEFAULT 1, + `name` VARCHAR(80) NOT NULL, `external_account` INT(10) UNSIGNED DEFAULT NULL, `external_name` VARCHAR(80) DEFAULT NULL, + `comment` VARCHAR(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - --- ###################################################################### --- ###################################################################### --- ###################################################################### --- ###################################################################### --- ###################################################################### --- ###################################################################### --- ###################################################################### --- ###################################################################### --- ###################################################################### --- ## --- ## CHARGES --- ## - - --- ---------------------------------------------------------------------- --- ---------------------------------------------------------------------- --- TABLE pmgr_charge_types - -DROP TABLE IF EXISTS `pmgr_charge_types`; -CREATE TABLE `pmgr_charge_types` ( - `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, - - `name` VARCHAR(80) NOT NULL, - `comment` VARCHAR(255) DEFAULT NULL, - `account_id` INT(10) UNSIGNED NOT NULL, -- quickbooks tracking - - PRIMARY KEY (`id`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -LOCK TABLES `pmgr_charge_types` WRITE; -INSERT INTO `pmgr_charge_types` (`id`, `name`, `account_id`) +LOCK TABLES `pmgr_accounts` WRITE; +INSERT INTO `pmgr_accounts` (`id`, `type`, `name`) VALUES - (1, 'Security Deposit', 0), - (2, 'Rent', 0), - (3, 'Late Charge', 0); + (1, 'ASSET', 'A/R'), + (2, 'LIABILITY', 'A/P'), + (3, 'LIABILITY', 'Tax'), + (4, 'LIABILITY', 'Customer Credit'), + (5, 'ASSET', 'Bank'), + (6, 'ASSET', 'Cash'), + (7, 'LIABILITY', 'Security Deposit'), + (8, 'INCOME', 'Rent'), + (9, 'INCOME', 'Late Charge'); UNLOCK TABLES; --- ---------------------------------------------------------------------- --- ---------------------------------------------------------------------- --- TABLE pmgr_charges -DROP TABLE IF EXISTS `pmgr_charges`; -CREATE TABLE `pmgr_charges` ( +-- ###################################################################### +-- ###################################################################### +-- ###################################################################### +-- ###################################################################### +-- ###################################################################### +-- ###################################################################### +-- ###################################################################### +-- ###################################################################### +-- ###################################################################### +-- ## +-- ## LEDGERS +-- ## + + +-- ---------------------------------------------------------------------- +-- ---------------------------------------------------------------------- +-- TABLE pmgr_ledgers +-- +-- REVISIT : 20090605 +-- We may not really need a ledgers table. +-- It's not clear to me though, as we very +-- possibly need to close out certain +-- ledgers every so often, and just carry +-- the balance forward (year end, etc). + +DROP TABLE IF EXISTS `pmgr_ledgers`; +CREATE TABLE `pmgr_ledgers` ( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, - `charge_type_id` INT(10) UNSIGNED NOT NULL, - `lease_id` INT(10) UNSIGNED NOT NULL, - `charge_date` DATE NOT NULL, - `charge_to_date` DATE DEFAULT NULL, - `due_date` DATE DEFAULT NULL, - `amount` FLOAT(12,2) NOT NULL, - `tax` FLOAT(12,2) NOT NULL, - `total` FLOAT(12,2) NOT NULL, + -- REVISIT : 20090605 + -- If ledgers do need to be closed, then we'll need + -- to add several parameters indicating the period + -- this particular ledger is valid and so on. + + `name` VARCHAR(80) DEFAULT NULL, + `account_id` INT(10) UNSIGNED NOT NULL, + `closed` INT UNSIGNED DEFAULT 0, + `comment` VARCHAR(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; --- -- ---------------------------------------------------------------------- --- -- ---------------------------------------------------------------------- --- -- TABLE pmgr_invoices +-- ---------------------------------------------------------------------- +-- ---------------------------------------------------------------------- +-- TABLE pmgr_transactions --- DROP TABLE IF EXISTS `pmgr_invoices`; --- CREATE TABLE `pmgr_invoices` ( --- `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, --- `stamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, +DROP TABLE IF EXISTS `pmgr_transactions`; +CREATE TABLE `pmgr_transactions` ( + `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, --- `comment` VARCHAR(255) DEFAULT NULL, + `stamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + `through_date` DATE DEFAULT NULL, + `due_date` DATE DEFAULT NULL, --- PRIMARY KEY (`id`) --- ) ENGINE=MyISAM DEFAULT CHARSET=utf8; + -- REVISIT : 20090604 + -- It really seems this is too restrictive. One tenant + -- should be able to, within a single transaction, pay + -- for their own charges and another tenant's as well. + -- customer_id may need to move to ledger_entries + `customer_id` INT(10) UNSIGNED NOT NULL, + -- REVISIT : 20090604 + -- How should we track which charges have been paid? + -- `related_transaction_id` INT(10) UNSIGNED NOT NULL, + -- `related_entry_id` INT(10) UNSIGNED NOT NULL, --- -- ---------------------------------------------------------------------- --- -- ---------------------------------------------------------------------- --- -- TABLE pmgr_charges_invoices + `comment` VARCHAR(255) DEFAULT NULL, --- DROP TABLE IF EXISTS `pmgr_charges_invoices`; --- CREATE TABLE `pmgr_charges_invoices` ( --- `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, --- `charge_id` INT(10) UNSIGNED NOT NULL, --- `invoice_id` INT(10) UNSIGNED NOT NULL, --- `amount` FLOAT(12,2) NOT NULL, --- PRIMARY KEY (`id`) --- ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - --- ###################################################################### --- ###################################################################### --- ###################################################################### --- ###################################################################### --- ###################################################################### --- ###################################################################### --- ###################################################################### --- ###################################################################### --- ###################################################################### --- ## --- ## PAYMENTS --- ## + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- ---------------------------------------------------------------------- -- ---------------------------------------------------------------------- --- TABLE pmgr_payment_types +-- TABLE pmgr_ledger_entries -DROP TABLE IF EXISTS `pmgr_payment_types`; -CREATE TABLE `pmgr_payment_types` ( +DROP TABLE IF EXISTS `pmgr_ledger_entries`; +CREATE TABLE `pmgr_ledger_entries` ( + `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + + `name` VARCHAR(80) DEFAULT NULL, + `monetary_source_id` INT(10) UNSIGNED DEFAULT NULL, -- NULL if internal transfer + `transaction_id` INT(10) UNSIGNED NOT NULL, + `amount` FLOAT(12,2) NOT NULL, + + `debit_ledger_id` INT(10) UNSIGNED NOT NULL, + `credit_ledger_id` INT(10) UNSIGNED NOT NULL, + + `comment` VARCHAR(255) DEFAULT NULL, + + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + + +-- ---------------------------------------------------------------------- +-- ---------------------------------------------------------------------- +-- TABLE pmgr_monetary_sources + +DROP TABLE IF EXISTS `pmgr_monetary_sources`; +CREATE TABLE `pmgr_monetary_sources` ( + `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + + `name` VARCHAR(80) DEFAULT NULL, + monetary_type_id INT(10) UNSIGNED NOT NULL, + + -- REVISIT : 20090605 + -- Check Number; + -- Routing Number, Account Number; + -- Card Number, Expiration Date; CCV2 Code + -- etc. + + `comment` VARCHAR(255) DEFAULT NULL, + + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + + +-- ---------------------------------------------------------------------- +-- ---------------------------------------------------------------------- +-- TABLE pmgr_monetary_types + +DROP TABLE IF EXISTS `pmgr_monetary_types`; +CREATE TABLE `pmgr_monetary_types` ( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `name` VARCHAR(80) NOT NULL, @@ -912,180 +981,21 @@ CREATE TABLE `pmgr_payment_types` ( PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -LOCK TABLES `pmgr_payment_types` WRITE; -INSERT INTO `pmgr_payment_types` (`id`, `name`, `tillable`) +LOCK TABLES `pmgr_monetary_types` WRITE; +INSERT INTO `pmgr_monetary_types` (`id`, `name`, `tillable`) VALUES - (1, 'Cash', 1), - (2, 'Check', 1), - (3, 'Money Order', 1), - (4, 'ACH', 0), - (5, 'Debit Card', 0), - (6, 'Credit Card', 0), - (7, 'Other Tillable', 1), - (8, 'Other Non-Tillable', 0); + -- (1, 'Transfer', 0), + (2, 'Cash', 1), + (3, 'Check', 1), + (4, 'Money Order', 1), + (5, 'ACH', 0), + (6, 'Debit Card', 0), + (7, 'Credit Card', 0), + (8, 'Other Tillable', 1), + (9, 'Other Non-Tillable', 0); UNLOCK TABLES; --- ---------------------------------------------------------------------- --- ---------------------------------------------------------------------- --- TABLE pmgr_payments - -DROP TABLE IF EXISTS `pmgr_payments`; -CREATE TABLE `pmgr_payments` ( - `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, - - `receipt_id` INT(10) UNSIGNED NOT NULL, - `payment_type_id` INT(10) UNSIGNED NOT NULL, - `amount` FLOAT(12,2) NOT NULL, - - `comment` VARCHAR(255) DEFAULT NULL, - - PRIMARY KEY (`id`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - - --- ###################################################################### --- ###################################################################### --- ###################################################################### --- ###################################################################### --- ###################################################################### --- ###################################################################### --- ###################################################################### --- ###################################################################### --- ###################################################################### --- ## --- ## CREDITS --- ## - - --- ---------------------------------------------------------------------- --- ---------------------------------------------------------------------- --- TABLE pmgr_credit_types - --- DROP TABLE IF EXISTS `pmgr_credit_types`; --- CREATE TABLE `pmgr_credit_types` ( --- `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, - --- `name` VARCHAR(80) NOT NULL, --- `comment` VARCHAR(255) DEFAULT NULL, --- `account_id` INT(10) UNSIGNED NOT NULL, -- quickbooks tracking - --- PRIMARY KEY (`id`) --- ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - --- LOCK TABLES `pmgr_credit_types` WRITE; --- INSERT INTO `pmgr_credit_types` (`id`, `name`, `account_id`) --- VALUES --- (1, 'Security Deposit', 0), --- (2, 'Rent', 0), --- (3, 'Late Credit', 0); --- UNLOCK TABLES; - - --- ---------------------------------------------------------------------- --- ---------------------------------------------------------------------- --- TABLE pmgr_credits - -DROP TABLE IF EXISTS `pmgr_credits`; -CREATE TABLE `pmgr_credits` ( - `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, - - -- `credit_type_id` INT(10) UNSIGNED NOT NULL, - `lease_id` INT(10) UNSIGNED NOT NULL, - `credit_date` DATE NOT NULL, - `credit_to_date` DATE DEFAULT NULL, - `due_date` DATE DEFAULT NULL, - `amount` FLOAT(12,2) NOT NULL, - `tax` FLOAT(12,2) NOT NULL, - `total` FLOAT(12,2) NOT NULL, - `comment` VARCHAR(255) DEFAULT NULL, - - PRIMARY KEY (`id`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - --- ###################################################################### --- ###################################################################### --- ###################################################################### --- ###################################################################### --- ###################################################################### --- ###################################################################### --- ###################################################################### --- ###################################################################### --- ###################################################################### --- ## --- ## RECEIPTS --- ## - --- # Charge --- # - Issued against customer lease --- # - associated with account (i.e. QuickBooks account / category) --- # Receipt --- # - Collections of payments paid at one time --- # Payment --- # - Credited towards customer (or lease?) --- # - may be more than customer owes --- # - cash/check/charge/ach/etc --- # Reconciliation --- # - Associates a payment with the charge --- # - Indicates amount of credit towards charge --- # - Payments may cover several charges --- # - Several payments may cover the same charge - - --- Which charges haven not been paid? --- SELECT C.id AS cid, C.total AS total, COALESCE(SUM(R.amount),0) AS paid --- FROM pmgr_charges C --- LEFT JOIN pmgr_charges_receipts R ON R.charge_id = C.id --- GROUP BY C.id --- HAVING paid < C.total - --- SELECT ChL.lid AS lid, U.name, C.display_name, --- SUM(ChL.total) AS total, SUM(ChL.paid) AS paid, --- SUM(ChL.total) - SUM(ChL.paid) AS owing --- FROM (SELECT Ch.lease_id AS lid, Ch.total AS total, COALESCE(SUM(R.amount),0) AS paid --- FROM pmgr_charges Ch --- LEFT JOIN pmgr_charges_receipts R ON R.charge_id = Ch.id --- WHERE Ch.due_date < NOW() --- GROUP BY Ch.id --- HAVING paid < Ch.total) ChL --- LEFT JOIN pmgr_leases L ON L.id = ChL.lid --- LEFT JOIN pmgr_lease_contacts Lc ON Lc.lease_id = L.id AND Lc.type = 'TENANT' --- LEFT JOIN pmgr_contacts C ON C.id = Lc.contact_id --- LEFT JOIN pmgr_units U ON U.id = L.unit_id - - --- ---------------------------------------------------------------------- --- ---------------------------------------------------------------------- --- TABLE pmgr_receipts - -DROP TABLE IF EXISTS `pmgr_receipts`; -CREATE TABLE `pmgr_receipts` ( - `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, - `stamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - - `comment` VARCHAR(255) DEFAULT NULL, - - PRIMARY KEY (`id`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - --- ---------------------------------------------------------------------- --- ---------------------------------------------------------------------- --- TABLE pmgr_charges_receipts - -DROP TABLE IF EXISTS `pmgr_charges_receipts`; -CREATE TABLE `pmgr_charges_receipts` ( - `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, - `charge_id` INT(10) UNSIGNED NOT NULL, - -- REVISIT : 20090514 - -- THIS SHOULD BE RECEIPT_ID, NOT PAYMENT_ID, RIGHT?? - `receipt_id` INT(10) UNSIGNED NOT NULL, - `amount` FLOAT(12,2) NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -- ###################################################################### diff --git a/scripts/sitelink2pmgr.pl b/scripts/sitelink2pmgr.pl index 3d331b5..3badbf2 100644 --- a/scripts/sitelink2pmgr.pl +++ b/scripts/sitelink2pmgr.pl @@ -26,9 +26,12 @@ my($hostname, $database, $user, $password) = ('localhost', 'pmgr', 'pmgruser'); my $db_handle = DBI->connect("DBI:mysql:database=$database;host=$hostname", $user, $password, - {'RaiseError' => 1}); + {'PrintError' => 1, + 'RaiseError' => 0}); +$SIG{__DIE__} = \&Die; + my ($query, $result, $nrows, $row); my ($aicur_c_id, $aicur_ca_id, $aicur_cp_id, $aicur_ce_id) = (0, 0, 0, 0); my ($aicur_g_id, $aicur_gp_id, $aicur_user_id) = (0, 0, 0); @@ -36,6 +39,9 @@ my ($aicur_type_id, $aicur_size_id, $aicur_unit_id) = (0, 0, 0); my ($aicur_site_id, $aicur_area_id) = (0, 0); my ($aicur_lease_type_id, $aicur_lease_id) = (0, 0); my ($aicur_charge_id, $aicur_receipt_id, $aicur_payment_id) = (0, 0, 0); +my ($aicur_tx_id) = (0); +my ($aicur_ledger_id) = (0); +my ($aicur_monetary_source_id) = (0); open(SCHEMA, "<$schema_file") || die ("Can't open schema ($!)\n"); my $schema_query = ""; @@ -224,14 +230,93 @@ $query = "INSERT INTO pmgr_lease_types query($db_handle, $query) || die("Unable to insert"); +my (%account_map, %monetary_type_map); +$query = "SELECT * FROM pmgr_accounts"; +$result = query($db_handle, $query); +foreach $row (@$result) { + ++$aicur_ledger_id; + $query = "INSERT INTO pmgr_ledgers + (`id`, `account_id`, `name`, `comment`) VALUES (" . + join(", ", map({defined $_ ? "'$_'" : "NULL"} + ($aicur_ledger_id, $row->{'id'}, + $row->{'name'} . ' Ledger', undef) + )) . ")"; + query($db_handle, $query) || die("Unable to insert"); + $account_map{$row->{'name'}} = {'id' => $row->{'id'}, + 'ledger' => $aicur_ledger_id }; +} + +# $query = +# "UPDATE pmgr_accounts A, pmgr_ledgers L SET A.ledger_id = L.id" . +# " WHERE A.id = L.account_id"; +# query($db_handle, $query); + + +$query = "SELECT * FROM pmgr_monetary_types"; +$result = query($db_handle, $query); +foreach $row (@$result) { + $monetary_type_map{$row->{'name'}} = {'id' => $row->{'id'}, 'name' => $row->{'name'}}; +} + +$account_map{'Late Fee'} = $account_map{'Late Charge'}; + +$monetary_type_map{1} = $monetary_type_map{'Cash'}; +$monetary_type_map{2} = $monetary_type_map{'Check'}; +$monetary_type_map{3} = $monetary_type_map{'Money Order'}; +$monetary_type_map{4} = $monetary_type_map{'ACH'}; +$monetary_type_map{12} = $monetary_type_map{'Other Non-Tillable'}; + +my $monetary_source_internal = undef; + +my $monetary_source_cash = ++$aicur_monetary_source_id; +$query = "INSERT INTO pmgr_monetary_sources + (`id`, `monetary_type_id`, `name`, `comment`) VALUES (" . + join(", ", map({defined $_ ? "'$_'" : "NULL"} + ($monetary_source_cash, + $monetary_type_map{'Cash'}{'id'}, + 'Cash Source', + 'Monetary source used for any cash transaction') + )) . ")"; +query($db_handle, $query) || die("Unable to insert"); + +my $monetary_source_closing = ++$aicur_monetary_source_id; +$query = "INSERT INTO pmgr_monetary_sources + (`id`, `monetary_type_id`, `name`, `comment`) VALUES (" . + join(", ", map({defined $_ ? "'$_'" : "NULL"} + ($monetary_source_closing, + $monetary_type_map{'Other Non-Tillable'}{'id'}, + 'Closing Monies Credited', + 'Credited at the closing table') + )) . ")"; +query($db_handle, $query) || die("Unable to insert"); + + +###################################################################### +###################################################################### +## Die + +sub Die { + my @text = @_; + warn "----------------------------------------------------------\n"; + warn "FATAL ERROR: @text\n"; + my $count = 0; + { + my ($package, $filename, $line, $sub) = caller($count); + last unless defined $line; + warn sprintf("%02i %5i %-35s %-20s\n", $count++, $line, $sub, + $filename); + redo; + } + exit 1; +} ###################################################################### ###################################################################### ## query sub query { - my ($dbh, $sql) = @_; + my ($dbh, $sql, $data, $ignore) = @_; #print("$sql\n\n"); #return [ { 'id' => 7 } ]; #print("$sql\n\n") if $sql =~ /^\s*UPDATE/i; #return 1 unless $sql =~ /^\s*SELECT/i; @@ -245,8 +330,13 @@ sub query { $result = $dbh->do($sql); } - #print("sth = " . Dumper($sth) . "\n"); - #print("result = " . Dumper($result) . "\n"); + if (!$result && !$ignore) { + print "SQL Query FAILED:\n"; + print "$query\n\n"; + print Dumper $data + if defined $data; + die; + } return ($sth, $result); } @@ -292,7 +382,7 @@ foreach $row (@$result) { (`id`, `code`, `name`) VALUES ($row->{'TypeID'}, 'xxx', '$row->{'UnitType'}')"; - query($db_handle, $query) || die("Unable to insert"); + query($db_handle, $query, $row); } @@ -323,7 +413,7 @@ foreach $row (@$result) { $internal_adjustment_factor * $row->{'Depth'}, $row->{'StdSecDep'}, $row->{'StdRent'}) )) . ")"; - query($db_handle, $query) || die("Unable to insert"); + query($db_handle, $query, $row); } @@ -347,7 +437,7 @@ foreach $row (@$result) { $row->{'Rented'} ?'OCCUPIED' :($row->{'Rentable'} ?'VACANT' :'UNAVAILABLE'), $uid, $uid, $row->{'StdSecDep'}, $row->{'StdRent'}) )) . ")"; - query($db_handle, $query) || die("Unable to insert"); + query($db_handle, $query, $row); } @@ -380,7 +470,7 @@ $query = " (1, 'Main Facility Map', $aicur_area_id," . ($info{'extents'}{'right'} - $info{'extents'}{'left'}) . ", " . ($info{'extents'}{'bottom'} - $info{'extents'}{'top'}) . ")"; -query($db_handle, $query) || die("Unable to insert"); +query($db_handle, $query, \%info); # Get list of units and positions $query = "SELECT U.UnitID, U.UnitID as name,"; @@ -405,7 +495,7 @@ foreach $row (@$result) { $internal_adjustment_factor * ($row->{'pt_t'}), $internal_adjustment_factor * ($row->{'pt_l'}), $row->{'reverseWL'}) . ")"; - query($db_handle, $query) || die("Unable to insert"); + query($db_handle, $query, $row); } @@ -431,8 +521,12 @@ print(" $nrows Tenants\n"); my %stmap = ( 1=>'AK', 14=>'ID', 48=>'WA' ); my (%tenant_map); foreach $row (@$result) { - $tenant_map{$row->{'TenantID'}} = { 'id' => ++$aicur_c_id }; - my $cid = $tenant_map{$row->{'TenantID'}}{'id'}; + $tenant_map{$row->{'TenantID'}} = { 'cid' => ++$aicur_c_id }; + my $cid = $tenant_map{$row->{'TenantID'}}{'cid'}; + $tenant_map{$row->{'TenantID'}}{'custid'} = $cid; + my $custid = $tenant_map{$row->{'TenantID'}}{'custid'}; + + $tenant_map{$row->{'TenantID'}}{'name'} = "$row->{'LastName'}, $row->{'FirstName'}"; $query = "INSERT INTO pmgr_contacts (`id`, `first_name`, `middle_name`, `last_name`, `display_name`, `id_local`, `id_local_state`) @@ -442,7 +536,23 @@ foreach $row (@$result) { "$row->{'LastName'}, $row->{'FirstName'}", $row->{'IDNum'} || undef, $row->{'IDNum'} ? $stmap{$row->{'DLStateID'}} : undef) )) . ")"; - query($db_handle, $query) || die("Unable to insert"); + query($db_handle, $query, $row); + + $query = "INSERT INTO pmgr_customers + (`id`, `name`) + VALUES (" . + join(", ", map({defined $_ ? "'$_'" : "NULL"} + ($custid, "$row->{'LastName'}, $row->{'FirstName'}") + )) . ")"; + query($db_handle, $query, $row); + + $query = "INSERT INTO pmgr_contacts_customers + (`customer_id`, `contact_id`, `type`) + VALUES (" . + join(", ", map({defined $_ ? "'$_'" : "NULL"} + ($custid, $cid, 'TENANT') + )) . ")"; + query($db_handle, $query, $row); if ($row->{'City'}) { $query = "INSERT INTO pmgr_contact_addresses @@ -454,12 +564,12 @@ foreach $row (@$result) { $row->{'HomeAddress'} . ($row->{'HomeAddr2'} ? "\n".$row->{'HomeAddr2'} : "") || undef, $row->{'City'}, $stmap{$row->{'StateID'}}, $row->{'Zip'} || undef, 'USA') )) . ")"; - query($db_handle, $query) || die("Unable to insert"); + query($db_handle, $query, $row); $query = "INSERT INTO pmgr_contacts_methods (`contact_id`, `method`, `method_id`, `type`, `preference`) VALUES ($cid, 'POST', $aicur_ca_id, 'HOME', 'PRIMARY')"; - query($db_handle, $query) || die("Unable to insert"); + query($db_handle, $query, $row); } foreach ({'type' => 'LANDLINE', 'preference' => 'PRIMARY', 'phone' => $row->{'Phone'}}, @@ -475,14 +585,14 @@ foreach $row (@$result) { join(", ", map({defined $_ ? "'$_'" : "NULL"} (++$aicur_cp_id, $_->{'type'}, $_->{'phone'}, $_->{'ext'}))) . ")"; - query($db_handle, $query) || die("Unable to insert"); + query($db_handle, $query, $row); $query = "INSERT INTO pmgr_contacts_methods (`contact_id`, `method`, `method_id`, `type`, `preference`) VALUES (" . join(", ", map({defined $_ ? "'$_'" : "NULL"} ($cid, 'PHONE', $aicur_cp_id, 'MAIN', $_->{'preference'}))) . ")"; - query($db_handle, $query) || die("Unable to insert"); + query($db_handle, $query, $row); } } @@ -490,12 +600,12 @@ foreach $row (@$result) { $query = "INSERT INTO pmgr_contact_emails (`id`, `email`) VALUES (".++$aicur_ce_id.", '$row->{'Email'}')"; - query($db_handle, $query) || die("Unable to insert"); + query($db_handle, $query, $row); $query = "INSERT INTO pmgr_contacts_methods (`contact_id`, `method`, `method_id`, `type`, `preference`) VALUE ($cid, 'EMAIL', $aicur_ce_id, 'MAIN', 'PRIMARY')"; - query($db_handle, $query) || die("Unable to insert"); + query($db_handle, $query, $row); } next unless $row->{'AltFirstName'} || $row->{'AltLastName'} || $row->{'AltAddress'} || $row->{'AltPhone'}; @@ -515,7 +625,15 @@ foreach $row (@$result) { ? "$row->{'AltLastName'}, $row->{'AltFirstName'}" : ($row->{'AltLastName'} || $row->{'AltFirstName'} || undef))) )) . ")"; - query($db_handle, $query) || die("Unable to insert"); + query($db_handle, $query, $row); + + $query = "INSERT INTO pmgr_contacts_customers + (`customer_id`, `contact_id`, `type`) + VALUES (" . + join(", ", map({defined $_ ? "'$_'" : "NULL"} + ($custid, $cid, 'ALTERNATE') + )) . ")"; + query($db_handle, $query, $row); if ($row->{'AltCity'}) { $query = "INSERT INTO pmgr_contact_addresses @@ -526,12 +644,12 @@ foreach $row (@$result) { $row->{'AltAddress'} . ($row->{'AltAddr2'} ? "\n".$row->{'AltAddr2'} : ""), $row->{'AltCity'}, $stmap{$row->{'AltStateID'}}, $row->{'AltZip'}, 'USA') )) . ")"; - query($db_handle, $query) || die("Unable to insert"); + query($db_handle, $query, $row); $query = "INSERT INTO pmgr_contacts_methods (`contact_id`, `method`, `method_id`, `type`, `preference`) VALUES ($cid, 'POST', $aicur_ca_id, 'MAIN', 'PRIMARY')"; - query($db_handle, $query) || die("Unable to insert"); + query($db_handle, $query, $row); } if ($row->{'AltPhone'}) { @@ -540,12 +658,12 @@ foreach $row (@$result) { join(", ", map({defined $_ ? "'$_'" : "NULL"} (++$aicur_cp_id, 'LANDLINE', $row->{'AltPhone'}, undef) )) . ")"; - query($db_handle, $query) || die("Unable to insert"); + query($db_handle, $query, $row); $query = "INSERT INTO pmgr_contacts_methods (`contact_id`, `method`, `method_id`, `type`, `preference`) VALUES ($cid, 'PHONE', $aicur_cp_id, 'MAIN', 'PRIMARY')"; - query($db_handle, $query) || die("Unable to insert"); + query($db_handle, $query, $row); } } @@ -559,45 +677,33 @@ $nrows = @$result; print(" $nrows Tenant Ledgers\n"); my (%ledger_map); foreach $row (@$result) { - $ledger_map{$row->{'LedgerID'}} = ++$aicur_lease_id; - my $cid = $tenant_map{$row->{'TenantID'}}{'id'}; + $ledger_map{$row->{'LedgerID'}} = { 'lid' => ++$aicur_lease_id }; + my $cid = $tenant_map{$row->{'TenantID'}}{'cid'}; my $uid = $unit_map{$row->{'UnitID'}}; - my $lid = $ledger_map{$row->{'LedgerID'}}; + my $lid = $ledger_map{$row->{'LedgerID'}}{'lid'}; + my $custid = $tenant_map{$row->{'TenantID'}}{'custid'}; + $ledger_map{$row->{'LedgerID'}}{'custid'} = $custid; $query = "INSERT INTO pmgr_leases - (`id`, `number`, `lease_type_id`, `unit_id`, + (`id`, `number`, `lease_type_id`, `unit_id`, `customer_id`, `lease_date`, `movein_date`, `moveout_date`, `close_date`, `amount`) VALUES (" . join(", ", map({defined $_ ? "'$_'" : "NULL"} - ($lid, $row->{'LedgerID'}, $aicur_lease_type_id, $uid, + ($lid, $row->{'LedgerID'}, $aicur_lease_type_id, $uid, $custid, datefmt($row->{'DateIn'}), datefmt($row->{'DateIn'}), datefmt($row->{'DateOut'}), datefmt($row->{'DateClosed'}), $row->{'Rent'}) )) . ")"; - query($db_handle, $query) || die("Unable to insert"); - - $query = "INSERT INTO pmgr_contacts_leases - (`lease_id`, `contact_id`, `type`) - VALUES (" . - join(", ", map({defined $_ ? "'$_'" : "NULL"} - ($lid, $cid, 'TENANT') - )) . ")"; - query($db_handle, $query) || die("Unable to insert"); - - $cid = $tenant_map{$row->{'TenantID'}}{'alt'}; - next unless $cid; - - $query = "INSERT INTO pmgr_contacts_leases - (`lease_id`, `contact_id`, `type`) - VALUES (" . - join(", ", map({defined $_ ? "'$_'" : "NULL"} - ($lid, $cid, 'ALTERNATE') - )) . ")"; - query($db_handle, $query) || die("Unable to insert"); + query($db_handle, $query, $row); } +$query = "UPDATE pmgr_units U, pmgr_leases L + SET U.`current_lease_id` = L.id + WHERE L.unit_id = U.id AND L.close_date IS NULL"; +query($db_handle, $query); + ###################################################################### ## Security Deposits @@ -612,7 +718,7 @@ foreach $row (@$result) { $query = "UPDATE pmgr_leases SET deposit = $row->{'ChargeAmount'} WHERE `number` = '$row->{'LedgerID'}'"; - query($db_handle, $query) || die("Unable to update"); + query($db_handle, $query, $row); } @@ -634,69 +740,116 @@ $result = query($sdbh, $query); $nrows = @$result; print(" $nrows Charges\n"); -my %charge_type_map = ('Rent' => 2, 'Security Deposit' => 1, 'Late Fee' => 3); my %charge_map; foreach $row (@$result) { - $charge_map{$row->{'ChargeID'}} = ++$aicur_charge_id; - my $lid = $ledger_map{$row->{'LedgerID'}}; + $charge_map{$row->{'ChargeID'}} = ++$aicur_tx_id; + my $lid = $ledger_map{$row->{'LedgerID'}}{'lid'}; my $chid = $charge_map{$row->{'ChargeID'}}; + my $custid = $ledger_map{$row->{'LedgerID'}}{'custid'}; + - $query = "INSERT INTO pmgr_charges - (`id`, `charge_type_id`, `lease_id`, - `charge_date`, `charge_to_date`, - `amount`, `tax`, `total`, `comment`) + $query = "INSERT INTO pmgr_transactions + (`id`, + `stamp`, `through_date`, + `customer_id`) VALUES (" . join(", ", map({defined $_ ? "'$_'" : "NULL"} - ($chid, $charge_type_map{$row->{'ChargeDescription'}}, $lid, + ($chid, datefmt($row->{'ChargeDate'}), datefmt($row->{'EndDate'}), - $row->{'ChargeAmount'}, $row->{'TaxAmount'}, - $row->{'ChargeAmount'} + $row->{'TaxAmount'}, - undef) + $custid) )) . ")"; - query($db_handle, $query) || die("Unable to insert"); + query($db_handle, $query, $row); - $query = "UPDATE pmgr_charges"; - $query .= " SET due_date = DATE_ADD(charge_date, INTERVAL IF(charge_type_id=2,10,0) DAY)"; - query($db_handle, $query) || die("Unable to update"); + $query = "INSERT INTO pmgr_ledger_entries + (`monetary_source_id`, `transaction_id`, + `debit_ledger_id`, + `credit_ledger_id`, + `amount`, `comment`) + VALUES (" . + join(", ", map({defined $_ ? "'$_'" : "NULL"} + ($monetary_source_internal, $chid, + $account_map{'A/R'}{'ledger'}, + $account_map{$row->{'ChargeDescription'}}{'ledger'}, + $row->{'ChargeAmount'}, "Charge: $row->{'ChargeID'}; Ledger: $row->{'LedgerID'}") + )) . ")"; + query($db_handle, $query, $row); + + next unless $row->{'TaxAmount'}; + + $query = "INSERT INTO pmgr_ledger_entries + (`monetary_source_id`, `transaction_id`, + `debit_ledger_id`, + `credit_ledger_id`, + `amount`, `comment`) + VALUES (" . + join(", ", map({defined $_ ? "'$_'" : "NULL"} + ($monetary_source_internal, $chid, + $account_map{'A/R'}{'ledger'}, + $account_map{'Tax'}{'ledger'}, + $row->{'TaxAmount'}, undef) + )) . ")"; + query($db_handle, $query, $row); + + +# $query = "UPDATE pmgr_charges"; +# $query .= " SET due_date = DATE_ADD(charge_date, INTERVAL IF(account_id=2,10,0) DAY)"; +# query($db_handle, $query); } ###################################################################### ## Receipts -$query = "SELECT * FROM Receipts ORDER BY ReceiptNum"; +#$query = "SELECT * FROM Receipts ORDER BY ReceiptNum"; +$query = + "SELECT R.ReceiptNum, C.LedgerID, R.ReceiptDate" . + " FROM Receipts R, Payments P, Charges C" . + " WHERE P.ReceiptNum = R.ReceiptNum" . + " AND C.ChargeID = P.ChargeID" . + " GROUP BY R.ReceiptNum, C.LedgerID, R.ReceiptDate" . + " ORDER BY R.ReceiptNum"; $result = query($sdbh, $query); $nrows = @$result; print(" $nrows Receipts\n"); my %receipt_map; foreach $row (@$result) { - $receipt_map{$row->{'ReceiptNum'}} = ++$aicur_receipt_id; - my $lid = $ledger_map{$row->{'LedgerID'}}; - my $rid = $receipt_map{$row->{'ReceiptNum'}}; + #print Dumper $row; + my $lid = $ledger_map{$row->{'LedgerID'}}{'lid'}; + my $custid = $ledger_map{$row->{'LedgerID'}}{'custid'}; - $query = "INSERT INTO pmgr_receipts - (`id`, `stamp`, `comment`) + if ($receipt_map{$row->{'ReceiptNum'}}) { + die unless $receipt_map{$row->{'ReceiptNum'}}{'cust'} == $custid; + push(@{$receipt_map{$row->{'ReceiptNum'}}{'lid'}}, $lid); + #print Dumper $receipt_map{$row->{'ReceiptNum'}}; + next; + } + + $receipt_map{$row->{'ReceiptNum'}} = { 'id' => ++$aicur_tx_id, 'cust' => $custid, 'lid' => [$lid] }; + my $rid = $receipt_map{$row->{'ReceiptNum'}}{'id'}; + #print Dumper $receipt_map{$row->{'ReceiptNum'}}; + + $query = "INSERT INTO pmgr_transactions + (`id`, + `stamp`, `through_date`, + `customer_id`) VALUES (" . join(", ", map({defined $_ ? "'$_'" : "NULL"} - ($rid, datefmt($row->{'ReceiptDate'}), undef) + ($rid, + datefmt($row->{'ReceiptDate'}), undef, + $custid) )) . ")"; - query($db_handle, $query) || die("Unable to insert"); + query($db_handle, $query, $row); } -# $query = "SELECT * FROM Receipts R INNER JOIN Payments P ON P.ReceiptNum = R.ReceiptNum" . -# " WHERE P.PaymentDate <> R.ReceiptDate"; -# $result = query($sdbh, $query); -# $nrows = @$result; -# print(" $nrows Mismatches\n"); -# foreach $row (@$result) { -# my @keys = qw(PaymentID P.ReceiptNum PaymentDate ReceiptDate); -# print("Payment Date Mismatch:\n"); -# print(" ", -# join("\n ", map({sprintf("%-12s => %s", $_, $row->{$_})} @keys)), -# "\n"); -# } +# sub idkeys { [ sort( {$a <=> $b} keys(%{$_[0]})) ] } +# $Data::Dumper::Sortkeys = \&idkeys; +# print("Tenant\n"); print Dumper \%tenant_map; +# print("Ledger\n"); print Dumper \%ledger_map; +# print("Charge\n"); print Dumper \%charge_map; +# print("Receipt\n"); print Dumper \%receipt_map; + ###################################################################### ## Payments @@ -710,274 +863,254 @@ my %payment_map; foreach $row (@$result) { $payment_map{$row->{'PaymentID'}} = ++$aicur_payment_id; my $pid = $payment_map{$row->{'PaymentID'}}; - my $rid = $receipt_map{$row->{'ReceiptNum'}}; + my $rid = $receipt_map{$row->{'ReceiptNum'}}{'id'}; my $chid = $charge_map{$row->{'ChargeID'}}; - $query = "INSERT INTO pmgr_payments - (`id`, `receipt_id`, `payment_type_id`, `amount`, `comment`) - VALUES (" . - join(", ", map({defined $_ ? "'$_'" : "NULL"} - ($pid, $rid, - $row->{'PaymentDate'} =~ m%3/25/2009% ? 8 : $row->{'PaymentType'}, - $row->{'PaymentAmount'}, undef) + my $monetary_source_id; + if ($row->{'PaymentDate'} =~ m%3/25/2009%) { + $monetary_source_id = $monetary_source_closing; + } + elsif ($monetary_type_map{$row->{'PaymentType'}}{'name'} eq 'Cash') { + $monetary_source_id = $monetary_source_cash; + } + else { + $monetary_source_id = ++$aicur_monetary_source_id; + $query = "INSERT INTO pmgr_monetary_sources + (`id`, `monetary_type_id`, `name`, `comment`) VALUES (" . + join(", ", map({defined $_ ? "'$_'" : "NULL"} + ($monetary_source_id, + $monetary_type_map{$row->{'PaymentType'}}{'id'}, + $row->{'RecdFrom'}, + "Payment: $row->{'PaymentID'}; Type: $row->{'PaymentType'}; Check: $row->{'CheckNum'}; $row->{'Memo'}") )) . ")"; - query($db_handle, $query) || die("Unable to insert"); + query($db_handle, $query) || die("Unable to insert"); + } - $query = "INSERT INTO pmgr_charges_receipts - (`charge_id`, `receipt_id`, `amount`) - VALUES (" . - join(", ", map({defined $_ ? "'$_'" : "NULL"} - ($chid, $rid, $row->{'PaymentAmount'}) - )) . ")"; - query($db_handle, $query) || die("Unable to insert"); + $query = "INSERT INTO pmgr_ledger_entries + (`monetary_source_id`, + `transaction_id`, + `debit_ledger_id`, + `credit_ledger_id`, + `amount`, `comment`) + VALUES (" . + join(", ", map({defined $_ ? "'$_'" : "NULL"} + ($monetary_source_id, + $rid, + $account_map{'Cash'}{'ledger'}, + $account_map{'A/R'}{'ledger'}, + $row->{'PaymentAmount'}, + "Receipt: $row->{'ReceiptNum'}; Payment: $row->{'PaymentID'}; Charge: $row->{'ChargeID'}") + )) . ")"; + query($db_handle, $query, $row); if ($row->{'Memo'}) { $query = - "UPDATE pmgr_receipts SET `comment` = '$row->{'Memo'}'" . + "UPDATE pmgr_transactions SET `comment` = '$row->{'Memo'}'" . " WHERE `id` = $rid"; - query($db_handle, $query) || die("Unable to update"); + query($db_handle, $query, $row); } } - - $query = "INSERT INTO pmgr_charges - (`id`, `charge_type_id`, `lease_id`, - `charge_date`, `charge_to_date`, - `amount`, `tax`, `total`, `comment`) - VALUES (" . - join(", ", map({defined $_ ? "'$_'" : "NULL"} - (1000, $charge_type_map{'Security Deposit'}, 17, - '2009-05-05', undef, - 10, 0, 10, - 'Fake security deposit for testing purposes') - )) . ")"; - query($db_handle, $query) || die("Unable to insert"); - - $query = "INSERT INTO pmgr_charges - (`id`, `charge_type_id`, `lease_id`, - `charge_date`, `charge_to_date`, - `amount`, `tax`, `total`, `comment`) - VALUES (" . - join(", ", map({defined $_ ? "'$_'" : "NULL"} - (1001, $charge_type_map{'Rent'}, 17, - '2009-05-01', '2009-05-31', - 100, 5, 105, - 'Fake charge for testing purposes') - )) . ")"; - query($db_handle, $query) || die("Unable to insert"); - - $query = "INSERT INTO pmgr_charges - (`id`, `charge_type_id`, `lease_id`, - `charge_date`, `charge_to_date`, - `amount`, `tax`, `total`, `comment`) - VALUES (" . - join(", ", map({defined $_ ? "'$_'" : "NULL"} - (1002, $charge_type_map{'Late Fee'}, 17, - '2009-05-11', undef, - 25, 0, 25, - 'Fake late charge for testing purposes') - )) . ")"; - query($db_handle, $query) || die("Unable to insert"); - - $query = "INSERT INTO pmgr_receipts - (`id`, `stamp`, `comment`) - VALUES (" . - join(", ", map({defined $_ ? "'$_'" : "NULL"} - (2000, '2009-05-15', 'Fake receipt #1') - )) . ")"; - query($db_handle, $query) || die("Unable to insert"); - - $query = "INSERT INTO pmgr_payments - (`id`, `receipt_id`, `payment_type_id`, `amount`, `comment`) - VALUES (" . - join(", ", map({defined $_ ? "'$_'" : "NULL"} - (3000, 2000, 1, 15, 'Fake receipt #1 payment #1') - )) . ")"; - query($db_handle, $query) || die("Unable to insert"); - - $query = "INSERT INTO pmgr_payments - (`id`, `receipt_id`, `payment_type_id`, `amount`, `comment`) - VALUES (" . - join(", ", map({defined $_ ? "'$_'" : "NULL"} - (3001, 2000, 2, 10, 'Fake receipt #1 payment #2') - )) . ")"; - query($db_handle, $query) || die("Unable to insert"); - - $query = "INSERT INTO pmgr_payments - (`id`, `receipt_id`, `payment_type_id`, `amount`, `comment`) - VALUES (" . - join(", ", map({defined $_ ? "'$_'" : "NULL"} - (3002, 2000, 3, 5, 'Fake receipt #1 payment #3') - )) . ")"; - query($db_handle, $query) || die("Unable to insert"); - - $query = "INSERT INTO pmgr_charges_receipts - (`charge_id`, `receipt_id`, `amount`) - VALUES (" . - join(", ", map({defined $_ ? "'$_'" : "NULL"} - (1000, 2000, 10) - )) . ")"; - query($db_handle, $query) || die("Unable to insert"); - - $query = "INSERT INTO pmgr_charges_receipts - (`charge_id`, `receipt_id`, `amount`) - VALUES (" . - join(", ", map({defined $_ ? "'$_'" : "NULL"} - (1001, 2000, 20) - )) . ")"; - query($db_handle, $query) || die("Unable to insert"); - - - $query = "INSERT INTO pmgr_receipts - (`id`, `stamp`, `comment`) - VALUES (" . - join(", ", map({defined $_ ? "'$_'" : "NULL"} - (2100, '2009-05-18', 'Fake receipt #2') - )) . ")"; - query($db_handle, $query) || die("Unable to insert"); - - $query = "INSERT INTO pmgr_payments - (`id`, `receipt_id`, `payment_type_id`, `amount`, `comment`) - VALUES (" . - join(", ", map({defined $_ ? "'$_'" : "NULL"} - (3100, 2100, 5, 30, 'Fake receipt #2 payment #1') - )) . ")"; - query($db_handle, $query) || die("Unable to insert"); - - $query = "INSERT INTO pmgr_payments - (`id`, `receipt_id`, `payment_type_id`, `amount`, `comment`) - VALUES (" . - join(", ", map({defined $_ ? "'$_'" : "NULL"} - (3101, 2100, 6, 20, 'Fake receipt #2 payment #2') - )) . ")"; - query($db_handle, $query) || die("Unable to insert"); - - $query = "INSERT INTO pmgr_charges_receipts - (`charge_id`, `receipt_id`, `amount`) - VALUES (" . - join(", ", map({defined $_ ? "'$_'" : "NULL"} - (1001, 2100, 50) - )) . ")"; - query($db_handle, $query) || die("Unable to insert"); - - - $query = "INSERT INTO pmgr_receipts - (`id`, `stamp`, `comment`) - VALUES (" . - join(", ", map({defined $_ ? "'$_'" : "NULL"} - (2200, '2009-05-22', 'Fake receipt #3') - )) . ")"; - query($db_handle, $query) || die("Unable to insert"); - - $query = "INSERT INTO pmgr_payments - (`id`, `receipt_id`, `payment_type_id`, `amount`, `comment`) - VALUES (" . - join(", ", map({defined $_ ? "'$_'" : "NULL"} - (3200, 2200, 1, 10, 'Fake receipt #3 payment #1') - )) . ")"; - query($db_handle, $query) || die("Unable to insert"); - - $query = "INSERT INTO pmgr_payments - (`id`, `receipt_id`, `payment_type_id`, `amount`, `comment`) - VALUES (" . - join(", ", map({defined $_ ? "'$_'" : "NULL"} - (3201, 2200, 2, 5, 'Fake receipt #3 payment #2') - )) . ")"; - query($db_handle, $query) || die("Unable to insert"); - - $query = "INSERT INTO pmgr_payments - (`id`, `receipt_id`, `payment_type_id`, `amount`, `comment`) - VALUES (" . - join(", ", map({defined $_ ? "'$_'" : "NULL"} - (3202, 2200, 7, 20, 'Fake receipt #3 payment #3') - )) . ")"; - query($db_handle, $query) || die("Unable to insert"); - - $query = "INSERT INTO pmgr_payments - (`id`, `receipt_id`, `payment_type_id`, `amount`, `comment`) - VALUES (" . - join(", ", map({defined $_ ? "'$_'" : "NULL"} - (3203, 2200, 8, 15, 'Fake receipt #3 payment #4') - )) . ")"; - query($db_handle, $query) || die("Unable to insert"); - - $query = "INSERT INTO pmgr_charges_receipts - (`charge_id`, `receipt_id`, `amount`) - VALUES (" . - join(", ", map({defined $_ ? "'$_'" : "NULL"} - (1001, 2200, 35) - )) . ")"; - query($db_handle, $query) || die("Unable to insert"); - - $query = "INSERT INTO pmgr_charges_receipts - (`charge_id`, `receipt_id`, `amount`) - VALUES (" . - join(", ", map({defined $_ ? "'$_'" : "NULL"} - (1002, 2200, 15) - )) . ")"; - query($db_handle, $query) || die("Unable to insert"); - - -__END__ - ###################################################################### -## Reconciliations +## Fake Data for Testing -# $query = "SELECT ReceiptNum, SUM(PaymentAmount) AS 'rTot'"; -# $query .= " FROM Payments GROUP BY ReceiptNum, ORDER BY ReceiptNum"; -$query = "SELECT ChargeID, ReceiptNum"; -$query .= " FROM Payments GROUP BY ChargeID, ReceiptNum ORDER BY ChargeID, ReceiptNum"; -$result = query($sdbh, $query); -$nrows = @$result; -print(" $nrows Reconciliations\n"); +my %fake = + ('custid' => 2, + 'invoice' => [ { 'id' => 1000, + 'date' => '2009-05-05', + 'entry' => [ { 'id' => 2100, + 'account' => 'Security Deposit', + 'amount' => 10, + 'tax' => 0 }, + ], + }, + { 'id' => 1001, + 'date' => '2009-05-01', + 'thru' => '2009-05-31', + 'entry' => [ { 'id' => 2110, + 'account' => 'Rent', + 'amount' => 100, + 'tax' => 5 }, + ], + }, + { 'id' => 1002, + 'date' => '2009-05-11', + 'entry' => [ { 'id' => 2120, + 'account' => 'Late Fee', + 'amount' => 25, + 'tax' => 0 }, + ], + }, + ], + 'receipt' => [ { 'id' => 2000, + 'date' => '2009-05-15', + 'entry' => [ { 'id' => 2200, + 'type' => 1, + 'amount' => 15 }, + { 'id' => 2201, + 'type' => 2, + 'amount' => 10 }, + { 'id' => 2202, + 'type' => 3, + 'amount' => 5 }, + ], + }, + { 'id' => 2001, + 'date' => '2009-05-18', + 'entry' => [ { 'id' => 2210, + 'type' => 5, + 'amount' => 30 }, + { 'id' => 2211, + 'type' => 6, + 'amount' => 20 }, + ], + }, + { 'id' => 2002, + 'date' => '2009-05-22', + 'entry' => [ { 'id' => 2220, + 'type' => 1, + 'amount' => 10 }, + { 'id' => 2221, + 'type' => 2, + 'amount' => 5 }, + { 'id' => 2222, + 'type' => 7, + 'amount' => 20 }, + { 'id' => 2223, + 'type' => 8, + 'amount' => 15 }, + ], + }, + ], -foreach $row (@$result) { - my $chid = $charge_map{$row->{'ChargeID'}}; - my $rid = $receipt_map{$row->{'ReceiptNum'}}; + ); - $query = "INSERT INTO pmgr_charges_receipts - (`charge_id`, `receipt_id`, `amount`) - VALUES (" . - join(", ", map({defined $_ ? "'$_'" : "NULL"} - ($chid, $rid, 0) - )) . ")"; - query($db_handle, $query) || die("Unable to insert"); +my $old_cash_ledger = $account_map{'Cash'}{'ledger'}; +my $new_cash_ledger = ++$aicur_ledger_id; +$account_map{'Cash'}{'ledger'} = $new_cash_ledger; +$query = "INSERT INTO pmgr_ledgers + (`id`, `account_id`, `name`, `comment`) VALUES (" . + join(", ", map({defined $_ ? "'$_'" : "NULL"} + ($new_cash_ledger, $account_map{'Cash'}{'id'}, + 'Fake Cash Ledger', 'Fake ledger for testing') + )) . ")"; +query($db_handle, $query) || die("Unable to insert"); + +$query = +"SELECT + SUM(IF(LedgerEntry.debit_ledger_id = Ledger.id, LedgerEntry.amount, 0)) AS debits, + SUM(IF(LedgerEntry.credit_ledger_id = Ledger.id, LedgerEntry.amount, 0)) AS credits, + SUM(IF(Account.type IN ('ASSET', 'EXPENSE'), + IF(LedgerEntry.debit_ledger_id = Ledger.id, 1, -1), + IF(LedgerEntry.credit_ledger_id = Ledger.id, 1, -1) ) + * LedgerEntry.amount) AS balance, + COUNT(`LedgerEntry`.`id`) AS entries +FROM + `pmgr_ledgers` AS `Ledger` + LEFT JOIN `pmgr_accounts` AS `Account` + ON (`Account`.`id` = `Ledger`.`account_id`) + LEFT JOIN `pmgr_ledger_entries` AS `LedgerEntry` + ON (((`LedgerEntry`.`debit_ledger_id` = Ledger.id) + OR (`LedgerEntry`.`credit_ledger_id` = Ledger.id))) +WHERE `Ledger`.`id` = $old_cash_ledger +GROUP BY `Ledger`.`id` LIMIT 1"; +$result = query($db_handle, $query); +my $balance = $result->[0]{'balance'}; + +$query = "INSERT INTO pmgr_transactions + (`id`, `customer_id`, `stamp`) + VALUES (" . + join(", ", map({defined $_ ? "'$_'" : "NULL"} + (++$aicur_tx_id, 0, + '2009-05-10') + )) . ")"; +query($db_handle, $query); + +$query = "INSERT INTO pmgr_ledger_entries + (`monetary_source_id`, `transaction_id`, + `debit_ledger_id`, + `credit_ledger_id`, + `amount`, + `name`, + `comment`) + VALUES (" . + join(", ", map({defined $_ ? "'$_'" : "NULL"} + ($monetary_source_internal, $aicur_tx_id, + $new_cash_ledger, + $old_cash_ledger, + $balance, + "Close Out ($old_cash_ledger -> $new_cash_ledger)", + "Carrying forward old ledger balance onto new ledger") + )) . ")"; +query($db_handle, $query); + +$query = + "UPDATE pmgr_ledgers SET `closed` = 1" . + " WHERE `id` = $old_cash_ledger"; +query($db_handle, $query); + + +# my $monetary_source_cash = ++$aicur_monetary_source_id; +# $query = "INSERT INTO pmgr_monetary_sources +# (`id`, `monetary_type_id`, `name`, `comment`) VALUES (" . +# join(", ", map({defined $_ ? "'$_'" : "NULL"} +# ($monetary_source_cash, +# $monetary_type_map{'Cash'}{'id'}, +# 'Fake Cash Source', +# 'Fake source used for testing') +# )) . ")"; +# query($db_handle, $query) || die("Unable to insert"); + +foreach my $ir ('invoice', 'receipt') { + foreach my $tx (@{$fake{$ir}}) { + #print Dumper ${%$tx{'date'}}; + #exit; + $query = "INSERT INTO pmgr_transactions + (`id`, `stamp`, `through_date`, `customer_id`, `comment`) + VALUES (" . + join(", ", map({defined $_ ? "'$_'" : "NULL"} + (@{$tx}{'id', 'date', 'thru'}, $fake{'custid'}, "Fake $ir") + )) . ")"; + query($db_handle, $query, $tx); + + foreach my $e (@{$tx->{'entry'}}) { + my $dr = ($ir eq 'invoice') ? $account_map{'A/R'} : $account_map{'Cash'}; + my $cr = ($ir eq 'invoice') ? $account_map{$e->{'account'}} : $account_map{'A/R'}; + + $query = "INSERT INTO pmgr_ledger_entries + (`id`, `monetary_source_id`, + `transaction_id`, + `debit_ledger_id`, + `credit_ledger_id`, + `amount`, `comment`) + VALUES (" . + join(", ", map({defined $_ ? "'$_'" : "NULL"} + ($e->{'id'}, $e->{'type'} || $monetary_source_internal, + $tx->{'id'}, + $dr->{'ledger'}, + $cr->{'ledger'}, + $e->{'amount'}, "Fake $ir entry") + )) . ")"; + query($db_handle, $query, $e); + + next unless $e->{'tax'}; + + $query = "INSERT INTO pmgr_ledger_entries + (`id`, `monetary_source_id`, + `transaction_id`, + `debit_ledger_id`, + `credit_ledger_id`, + `amount`, `comment`) + VALUES (" . + join(", ", map({defined $_ ? "'$_'" : "NULL"} + ($e->{'id'}+1, $monetary_source_internal, + $tx->{'id'}, + $account_map{'A/R'}{'ledger'}, + $account_map{'Tax'}{'ledger'}, + $e->{'tax'}, "Fake Tax Charge") + )) . ")"; + query($db_handle, $query, $e); + } + } } - -$query ="UPDATE pmgr_charges_receipts R - JOIN (SELECT P.receipt_id AS rid, - IF(COALESCE(Ch.total, 0)disconnect(); - diff --git a/site/app_model.php b/site/app_model.php index 8914138..0f1bb9c 100644 --- a/site/app_model.php +++ b/site/app_model.php @@ -83,27 +83,51 @@ class AppModel extends Model { // a really large number of rows. However, trying to untagle this // without changing a bunch of core code is near impossible. - var $paginate_rows_save; - function paginate($conditions, $fields, $order, $limit, $page = 1, $recursive = null, $extra = null) { + //var $paginate_rows_save; + function paginate($conditions, $fields, $order, $limit, $page = 1, $recursive = null, &$extra = null) { /* pr("paginate"); */ /* pr(array_merge(compact('conditions', 'fields', 'order', 'limit', 'page', 'recursive', 'extra'))); */ if ($page > 1 && isset($limit)) $offset = ($page - 1) * $limit; else $offset = 0; - return array_slice($this->paginate_rows_save, $offset, $limit); + + if (!isset($extra['results'])) + die("Why isn't results set!?!"); + + $results = $extra['results']; + unset($extra['results']); + return array_slice($results, $offset, $limit); } - function paginateCount($conditions = null, $recursive = null, $extra = null) { + function paginateCount($conditions = null, $recursive = null, &$extra = null) { /* pr("paginateCount"); */ -/* pr(array_merge(compact('conditions', 'recursive', 'extra'))); */ +/* pr(compact('conditions', 'recursive', 'extra')); */ - if (!isset($recursive)) - $recursive = $this->recursive; - $parameters = array_merge(compact('conditions', 'recursive'), $extra); - $results = $this->find('all', $parameters); + if (isset($extra['results'])) { + // Beauty! The results are already in! + // This happens if the user sets up a complex query + // and passes us the result to paginate. + $results = $extra['results']; + } + elseif (isset($extra['query'])) { + // Perform the query directly... forget all the find B.S. + $results = $this->query($extra['query']); + } + else { + if (!isset($recursive)) + $recursive = $this->recursive; - $this->paginate_rows_save = $results; - return count($this->paginate_rows_save); + $parameters = array_merge(compact('conditions', 'recursive'), $extra); + $results = $this->find('all', $parameters); + } + + //$this->paginate_rows_save = $results; + //return count($this->paginate_rows_save); + + if (!isset($extra['results'])) + $extra['results'] = $results; + + return count($results); } } diff --git a/site/controllers/accounts_controller.php b/site/controllers/accounts_controller.php new file mode 100644 index 0000000..1bb9c21 --- /dev/null +++ b/site/controllers/accounts_controller.php @@ -0,0 +1,265 @@ + 100, + 'link' => + array(// Models + 'CurrentLedger' => array + (// Models + 'LedgerEntry' => + array('fields' => + array('SUM(IF(LedgerEntry.debit_ledger_id = CurrentLedger.id, LedgerEntry.amount, 0)) AS debits', + 'SUM(IF(LedgerEntry.credit_ledger_id = CurrentLedger.id, LedgerEntry.amount, 0)) AS credits', + "SUM(IF(Account.type IN ('ASSET', 'EXPENSE'), + IF(LedgerEntry.debit_ledger_id = CurrentLedger.id, 1, -1), + IF(LedgerEntry.credit_ledger_id = CurrentLedger.id, 1, -1) + )* LedgerEntry.amount) AS balance", + 'COUNT(LedgerEntry.id) AS entries'), + 'conditions' => + array('OR' => + array('LedgerEntry.debit_ledger_id = CurrentLedger.id', + 'LedgerEntry.credit_ledger_id = CurrentLedger.id'), + ), + ), + ), + ), + 'group' => 'Account.id', + 'order' => array('Account.name' => 'ASC')); + + var $uses = array('Account', 'LedgerEntry'); + + var $sidemenu_links = + array(array('name' => 'Accounts', 'header' => true), + array('name' => 'All', 'url' => array('controller' => 'accounts', 'action' => 'all')), + array('name' => 'Asset', 'url' => array('controller' => 'accounts', 'action' => 'asset')), + array('name' => 'Liability', 'url' => array('controller' => 'accounts', 'action' => 'liability')), + array('name' => 'Equity', 'url' => array('controller' => 'accounts', 'action' => 'equity')), + array('name' => 'Income', 'url' => array('controller' => 'accounts', 'action' => 'income')), + array('name' => 'Expense', 'url' => array('controller' => 'accounts', 'action' => 'expense')), + ); + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * override: sideMenuLinks + * - Generates controller specific links for the side menu + */ + function sideMenuLinks() { + return array_merge(parent::sideMenuLinks(), $this->sidemenu_links); + } + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * action: index + * - Lists all accounts + */ + + function index() { + $this->all(); + } + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * action: asset + * - Lists all asset accounts + */ + + function asset() { + $title = 'Asset Accounts'; + $this->set('title', $title); $this->set('heading', $title); + $this->set('accounts', $this->paginate(array('Account.type' => 'ASSET'))); + $this->render('index'); + } + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * action: liability + * - Lists all liability accounts + */ + + function liability() { + $title = 'Liability Accounts'; + $this->set('title', $title); $this->set('heading', $title); + $this->set('accounts', $this->paginate(array('Account.type' => 'LIABILITY'))); + $this->render('index'); + } + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * action: equity + * - Lists all equity accounts + */ + + function equity() { + $title = 'Equity Accounts'; + $this->set('title', $title); $this->set('heading', $title); + $this->set('accounts', $this->paginate(array('Account.type' => 'EQUITY'))); + $this->render('index'); + } + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * action: income + * - Lists all income accounts + */ + + function income() { + $title = 'Income Accounts'; + $this->set('title', $title); $this->set('heading', $title); + $this->set('accounts', $this->paginate(array('Account.type' => 'INCOME'))); + $this->render('index'); + } + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * action: expense + * - Lists all expense accounts + */ + + function expense() { + $title = 'Expense Accounts'; + $this->set('title', $title); $this->set('heading', $title); + $this->set('accounts', $this->paginate(array('Account.type' => 'EXPENSE'))); + $this->render('index'); + } + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * action: all + * - Lists all accounts + */ + + function all() { + $title = 'All Accounts'; + $this->set('title', $title); $this->set('heading', $title); + $this->set('accounts', $this->paginate()); + $this->render('index'); + } + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * action: view + * - Displays information about a specific account + */ + + function view($id = null) { + if (!$id) { + $this->Session->setFlash(__('Invalid Item.', true)); + $this->redirect(array('action'=>'index')); + } + +/* $this->Account->bindModel(array('hasMany' => array */ +/* ('LedgerEntry' => array */ +/* ('className' => 'LedgerEntry', */ +/* 'foreignKey' => false, */ +/* 'finderQuery' => 'SELECT `LedgerEntry`.* */ +/* FROM pmgr_entries AS `LedgerEntry` */ +/* LEFT JOIN pmgr_transactions AS `Transaction` */ +/* ON `Transaction`.id = `LedgerEntry`.transaction_id */ +/* WHERE LedgerEntry.debit_ledger_id = ({$__cakeID__$}) */ +/* OR LedgerEntry.credit_ledger_id = ({$__cakeID__$}) */ +/* ORDER BY Transaction.stamp', */ +/* )))); */ + +/* $this->Account->Behaviors->attach('Containable'); */ +/* $this->Account->Contain(array('LedgerEntry' => array */ +/* ( */ +/* // Models */ +/* 'Transaction' => array */ +/* ( */ +/* // Models */ +/* 'Customer', */ +/* )), */ + +/* )); */ +/* } */ +/* $account = $this->Account->read(null, $id); */ + + + $this->Account->recursive = -1; + $account = $this->Account->read(null, $id); + + $account['Ledger'] = $this->Account->find + ('all', array + ('link' => array + (// Models + 'Ledger' => array + (// Models + 'LedgerEntry' => + array('fields' => + array('SUM(IF(LedgerEntry.debit_ledger_id = Ledger.id, LedgerEntry.amount, 0)) AS debits', + 'SUM(IF(LedgerEntry.credit_ledger_id = Ledger.id, LedgerEntry.amount, 0)) AS credits', + "SUM(IF(Account.type IN ('ASSET', 'EXPENSE'), + IF(LedgerEntry.debit_ledger_id = Ledger.id, 1, -1), + IF(LedgerEntry.credit_ledger_id = Ledger.id, 1, -1) + ) * LedgerEntry.amount) AS balance", + 'COUNT(LedgerEntry.id) AS entries'), + 'conditions' => + array('OR' => + array('LedgerEntry.debit_ledger_id = Ledger.id', + 'LedgerEntry.credit_ledger_id = Ledger.id'), + ), + ), + ), + ), + 'fields' => array(), + 'conditions' => array('Account.id' => $id), + 'order' => 'Ledger.name', + 'group' => 'Ledger.id', + 'limit' => 4, + )); + + + $account['CurrentLedger'] = array_shift($this->Account->Ledger->find + ('first', array + ('link' => array + (// Models + 'Account' => array('fields' => array()), + 'LedgerEntry' => + array('fields' => + array("SUM(IF(LedgerEntry.debit_ledger_id = Ledger.id, LedgerEntry.amount, 0)) AS debits", + "SUM(IF(LedgerEntry.credit_ledger_id = Ledger.id, LedgerEntry.amount, 0)) AS credits", + "SUM(IF(Account.type IN ('ASSET', 'EXPENSE'), + IF(LedgerEntry.debit_ledger_id = Ledger.id, 1, -1), + IF(LedgerEntry.credit_ledger_id = Ledger.id, 1, -1) + ) * LedgerEntry.amount) AS balance", + 'COUNT(LedgerEntry.id) AS entries'), + 'conditions' => + array('OR' => + array("LedgerEntry.debit_ledger_id = Ledger.id", + "LedgerEntry.credit_ledger_id = Ledger.id"), + ), + ), + ), + 'fields' => array(), + 'conditions' => array(array('Ledger.account_id' => $id), + 'NOT' => array('Ledger.closed')), + //'order' => 'Ledger.name', + 'group' => 'Ledger.id', + //'limit' => 4, + ))); + //pr($account); + + $balance = $account['CurrentLedger']['balance']; + $title = 'Account: ' . $account['Account']['name']; + $this->set(compact('account', 'title', 'balance')); + } +} diff --git a/site/controllers/accounts_controller.php.bak b/site/controllers/accounts_controller.php.bak new file mode 100644 index 0000000..237b95d --- /dev/null +++ b/site/controllers/accounts_controller.php.bak @@ -0,0 +1,244 @@ + 100, + 'link' => + array(// Models + 'CurrentLedger' => array + (// Models + 'LedgerEntry' => + array('fields' => + array('SUM(IF(LedgerEntry.debit_account_id = Account.id, LedgerEntry.amount, 0)) AS debits', + 'SUM(IF(LedgerEntry.credit_account_id = Account.id, LedgerEntry.amount, 0)) AS credits', + "SUM(IF(Account.type IN ('ASSET', 'EXPENSE'), + IF(LedgerEntry.debit_account_id = Account.id, 1, -1), + IF(LedgerEntry.credit_account_id = Account.id, 1, -1) + )* LedgerEntry.amount) AS balance", + 'COUNT(LedgerEntry.id) AS entries'), + 'conditions' => + array('OR' => + array('LedgerEntry.debit_account_id = Account.id', + 'LedgerEntry.credit_account_id = Account.id'), + ), + ), + ), + + 'group' => 'Account.id', + 'order' => array('Account.name' => 'ASC')); + + var $sidemenu_links = + array(array('name' => 'Accounts', 'header' => true), + array('name' => 'All', 'url' => array('controller' => 'accounts', 'action' => 'all')), + array('name' => 'Asset', 'url' => array('controller' => 'accounts', 'action' => 'asset')), + array('name' => 'Liability', 'url' => array('controller' => 'accounts', 'action' => 'liability')), + array('name' => 'Equity', 'url' => array('controller' => 'accounts', 'action' => 'equity')), + array('name' => 'Income', 'url' => array('controller' => 'accounts', 'action' => 'income')), + array('name' => 'Expense', 'url' => array('controller' => 'accounts', 'action' => 'expense')), + ); + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * override: sideMenuLinks + * - Generates controller specific links for the side menu + */ + function sideMenuLinks() { + return array_merge(parent::sideMenuLinks(), $this->sidemenu_links); + } + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * action: index + * - Lists all accounts + */ + + function index() { + $this->all(); + } + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * action: asset + * - Lists all asset accounts + */ + + function asset() { + $title = 'Asset Accounts'; + $this->set('title', $title); $this->set('heading', $title); + $this->set('accounts', $this->paginate(array('Account.type' => 'ASSET'))); + $this->render('index'); + } + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * action: liability + * - Lists all liability accounts + */ + + function liability() { + $title = 'Liability Accounts'; + $this->set('title', $title); $this->set('heading', $title); + $this->set('accounts', $this->paginate(array('Account.type' => 'LIABILITY'))); + $this->render('index'); + } + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * action: equity + * - Lists all equity accounts + */ + + function equity() { + $title = 'Equity Accounts'; + $this->set('title', $title); $this->set('heading', $title); + $this->set('accounts', $this->paginate(array('Account.type' => 'EQUITY'))); + $this->render('index'); + } + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * action: income + * - Lists all income accounts + */ + + function income() { + $title = 'Income Accounts'; + $this->set('title', $title); $this->set('heading', $title); + $this->set('accounts', $this->paginate(array('Account.type' => 'INCOME'))); + $this->render('index'); + } + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * action: expense + * - Lists all expense accounts + */ + + function expense() { + $title = 'Expense Accounts'; + $this->set('title', $title); $this->set('heading', $title); + $this->set('accounts', $this->paginate(array('Account.type' => 'EXPENSE'))); + $this->render('index'); + } + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * action: all + * - Lists all accounts + */ + + function all() { + $title = 'All Accounts'; + $this->set('title', $title); $this->set('heading', $title); + $this->set('accounts', $this->paginate()); + $this->render('index'); + } + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * action: view + * - Displays information about a specific account + */ + + function view($id = null) { + if (!$id) { + $this->Session->setFlash(__('Invalid Item.', true)); + $this->redirect(array('action'=>'index')); + } + +/* $this->Account->bindModel(array('hasMany' => array */ +/* ('LedgerEntry' => array */ +/* ('className' => 'LedgerEntry', */ +/* 'foreignKey' => false, */ +/* 'finderQuery' => 'SELECT `LedgerEntry`.* */ +/* FROM pmgr_entries AS `LedgerEntry` */ +/* LEFT JOIN pmgr_transactions AS `Transaction` */ +/* ON `Transaction`.id = `LedgerEntry`.transaction_id */ +/* WHERE LedgerEntry.debit_account_id = ({$__cakeID__$}) */ +/* OR LedgerEntry.credit_account_id = ({$__cakeID__$}) */ +/* ORDER BY Transaction.stamp', */ +/* )))); */ + +/* $this->Account->Behaviors->attach('Containable'); */ +/* $this->Account->Contain(array('LedgerEntry' => array */ +/* ( */ +/* // Models */ +/* 'Transaction' => array */ +/* ( */ +/* // Models */ +/* 'Customer', */ +/* )), */ + +/* )); */ +/* } */ +/* $account = $this->Account->read(null, $id); */ + + $this->Account->recursive = -1; + $account = $this->Account->read(null, $id); + + if (in_array($account['Account']['type'], array('ASSET', 'EXPENSE'))) + $account_type = 'debit'; + else + $account_type = 'credit'; + + $ledger_id = $account['current_ledger_id']; + $account['CurrentLedger']['LedgerEntry'] = + $this->Account->Ledger->LedgerEntry->find + ('all', + array('link' => array + (// Models + 'fields' => + array('id', 'name', 'comment', + "IF(LedgerEntry.debit_ledger_id = $id, LedgerEntry.amount, NULL) AS debit", + "IF(LedgerEntry.credit_ledger_id = $id, LedgerEntry.amount, NULL) AS credit", + "(IF(LedgerEntry.{$account_type}_ledger_id = $id, 1, -1) + * LedgerEntry.amount) AS balance"), + 'conditions' => + array('OR' => + array('LedgerEntry.debit_ledger_id = Account.id', + 'LedgerEntry.credit_ledger_id = Account.id'), + + + 'Transaction' => + array(// Models + 'Customer', + )), + 'conditions' => array('OR' => + array("LedgerEntry.debit_account_id = $id", + "LedgerEntry.credit_account_id = $id")), + 'order' => array('Transaction.stamp'), + //'limit' => 15, + //'limit' => 2, + )); + //pr($account); + + $balance = 0; + foreach($account['LedgerEntry'] AS &$entry) { + if (isset($entry[0])) + $entry = array_merge($entry[0], array_diff_key($entry, array(0))); + + $balance += $entry['balance']; + } + + $title = 'Account: ' . $account['Account']['name']; + $this->set(compact('account', 'title', 'balance')); + } +} diff --git a/site/controllers/contacts_controller.php b/site/controllers/contacts_controller.php index f3aae03..34f1f19 100644 --- a/site/controllers/contacts_controller.php +++ b/site/controllers/contacts_controller.php @@ -7,10 +7,10 @@ class ContactsController extends AppController { 'Contact.first_name' => 'ASC')); var $sidemenu_links = - array(array('name' => 'Tenants', 'header' => true), - array('name' => 'Current', 'url' => array('controller' => 'contacts', 'action' => 'current')), - array('name' => 'Past', 'url' => array('controller' => 'contacts', 'action' => 'past')), - array('name' => 'All Tenants', 'url' => array('controller' => 'contacts', 'action' => 'tenants')), + array(array('name' => 'Contacts', 'header' => true), + //array('name' => 'Current', 'url' => array('controller' => 'contacts', 'action' => 'current')), + //array('name' => 'Past', 'url' => array('controller' => 'contacts', 'action' => 'past')), + //array('name' => 'All Tenants', 'url' => array('controller' => 'contacts', 'action' => 'tenants')), array('name' => 'All Contacts', 'url' => array('controller' => 'contacts', 'action' => 'all')), ); @@ -154,50 +154,12 @@ class ContactsController extends AppController { 'ContactPhone', 'ContactEmail', 'ContactAddress', - 'Lease' => - array('order' => 'movein_date', - 'conditions' => array('Lease.lease_date IS NOT NULL', - 'ContactsLease.type !=' => 'ALTERNATE'), - // Models - 'Unit' => - array('order' => array('sort_order'), - 'fields' => array('id', 'name'), - ), - 'Charge' => - array('order' => array('charge_date'), - // Models - 'ChargeType', - 'Receipt', - ) - ) - ) + 'Customer') ); $contact = $this->Contact->read(null, $id); - - $outstanding_deposit = 0; - $outstanding_balance = 0; - foreach($contact['Lease'] AS $lease) { - foreach($lease['Charge'] AS $charge) { - $outstanding_balance += $charge['total']; - foreach ($charge['Receipt'] AS $receipt) { - $outstanding_balance -= $receipt['ChargesReceipt']['amount']; - // REVISIT 20090530: - // Using hardcoded value for security deposit... - // That can't be good! - if ($charge['charge_type_id'] == 1) - $outstanding_deposit += $receipt['ChargesReceipt']['amount']; - } - } - } - - $this->sidemenu_links[] = - array('name' => 'Operations', 'header' => true); - $this->sidemenu_links[] = - array('name' => 'Move-Out', 'url' => array('controller' => 'units', 'action' => 'move-out')); + //pr($contact); $title = $contact['Contact']['display_name']; - $this->set(compact('contact', 'title', - 'outstanding_balance', - 'outstanding_deposit')); + $this->set(compact('contact', 'title')); } } diff --git a/site/controllers/customers_controller.php b/site/controllers/customers_controller.php new file mode 100644 index 0000000..c6db067 --- /dev/null +++ b/site/controllers/customers_controller.php @@ -0,0 +1,177 @@ + 100, + 'group' => 'Customer.id', + 'order' => array('Customer.name' => 'ASC')); + + var $sidemenu_links = + array(array('name' => 'Tenants', 'header' => true), + array('name' => 'Current', 'url' => array('controller' => 'customers', 'action' => 'current')), + array('name' => 'Past', 'url' => array('controller' => 'customers', 'action' => 'past')), + array('name' => 'All', 'url' => array('controller' => 'customers', 'action' => 'all')), + ); + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * override: sideMenuLinks + * - Generates controller specific links for the side menu + */ + function sideMenuLinks() { + return array_merge(parent::sideMenuLinks(), $this->sidemenu_links); + } + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * action: index + * - Lists all current tenants + */ + + function index() { + $this->current(); + } + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * action: current + * - Lists all current tenants + */ + + function current() { + $this->paginate = array_merge + ($this->paginate, + array('link' => + array(// Models + 'Lease' => + array('fields' => array(), + 'type' => 'INNER', + ), + ), + 'conditions' => array('Lease.close_date IS NULL') + )); + + $title = 'Current Tenants'; + $this->set('title', $title); $this->set('heading', $title); + $this->set('customers', $this->paginate()); + $this->render('index'); + } + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * action: past + * - Lists all past tenants + */ + + function past() { + $this->paginate = array_merge + ($this->paginate, + array('link' => + array(// Models + 'Lease' => + array('fields' => array(), + 'type' => 'INNER', + ), + ), + 'conditions' => array('Lease.close_date IS NOT NULL') + )); + + $title = 'Past Tenants'; + $this->set('title', $title); $this->set('heading', $title); + $this->set('customers', $this->paginate()); + $this->render('index'); + } + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * action: all + * - Lists all customers, including non-tenants + */ + + function all() { + $title = 'All Customers'; + $this->set('title', $title); $this->set('heading', $title); + $this->set('customers', $this->paginate()); + $this->render('index'); + } + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * action: view + * - Displays information about a specific customer + */ + + function view($id = null) { + if (!$id) { + $this->Session->setFlash(__('Invalid Item.', true)); + $this->redirect(array('action'=>'index')); + } + + $this->Customer->Behaviors->attach('Containable'); + $this->Customer->contain + (array(// Models + 'Contact' => + array(// Models + 'ContactPhone', + 'ContactEmail', + 'ContactAddress', + ), + 'Transaction' => + array('order' => array('stamp'), + // Models + 'Entry' => + array(// Models + 'DebitAccount', + 'CreditAccount'), + ), + 'Lease' => + array('order' => 'movein_date', + 'conditions' => array('Lease.lease_date IS NOT NULL'), + // Models + 'Unit' => + array('order' => array('sort_order'), + 'fields' => array('id', 'name'), + ), + ), + ) + ); + $customer = $this->Customer->read(null, $id); + //pr($customer); + + $outstanding_deposit = 0; + $outstanding_balance = 0; + foreach($customer['Transaction'] AS $transaction) { + foreach($transaction['Entry'] AS $entry) { + if ($entry['DebitAccount']['name'] === 'A/R') + $outstanding_balance += $entry['amount']; + if ($entry['CreditAccount']['name'] === 'A/R') + $outstanding_balance -= $entry['amount']; + + if ($entry['DebitAccount']['name'] === 'Security Deposit') + $outstanding_deposit -= $entry['amount']; + if ($entry['CreditAccount']['name'] === 'Security Deposit') + $outstanding_deposit += $entry['amount']; + } + } + + $this->sidemenu_links[] = + array('name' => 'Operations', 'header' => true); + $this->sidemenu_links[] = + array('name' => 'Move-Out', 'url' => array('controller' => 'units', 'action' => 'move-out')); + + $title = $customer['Customer']['name']; + $this->set(compact('customer', 'title', + 'outstanding_balance', + 'outstanding_deposit')); + } +} diff --git a/site/controllers/ledger_entries_controller.php b/site/controllers/ledger_entries_controller.php new file mode 100644 index 0000000..5a7c11a --- /dev/null +++ b/site/controllers/ledger_entries_controller.php @@ -0,0 +1,55 @@ + 100, + 'group' => 'Entry.id', + 'order' => array('Entry.stamp' => 'ASC')); + + var $sidemenu_links = + array(array('name' => 'Entries', 'header' => true), + array('name' => 'Cleared', 'url' => array('controller' => 'ledger_entries', 'action' => 'cleared')), + array('name' => 'Unresolved', 'url' => array('controller' => 'ledger_entries', 'action' => 'unresolved')), + ); + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * override: sideMenuLinks + * - Generates controller specific links for the side menu + */ + function sideMenuLinks() { + return array_merge(parent::sideMenuLinks(), $this->sidemenu_links); + } + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * action: view + * - Displays information about a specific entry + */ + + function view($id = null) { + if (!$id) { + $this->Session->setFlash(__('Invalid Item.', true)); + $this->redirect(array('controller' => 'accounts', 'action'=>'index')); + } + + $this->LedgerEntry->Behaviors->attach('Containable'); + $this->LedgerEntry->contain + (array(// Models + 'MonetarySource' => array('MonetaryType'), + 'Transaction', + 'DebitLedger', + 'CreditLedger', + ) + ); + $entry = $this->LedgerEntry->read(null, $id); + pr($entry); + + $title = "Entry #{$entry['LedgerEntry']['id']} ({$entry['LedgerEntry']['name']})"; + $this->set(compact('entry', 'title')); + //$this->autoRender = false; + } +} diff --git a/site/controllers/ledgers_controller.php b/site/controllers/ledgers_controller.php new file mode 100644 index 0000000..e54063c --- /dev/null +++ b/site/controllers/ledgers_controller.php @@ -0,0 +1,188 @@ + 100, + 'link' => + array(// Models + 'Account', + 'LedgerEntry' => + array('fields' => + array('SUM(IF(LedgerEntry.debit_ledger_id = Ledger.id, LedgerEntry.amount, 0)) AS debits', + 'SUM(IF(LedgerEntry.credit_ledger_id = Ledger.id, LedgerEntry.amount, 0)) AS credits', + "SUM(IF(Account.type IN ('ASSET', 'EXPENSE'), + IF(LedgerEntry.debit_ledger_id = Ledger.id, 1, -1), + IF(LedgerEntry.credit_ledger_id = Ledger.id, 1, -1)) * LedgerEntry.amount) AS balance", + 'COUNT(LedgerEntry.id) AS entries'), + 'conditions' => + array('OR' => + array('LedgerEntry.debit_ledger_id = Ledger.id', + 'LedgerEntry.credit_ledger_id = Ledger.id'), + ), + ), + ), + + 'group' => 'Ledger.id', + 'order' => array('Ledger.name' => 'ASC')); + + var $uses = array('Ledger', 'LedgerEntry'); + + var $sidemenu_links = + array(array('name' => 'Ledgers', 'header' => true), + array('name' => 'Current', 'url' => array('controller' => 'ledgers', 'action' => 'current')), + array('name' => 'Closed', 'url' => array('controller' => 'ledgers', 'action' => 'closed')), + array('name' => 'All', 'url' => array('controller' => 'ledgers', 'action' => 'all')), + ); + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * override: sideMenuLinks + * - Generates controller specific links for the side menu + */ + function sideMenuLinks() { + return array_merge(parent::sideMenuLinks(), $this->sidemenu_links); + } + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * action: index + */ + + function index() { + $this->current(); + } + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * action: current + * - Lists all current ledgers + */ + + function current() { + $title = 'Current Ledgers'; + $this->set('title', $title); $this->set('heading', $title); + $this->set('ledgers', $this->paginate(null, array('NOT' => array('Ledger.closed')))); + $this->render('index'); + } + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * action: closed + * - Lists all closed ledgers + */ + + function closed() { + $title = 'Closed Ledgers'; + $this->set('title', $title); $this->set('heading', $title); + $this->set('ledgers', $this->paginate(null, array('Ledger.closed'))); + $this->render('index'); + } + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * action: all + * - Lists all ledgers + */ + + function all() { + $title = 'All Ledgers'; + $this->set('title', $title); $this->set('heading', $title); + $this->set('ledgers', $this->paginate()); + $this->render('index'); + } + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * action: view + * - Displays information about a specific ledger + */ + + function view($id = null) { + if (!$id) { + $this->Session->setFlash(__('Invalid Item.', true)); + $this->redirect(array('action'=>'index')); + } + +/* $this->Ledger->bindModel(array('hasMany' => array */ +/* ('LedgerEntry' => array */ +/* ('className' => 'LedgerEntry', */ +/* 'foreignKey' => false, */ +/* 'finderQuery' => 'SELECT `LedgerEntry`.* */ +/* FROM pmgr_entries AS `LedgerEntry` */ +/* LEFT JOIN pmgr_transactions AS `Transaction` */ +/* ON `Transaction`.id = `LedgerEntry`.transaction_id */ +/* WHERE LedgerEntry.debit_ledger_id = ({$__cakeID__$}) */ +/* OR LedgerEntry.credit_ledger_id = ({$__cakeID__$}) */ +/* ORDER BY Transaction.stamp', */ +/* )))); */ + +/* $this->Ledger->Behaviors->attach('Containable'); */ +/* $this->Ledger->Contain(array('LedgerEntry' => array */ +/* ( */ +/* // Models */ +/* 'Transaction' => array */ +/* ( */ +/* // Models */ +/* 'Customer', */ +/* )), */ + +/* )); */ +/* } */ +/* $ledger = $this->Ledger->read(null, $id); */ + + $this->Ledger->Behaviors->attach('Containable'); + $this->Ledger->Contain(array('Account')); + $ledger = $this->Ledger->read(null, $id); + //pr($ledger); + + if (in_array($ledger['Account']['type'], array('ASSET', 'EXPENSE'))) + $ledger_type = 'debit'; + else + $ledger_type = 'credit'; + + $ledger['LedgerEntry'] = $this->LedgerEntry->find + ('all', + array('link' => array + (// Models + 'Transaction' => + array(// Models + 'Customer', + )), + 'fields' => + array('id', 'name', 'comment', + "IF(LedgerEntry.debit_ledger_id = $id, LedgerEntry.amount, NULL) AS debit", + "IF(LedgerEntry.credit_ledger_id = $id, LedgerEntry.amount, NULL) AS credit", + "(IF(LedgerEntry.{$ledger_type}_ledger_id = $id, 1, -1) * LedgerEntry.amount) AS balance"), + 'conditions' => array('OR' => + array("LedgerEntry.debit_ledger_id = $id", + "LedgerEntry.credit_ledger_id = $id")), + 'order' => array('Transaction.stamp'), + //'limit' => 15, + //'limit' => 2, + )); + //pr($ledger); + + $balance = 0; + foreach($ledger['LedgerEntry'] AS &$entry) { + if (isset($entry[0])) + $entry = array_merge($entry[0], array_diff_key($entry, array(0))); + + $balance += $entry['balance']; + } + + $title = 'Ledger: ' . $ledger['Ledger']['name']; + $this->set(compact('ledger', 'title', 'balance')); + } +} diff --git a/site/controllers/payments_controller.php b/site/controllers/payments_controller.php deleted file mode 100644 index 63e1a41..0000000 --- a/site/controllers/payments_controller.php +++ /dev/null @@ -1,118 +0,0 @@ - 100, - 'group' => 'Payment.id', - 'order' => array('Payment.id' => 'ASC')); - - var $sidemenu_links = - array(array('name' => 'Payments', 'header' => true), - array('name' => 'Cleared', 'url' => array('controller' => 'payments', 'action' => 'cleared')), - array('name' => 'Unresolved', 'url' => array('controller' => 'payments', 'action' => 'unresolved')), - ); - - - /************************************************************************** - ************************************************************************** - ************************************************************************** - * override: sideMenuLinks - * - Generates controller specific links for the side menu - */ - function sideMenuLinks() { - return array_merge(parent::sideMenuLinks(), $this->sidemenu_links); - } - - - /************************************************************************** - ************************************************************************** - ************************************************************************** - * action: index - * - Lists all payments - */ - - function index() { - $this->all(); - } - - - /************************************************************************** - ************************************************************************** - ************************************************************************** - * action: cleared - * - Lists cleared payments - */ - - function cleared() { - $this->all(); - } - - - /************************************************************************** - ************************************************************************** - ************************************************************************** - * action: unresolved - * - Lists unresolved payments - */ - - function unresolved() { - $this->all(); - } - - - - /************************************************************************** - ************************************************************************** - ************************************************************************** - * action: all - * - Lists all payments - */ - - function all() { - $this->paginate = array_merge - ($this->paginate, - array('link' => - array(// Models - 'PaymentType', - 'Receipt', - ), - )); - - $title = 'All Payments'; - $this->set('title', $title); $this->set('heading', $title); - $this->set('payments', $this->paginate()); - $this->render('index'); - } - - - /************************************************************************** - ************************************************************************** - ************************************************************************** - * action: view - * - Displays information about a specific payment - */ - - function view($id = null) { - if (!$id) { - $this->Session->setFlash(__('Invalid Item.', true)); - $this->redirect(array('action'=>'index')); - } - - $this->Payment->Behaviors->attach('Containable'); - $this->Payment->contain - (array(// Models - 'PaymentType', - 'Receipt', - ) - ); - $payment = $this->Payment->read(null, $id); - //pr($payment); - -/* $this->sidemenu_links[] = */ -/* array('name' => 'Operations', 'header' => true); */ -/* $this->sidemenu_links[] = */ -/* array('name' => 'Move-Out', 'url' => array('controller' => 'payments', 'action' => 'move-out')); */ - - $title = 'Payment #' . $payment['Payment']['id']; - $this->set(compact('payment', 'title')); - } -} diff --git a/site/controllers/receipts_controller.php b/site/controllers/receipts_controller.php deleted file mode 100644 index 77215dd..0000000 --- a/site/controllers/receipts_controller.php +++ /dev/null @@ -1,131 +0,0 @@ - 100, - 'group' => 'Receipt.id', - 'order' => array('Receipt.stamp' => 'ASC')); - - var $sidemenu_links = - array(array('name' => 'Receipts', 'header' => true), - array('name' => 'Cleared', 'url' => array('controller' => 'receipts', 'action' => 'cleared')), - array('name' => 'Unresolved', 'url' => array('controller' => 'receipts', 'action' => 'unresolved')), - ); - - - /************************************************************************** - ************************************************************************** - ************************************************************************** - * override: sideMenuLinks - * - Generates controller specific links for the side menu - */ - function sideMenuLinks() { - return array_merge(parent::sideMenuLinks(), $this->sidemenu_links); - } - - - /************************************************************************** - ************************************************************************** - ************************************************************************** - * action: index - * - Lists all receipts - */ - - function index() { - $this->all(); - } - - - /************************************************************************** - ************************************************************************** - ************************************************************************** - * action: cleared - * - Lists cleared receipts - */ - - function cleared() { - $this->all(); - } - - - /************************************************************************** - ************************************************************************** - ************************************************************************** - * action: unresolved - * - Lists unresolved receipts - */ - - function unresolved() { - $this->all(); - } - - - - /************************************************************************** - ************************************************************************** - ************************************************************************** - * action: all - * - Lists all receipts - */ - - function all() { - $this->paginate = array_merge - ($this->paginate, - array('link' => - array(// Models - 'Charge', - 'Payment' - ), - )); - - $title = 'All Receipts'; - $this->set('title', $title); $this->set('heading', $title); - $this->set('receipts', $this->paginate()); - $this->render('index'); - } - - - /************************************************************************** - ************************************************************************** - ************************************************************************** - * action: view - * - Displays information about a specific receipt - */ - - function view($id = null) { - if (!$id) { - $this->Session->setFlash(__('Invalid Item.', true)); - $this->redirect(array('action'=>'index')); - } - - $this->Receipt->Behaviors->attach('Containable'); - $this->Receipt->contain - (array(// Models - 'Charge' => array(// Models - 'Lease' => array('fields' => array('number')), - 'ChargesReceipt', - 'ChargeType'), - 'Payment' => array(// Models - 'PaymentType'), - ) - ); - $receipt = $this->Receipt->read(null, $id); - //pr($receipt); - - $charge_amount = 0; - $payment_amount = 0; - foreach($receipt['Charge'] AS $charge) - $charge_amount += $charge['ChargesReceipt']['amount']; - foreach($receipt['Payment'] AS $payment) - $payment_amount += $payment['amount']; - -/* $this->sidemenu_links[] = */ -/* array('name' => 'Operations', 'header' => true); */ -/* $this->sidemenu_links[] = */ -/* array('name' => 'Move-Out', 'url' => array('controller' => 'receipts', 'action' => 'move-out')); */ - - $title = 'Receipt #' . $receipt['Receipt']['id']; - $this->set(compact('receipt', 'title', - 'charge_amount', - 'payment_amount')); - } -} diff --git a/site/controllers/charges_controller.php b/site/controllers/transactions_controller.php similarity index 65% rename from site/controllers/charges_controller.php rename to site/controllers/transactions_controller.php index d1b890c..a5d0da3 100644 --- a/site/controllers/charges_controller.php +++ b/site/controllers/transactions_controller.php @@ -1,14 +1,14 @@ 100, - 'group' => 'Charge.id', - 'order' => array('Charge.charge_date' => 'ASC')); + 'group' => 'Transaction.id', + 'order' => array('Transaction.stamp' => 'ASC')); var $sidemenu_links = - array(array('name' => 'Charges', 'header' => true), - array('name' => 'Cleared', 'url' => array('controller' => 'charges', 'action' => 'cleared')), - array('name' => 'Unresolved', 'url' => array('controller' => 'charges', 'action' => 'unresolved')), + array(array('name' => 'Transactions', 'header' => true), + array('name' => 'Cleared', 'url' => array('controller' => 'transactions', 'action' => 'cleared')), + array('name' => 'Unresolved', 'url' => array('controller' => 'transactions', 'action' => 'unresolved')), ); @@ -27,7 +27,7 @@ class ChargesController extends AppController { ************************************************************************** ************************************************************************** * action: index - * - Lists all charges + * - Lists all transactions */ function index() { @@ -39,7 +39,7 @@ class ChargesController extends AppController { ************************************************************************** ************************************************************************** * action: cleared - * - Lists cleared charges + * - Lists cleared transactions */ function cleared() { @@ -51,7 +51,7 @@ class ChargesController extends AppController { ************************************************************************** ************************************************************************** * action: unresolved - * - Lists unresolved charges + * - Lists unresolved transactions */ function unresolved() { @@ -64,7 +64,7 @@ class ChargesController extends AppController { ************************************************************************** ************************************************************************** * action: all - * - Lists all charges + * - Lists all transactions */ function all() { @@ -72,15 +72,14 @@ class ChargesController extends AppController { ($this->paginate, array('link' => array(// Models - 'ChargeType', - 'Receipt', - 'Lease' => array('fields' => array('number')) + 'Customer', + 'LedgerEntry' => array('DebitLedger', 'CreditLedger') ), )); - $title = 'All Charges'; + $title = 'All Transactions'; $this->set('title', $title); $this->set('heading', $title); - $this->set('charges', $this->paginate()); + $this->set('transactions', $this->paginate()); $this->render('index'); } @@ -89,7 +88,7 @@ class ChargesController extends AppController { ************************************************************************** ************************************************************************** * action: view - * - Displays information about a specific charge + * - Displays information about a specific transaction */ function view($id = null) { @@ -98,30 +97,33 @@ class ChargesController extends AppController { $this->redirect(array('action'=>'index')); } - $this->Charge->Behaviors->attach('Containable'); - $this->Charge->contain + $this->Transaction->Behaviors->attach('Containable'); + $this->Transaction->contain (array(// Models - 'ChargeType', - 'Receipt', - 'Lease' => array('fields' => array('number')), + 'LedgerEntry' => array(//Models + 'DebitLedger', + 'CreditLedger', + ), ) ); - $charge = $this->Charge->read(null, $id); - //pr($charge); + $transaction = $this->Transaction->read(null, $id); + pr($transaction); - $payment_amount = 0; - foreach($charge['Receipt'] AS $receipt) - $payment_amount += $receipt['ChargesReceipt']['amount']; - $balance_amount = $charge['Charge']['total'] - $payment_amount; + $debit_amount = 0; + $credit_amount = 0; + foreach($transaction['LedgerEntry'] AS $entry) { + $debit_amount += $entry['amount']; + $credit_amount += $entry['amount']; + } /* $this->sidemenu_links[] = */ /* array('name' => 'Operations', 'header' => true); */ /* $this->sidemenu_links[] = */ -/* array('name' => 'Move-Out', 'url' => array('controller' => 'charges', 'action' => 'move-out')); */ +/* array('name' => 'Move-Out', 'url' => array('controller' => 'transactions', 'action' => 'move-out')); */ - $title = 'Charge #' . $charge['Charge']['id']; - $this->set(compact('charge', 'title', - 'payment_amount', - 'balance_amount')); + $title = 'Transaction #' . $transaction['Transaction']['id']; + $this->set(compact('transaction', 'title', + 'debit_amount', + 'credit_amount')); } } diff --git a/site/controllers/units_controller.php b/site/controllers/units_controller.php index 453097a..abe18cf 100644 --- a/site/controllers/units_controller.php +++ b/site/controllers/units_controller.php @@ -156,45 +156,70 @@ class UnitsController extends AppController { $this->Unit->contain (array(// Models 'UnitSize', + //'CurrentLease' => 'Lease' => - array('order' => 'movein_date', - 'conditions' => array('Lease.lease_date IS NOT NULL', - ), + array(//'order' => 'movein_date', + //'conditions' => array('Lease.lease_date IS NOT NULL', + //), // Models - 'Contact' => - array(//'order' => array('sort_order'), - 'fields' => array('id', 'display_name'), - ), - 'Charge' => - array('order' => array('charge_date'), - // Models - 'ChargeType', - 'Receipt' => array(// Models - 'Payment' - ), - ) + //'Contact' => array('alias' => 'PrimaryContact'), + // 'PrimaryContact', + 'Customer' => array('fields' => array('id', 'name'), + // Models + 'Transaction' => + array('order' => array('stamp'), + // Models + 'LedgerEntry' => array('DebitLedger' => array('Account'), + 'CreditLedger' => array('Account'), + ), + ), + ), +/* array(//'order' => array('sort_order'), */ +/* 'fields' => array('id', 'display_name'), */ +/* ), */ ) ) ); - $unit = $this->Unit->read(null, $id); + + //$unit = $this->Unit->read(null, $id); //pr($unit); + $this->Unit->Lease->Customer->Transaction->LedgerEntry->Behaviors->attach('Containable'); + $entries = $this->Unit->Lease->Customer->Transaction->LedgerEntry->find + ('all', + array + ( + 'contain' => + array('Transaction' => + array('Customer' => + array('Lease' => + array('Unit' => + array('conditions' => array('Unit.id' => $id)), + ), + ), + ), + ), + //'conditions' => 'xyz', + 'limit' => 2, + )); + pr($entries); + $this->autoRender = false; + + $outstanding_deposit = 0; $outstanding_balance = 0; foreach($unit['Lease'] AS $lease) { - foreach($lease['Charge'] AS $charge) { - $outstanding_balance += $charge['total']; - foreach ($charge['Receipt'] AS $receipt) { - $outstanding_balance -= $receipt['ChargesReceipt']['amount']; + foreach($lease['Customer']['Transaction'] AS $transaction) { + foreach($transaction['LedgerEntry'] AS $entry) { + if ($entry['DebitLedger']['Account']['name'] === 'A/R') + $outstanding_balance += $entry['amount']; + if ($entry['CreditLedger']['Account']['name'] === 'A/R') + $outstanding_balance -= $entry['amount']; -/* foreach($receipt['Payment'] AS $payment) */ -/* $outstanding_balance -= $payment['amount']; */ - - // REVISIT 20090530: - // Using hardcoded value for security deposit... - // That can't be good! - if ($charge['charge_type_id'] == 1) - $outstanding_deposit += $receipt['ChargesReceipt']['amount']; + if ($entry['DebitLedger']['Account']['name'] === 'Security Deposit') + $outstanding_deposit -= $entry['amount']; + if ($entry['CreditLedger']['Account']['name'] === 'Security Deposit') + $outstanding_deposit += $entry['amount']; } } } diff --git a/site/models/account.php b/site/models/account.php index 35eeca0..0079017 100644 --- a/site/models/account.php +++ b/site/models/account.php @@ -8,10 +8,25 @@ class Account extends AppModel { 'external_name' => array('notempty') ); - //The Associations below have been created with all possible keys, those that are not needed can be removed + var $hasOne = array( + 'CurrentLedger' => array( + 'className' => 'Ledger', + 'foreignKey' => 'account_id', + 'dependent' => false, + 'conditions' => array(array('CurrentLedger.closed' => 0)), + 'fields' => '', + 'order' => '', + 'limit' => '', + 'offset' => '', + 'exclusive' => '', + 'finderQuery' => '', + 'counterQuery' => '' + ), + ); + var $hasMany = array( - 'ChargeType' => array( - 'className' => 'ChargeType', + 'Ledger' => array( + 'className' => 'Ledger', 'foreignKey' => 'account_id', 'dependent' => false, 'conditions' => '', @@ -22,7 +37,7 @@ class Account extends AppModel { 'exclusive' => '', 'finderQuery' => '', 'counterQuery' => '' - ) + ), ); } diff --git a/site/models/behaviors/linkable.php b/site/models/behaviors/linkable.php index f38c7da..388456f 100644 --- a/site/models/behaviors/linkable.php +++ b/site/models/behaviors/linkable.php @@ -82,23 +82,51 @@ class LinkableBehavior extends ModelBehavior { /* pr("_Model: $options[class] : $_Model->name ($_Model->alias)"); */ /* pr("Reference: $options[reference] : $Reference->name ($Reference->alias)"); */ $db =& $_Model->getDataSource(); - $associations = $_Model->getAssociated(); - if (isset($associations[$Reference->alias])) { + + $associatedThroughReference = 0; + $association = null; + + // Figure out how these two models are related, creating + // a relationship if one doesn't otherwise already exists. + if (($associations = $Reference->getAssociated()) && + isset($associations[$_Model->alias])) { +/* pr("Reference defines association to _Model"); */ + $associatedThroughReference = 1; + $type = $associations[$_Model->alias]; + $association = $Reference->{$type}[$_Model->alias]; + } + elseif (($associations = $_Model->getAssociated()) && + isset($associations[$Reference->alias])) { +/* pr("_Model defines association to Reference"); */ $type = $associations[$Reference->alias]; $association = $_Model->{$type}[$Reference->alias]; - } else { - $_Model->bind($Reference->alias); + } + else { + // No relationship... make our best effort to create one. +/* pr("No assocation between _Model and Reference"); */ $type = 'belongsTo'; + $_Model->bind($Reference->alias); + // Grab the association now, since we'll unbind in a moment. $association = $_Model->{$type}[$Reference->alias]; $_Model->unbindModel(array('belongsTo' => array($Reference->alias))); } + // Determine which model holds the foreign key + if (($type === 'hasMany' || $type === 'hasOne') ^ $associatedThroughReference) { + $primaryModel = $Reference; + $foreignModel = $_Model; + } else { + $primaryModel = $_Model; + $foreignModel = $Reference; + } + +/* pr("primaryModel: $primaryModel->name ($primaryModel->alias)"); */ +/* pr("foreignModel: $foreignModel->name ($foreignModel->alias)"); */ +/* pr($type); */ +/* pr($association); */ + if (empty($options['conditions'])) { - if ($type === 'belongsTo') { - $modelKey = $_Model->escapeField($association['foreignKey']); - $referenceKey = $Reference->escapeField($Reference->primaryKey); - $options['conditions'] = "{$referenceKey} = {$modelKey}"; - } elseif ($type === 'hasAndBelongsToMany') { + if ($type === 'hasAndBelongsToMany') { if (isset($association['with'])) $Link =& $_Model->{$association['with']}; else @@ -139,17 +167,10 @@ class LinkableBehavior extends ModelBehavior { // be concerned with whether or not the join has any results. // They control that with the 'type' parameter which will be at // the top level join. - $options['joins'][] = array('type' => 'INNER', - 'alias' => $options['alias'], - 'conditions' => "{$modelKey} = {$modelLink}", - 'table' => $db->fullTableName($_Model, true)); - - // The user may have specified conditions directly in the model - // for this join. Make sure to adhere to those conditions. - if (isset($association['conditions']) && is_array($association['conditions'])) - $options['conditions'] = $association['conditions']; - elseif (!empty($association['conditions'])) - $options['conditions'] = array($association['conditions']); + $options['joins'][] = array('type' => 'INNER', + 'alias' => $options['alias'], + 'conditions' => "{$modelKey} = {$modelLink}", + 'table' => $db->fullTableName($_Model, true)); // Now for the top level join. This will be added into the list // of joins down below, outside of the HABTM specific code. @@ -157,10 +178,28 @@ class LinkableBehavior extends ModelBehavior { $options['table'] = $Link->getDataSource()->fullTableName($Link); $options['conditions'][] = "{$referenceLink} = {$referenceKey}"; } else { - $referenceKey = $Reference->escapeField($association['foreignKey']); - $modelKey = $_Model->escapeField($_Model->primaryKey); - $options['conditions'] = "{$modelKey} = {$referenceKey}"; + $foreignKey = $primaryModel->escapeField($association['foreignKey']); + $primaryKey = $foreignModel->escapeField($foreignModel->primaryKey); + + // Only differentiating to help show the logical flow. + // Either way works and this test can be tossed out + if (($type === 'hasMany' || $type === 'hasOne') ^ $associatedThroughReference) + $options['conditions'][] = "{$primaryKey} = {$foreignKey}"; + else + $options['conditions'][] = "{$foreignKey} = {$primaryKey}"; } + + // The user may have specified conditions directly in the model + // for this join. Make sure to adhere to those conditions. + if (isset($association['conditions']) && is_array($association['conditions'])) + $options['conditions'] = array_merge($options['conditions'], $association['conditions']); + elseif (!empty($association['conditions'])) + $options['conditions'][] = $association['conditions']; + +/* pr(array("Link ", $options['conditions'])); */ + //pr($modelKey); + //pr($referenceKey); + } if (empty($options['table'])) { $options['table'] = $db->fullTableName($_Model, true); diff --git a/site/models/charge.php b/site/models/charge.php deleted file mode 100644 index e37a8e9..0000000 --- a/site/models/charge.php +++ /dev/null @@ -1,53 +0,0 @@ - array('numeric'), - 'charge_type_id' => array('numeric'), - 'lease_id' => array('numeric'), - 'charge_date' => array('date'), - 'charge_to_date' => array('date'), - 'due_date' => array('date'), - 'amount' => array('money'), - 'tax' => array('money'), - 'total' => array('money') - ); - - var $belongsTo = array( - 'ChargeType' => array( - 'className' => 'ChargeType', - 'foreignKey' => 'charge_type_id', - 'conditions' => '', - 'fields' => '', - 'order' => '' - ), - 'Lease' => array( - 'className' => 'Lease', - 'foreignKey' => 'lease_id', - 'conditions' => '', - 'fields' => '', - 'order' => '' - ) - ); - - var $hasAndBelongsToMany = array( - 'Receipt' => array( - 'className' => 'Receipt', - 'joinTable' => 'charges_receipts', - 'foreignKey' => 'charge_id', - 'associationForeignKey' => 'receipt_id', - 'unique' => true, - 'conditions' => '', - 'fields' => '', - 'order' => '', - 'limit' => '', - 'offset' => '', - 'finderQuery' => '', - 'deleteQuery' => '', - 'insertQuery' => '' - ) - ); - -} -?> \ No newline at end of file diff --git a/site/models/charge_type.php b/site/models/charge_type.php deleted file mode 100644 index fe42c68..0000000 --- a/site/models/charge_type.php +++ /dev/null @@ -1,39 +0,0 @@ - array('numeric'), - 'name' => array('notempty'), - 'account_id' => array('numeric') - ); - - //The Associations below have been created with all possible keys, those that are not needed can be removed -/* var $belongsTo = array( */ -/* 'Account' => array( */ -/* 'className' => 'Account', */ -/* 'foreignKey' => 'account_id', */ -/* 'conditions' => '', */ -/* 'fields' => '', */ -/* 'order' => '' */ -/* ) */ -/* ); */ - - var $hasMany = array( - 'Charge' => array( - 'className' => 'Charge', - 'foreignKey' => 'charge_type_id', - 'dependent' => false, - 'conditions' => '', - 'fields' => '', - 'order' => '', - 'limit' => '', - 'offset' => '', - 'exclusive' => '', - 'finderQuery' => '', - 'counterQuery' => '' - ) - ); - -} -?> \ No newline at end of file diff --git a/site/models/contact.php b/site/models/contact.php index c3d834a..04052c2 100644 --- a/site/models/contact.php +++ b/site/models/contact.php @@ -10,11 +10,11 @@ class Contact extends AppModel { ); var $hasAndBelongsToMany = array( - 'Lease' => array( - 'className' => 'Lease', - 'joinTable' => 'contacts_leases', + 'Customer' => array( + 'className' => 'Customer', + 'joinTable' => 'contacts_customers', 'foreignKey' => 'contact_id', - 'associationForeignKey' => 'lease_id', + 'associationForeignKey' => 'customer_id', 'unique' => true, 'conditions' => '', 'fields' => '', diff --git a/site/models/customer.php b/site/models/customer.php new file mode 100644 index 0000000..652cef3 --- /dev/null +++ b/site/models/customer.php @@ -0,0 +1,58 @@ + array('numeric'), + 'name' => array('notempty'), + ); + + var $hasMany = array( + 'Lease' => array( + 'className' => 'Lease', + 'foreignKey' => 'customer_id', + 'dependent' => false, + 'conditions' => '', + 'fields' => '', + 'order' => '', + 'limit' => '', + 'offset' => '', + 'exclusive' => '', + 'finderQuery' => '', + 'counterQuery' => '' + ), + 'Transaction' => array( + 'className' => 'Transaction', + 'foreignKey' => 'customer_id', + 'dependent' => false, + 'conditions' => '', + 'fields' => '', + 'order' => '', + 'limit' => '', + 'offset' => '', + 'exclusive' => '', + 'finderQuery' => '', + 'counterQuery' => '' + ) + ); + + var $hasAndBelongsToMany = array( + 'Contact' => array( + 'className' => 'Contact', + 'joinTable' => 'contacts_customers', + 'foreignKey' => 'customer_id', + 'associationForeignKey' => 'contact_id', + 'unique' => true, + 'conditions' => '', + 'fields' => '', + 'order' => '', + 'limit' => '', + 'offset' => '', + 'finderQuery' => '', + 'deleteQuery' => '', + 'insertQuery' => '' + ), + ); + +} +?> \ No newline at end of file diff --git a/site/models/lease.php b/site/models/lease.php index 509b333..fd349fe 100644 --- a/site/models/lease.php +++ b/site/models/lease.php @@ -22,7 +22,6 @@ class Lease extends AppModel { 'next_amount_date' => array('date') ); - //The Associations below have been created with all possible keys, those that are not needed can be removed var $belongsTo = array( 'LeaseType' => array( 'className' => 'LeaseType', @@ -44,41 +43,15 @@ class Lease extends AppModel { 'conditions' => '', 'fields' => '', 'order' => '' - ) - ); - - var $hasMany = array( - 'Charge' => array( - 'className' => 'Charge', - 'foreignKey' => 'lease_id', + ), + 'Customer' => array( + 'className' => 'Customer', + 'foreignKey' => 'customer_id', 'dependent' => false, 'conditions' => '', 'fields' => '', - 'order' => '', - 'limit' => '', - 'offset' => '', - 'exclusive' => '', - 'finderQuery' => '', - 'counterQuery' => '' - ) - ); - - var $hasAndBelongsToMany = array( - 'Contact' => array( - 'className' => 'Contact', - 'joinTable' => 'contacts_leases', - 'foreignKey' => 'lease_id', - 'associationForeignKey' => 'contact_id', - 'unique' => true, - 'conditions' => '', - 'fields' => '', - 'order' => '', - 'limit' => '', - 'offset' => '', - 'finderQuery' => '', - 'deleteQuery' => '', - 'insertQuery' => '' - ) + 'order' => '' + ), ); } diff --git a/site/models/ledger.php b/site/models/ledger.php new file mode 100644 index 0000000..6808a1f --- /dev/null +++ b/site/models/ledger.php @@ -0,0 +1,65 @@ + array('numeric'), + 'name' => array('notempty'), + ); + + var $belongsTo = array( + 'Account' => array( + 'className' => 'Account', + 'foreignKey' => 'account_id', + 'conditions' => '', + 'fields' => '', + 'order' => '' + ), + ); + + var $hasMany = array( +/* 'LedgerEntry' => array( */ +/* 'className' => 'LedgerEntry', */ +/* 'foreignKey' => false, */ +/* 'dependent' => false, */ +/* 'conditions' => '', */ +/* 'fields' => '', */ +/* 'order' => '', */ +/* 'limit' => '', */ +/* 'offset' => '', */ +/* 'exclusive' => '', */ +/* 'finderQuery' => 'SELECT `Entry`.* FROM pmgr_entries AS `Entry` */ +/* WHERE Entry.debit_ledger_id = ({$__cakeID__$}) */ +/* OR Entry.credit_ledger_id = ({$__cakeID__$})', */ +/* 'counterQuery' => '' */ +/* ), */ + 'DebitLedgerEntry' => array( + 'className' => 'LedgerEntry', + 'foreignKey' => 'debit_ledger_id', + 'dependent' => false, + 'conditions' => '', + 'fields' => '', + 'order' => '', + 'limit' => '', + 'offset' => '', + 'exclusive' => '', + 'finderQuery' => '', + 'counterQuery' => '' + ), + 'CreditLedgerEntry' => array( + 'className' => 'LedgerEntry', + 'foreignKey' => 'credit_ledger_id', + 'dependent' => false, + 'conditions' => '', + 'fields' => '', + 'order' => '', + 'limit' => '', + 'offset' => '', + 'exclusive' => '', + 'finderQuery' => '', + 'counterQuery' => '' + ), + ); + +} +?> \ No newline at end of file diff --git a/site/models/ledger_entry.php b/site/models/ledger_entry.php new file mode 100644 index 0000000..4d84e6c --- /dev/null +++ b/site/models/ledger_entry.php @@ -0,0 +1,43 @@ + array('numeric'), + 'transaction_id' => array('numeric'), + 'amount' => array('money') + ); + + var $belongsTo = array( + 'MonetarySource' => array( + 'className' => 'MonetarySource', + 'foreignKey' => 'monetary_source_id', + 'conditions' => '', + 'fields' => '', + 'order' => '' + ), + 'Transaction' => array( + 'className' => 'Transaction', + 'foreignKey' => 'transaction_id', + 'conditions' => '', + 'fields' => '', + 'order' => '' + ), + 'DebitLedger' => array( + 'className' => 'Ledger', + 'foreignKey' => 'debit_ledger_id', + 'conditions' => '', + 'fields' => '', + 'order' => '' + ), + 'CreditLedger' => array( + 'className' => 'Ledger', + 'foreignKey' => 'credit_ledger_id', + 'conditions' => '', + 'fields' => '', + 'order' => '' + ), + ); + +} +?> \ No newline at end of file diff --git a/site/models/monetary_source.php b/site/models/monetary_source.php new file mode 100644 index 0000000..a2d5bcc --- /dev/null +++ b/site/models/monetary_source.php @@ -0,0 +1,28 @@ + array('numeric'), + 'name' => array('notempty'), + 'tillable' => array('boolean') + ); + + var $belongsTo = array( + 'MonetaryType' => array( + 'className' => 'MonetaryType', + 'foreignKey' => 'monetary_type_id', + 'dependent' => false, + 'conditions' => '', + 'fields' => '', + 'order' => '', + 'limit' => '', + 'offset' => '', + 'exclusive' => '', + 'finderQuery' => '', + 'counterQuery' => '' + ) + ); + +} +?> \ No newline at end of file diff --git a/site/models/payment_type.php b/site/models/monetary_type.php similarity index 55% rename from site/models/payment_type.php rename to site/models/monetary_type.php index 45f5881..d79d4fc 100644 --- a/site/models/payment_type.php +++ b/site/models/monetary_type.php @@ -1,18 +1,17 @@ array('numeric'), 'name' => array('notempty'), 'tillable' => array('boolean') ); - //The Associations below have been created with all possible keys, those that are not needed can be removed var $hasMany = array( - 'Payment' => array( - 'className' => 'Payment', - 'foreignKey' => 'payment_type_id', + 'MonetarySource' => array( + 'className' => 'MonetarySource', + 'foreignKey' => 'monetary_type_id', 'dependent' => false, 'conditions' => '', 'fields' => '', diff --git a/site/models/payment.php b/site/models/payment.php deleted file mode 100644 index e3b2fc8..0000000 --- a/site/models/payment.php +++ /dev/null @@ -1,31 +0,0 @@ - array('numeric'), - 'receipt_id' => array('numeric'), - 'payment_type_id' => array('numeric'), - 'amount' => array('money') - ); - - //The Associations below have been created with all possible keys, those that are not needed can be removed - var $belongsTo = array( - 'Receipt' => array( - 'className' => 'Receipt', - 'foreignKey' => 'receipt_id', - 'conditions' => '', - 'fields' => '', - 'order' => '' - ), - 'PaymentType' => array( - 'className' => 'PaymentType', - 'foreignKey' => 'payment_type_id', - 'conditions' => '', - 'fields' => '', - 'order' => '' - ) - ); - -} -?> \ No newline at end of file diff --git a/site/models/receipt.php b/site/models/receipt.php deleted file mode 100644 index 66a2164..0000000 --- a/site/models/receipt.php +++ /dev/null @@ -1,46 +0,0 @@ - array('numeric'), - 'stamp' => array('time') - ); - - //The Associations below have been created with all possible keys, those that are not needed can be removed - var $hasMany = array( - 'Payment' => array( - 'className' => 'Payment', - 'foreignKey' => 'receipt_id', - 'dependent' => false, - 'conditions' => '', - 'fields' => '', - 'order' => '', - 'limit' => '', - 'offset' => '', - 'exclusive' => '', - 'finderQuery' => '', - 'counterQuery' => '' - ) - ); - - var $hasAndBelongsToMany = array( - 'Charge' => array( - 'className' => 'Charge', - 'joinTable' => 'charges_receipts', - 'foreignKey' => 'receipt_id', - 'associationForeignKey' => 'charge_id', - 'unique' => true, - 'conditions' => '', - 'fields' => '', - 'order' => '', - 'limit' => '', - 'offset' => '', - 'finderQuery' => '', - 'deleteQuery' => '', - 'insertQuery' => '' - ) - ); - -} -?> \ No newline at end of file diff --git a/site/models/transaction.php b/site/models/transaction.php new file mode 100644 index 0000000..d52f06e --- /dev/null +++ b/site/models/transaction.php @@ -0,0 +1,37 @@ + array('numeric'), + 'stamp' => array('time') + ); + + var $belongsTo = array( + 'Customer' => array( + 'className' => 'Customer', + 'foreignKey' => 'customer_id', + 'conditions' => '', + 'fields' => '', + 'order' => '' + ), + ); + + var $hasMany = array( + 'LedgerEntry' => array( + 'className' => 'LedgerEntry', + 'foreignKey' => 'transaction_id', + 'dependent' => false, + 'conditions' => '', + 'fields' => '', + 'order' => '', + 'limit' => '', + 'offset' => '', + 'exclusive' => '', + 'finderQuery' => '', + 'counterQuery' => '' + ) + ); + +} +?> \ No newline at end of file diff --git a/site/models/unit.php b/site/models/unit.php index fb0b173..d03ddaa 100644 --- a/site/models/unit.php +++ b/site/models/unit.php @@ -20,6 +20,13 @@ class Unit extends AppModel { 'fields' => '', 'order' => '' ), + 'CurrentLease' => array( + 'className' => 'Lease', + 'foreignKey' => 'current_lease_id', + 'conditions' => '', + 'fields' => '', + 'order' => '' + ), /* 'Map' => array( */ /* 'className' => 'MapsUnit', */ /* 'foreignKey' => 'unit_id', */ diff --git a/site/views/accounts/index.ctp b/site/views/accounts/index.ctp new file mode 100644 index 0000000..2518428 --- /dev/null +++ b/site/views/accounts/index.ctp @@ -0,0 +1,3 @@ +
+element('accounts', array('heading' => '

'.$heading.'

')) ?> +
diff --git a/site/views/accounts/view.ctp b/site/views/accounts/view.ctp new file mode 100644 index 0000000..8d252da --- /dev/null +++ b/site/views/accounts/view.ctp @@ -0,0 +1,95 @@ + + + diff --git a/site/views/charges/index.ctp b/site/views/charges/index.ctp deleted file mode 100644 index 1d4e8e3..0000000 --- a/site/views/charges/index.ctp +++ /dev/null @@ -1,3 +0,0 @@ -
-element('charges', array('heading' => '

'.$heading.'

')) ?> -
diff --git a/site/views/charges/view.ctp b/site/views/charges/view.ctp deleted file mode 100644 index ab4d948..0000000 --- a/site/views/charges/view.ctp +++ /dev/null @@ -1,87 +0,0 @@ - - -
- -element('table', - array('class' => 'item charge detail', - 'caption' => 'Charge Info', - 'rows' => $rows, - 'column_class' => array('field', 'value'))); - - -?> -
-
- Amount Received: -
-
- Amount Owing: -
-
-link('#'.$receipt['id'], - array('controller' => 'receipts', - 'action' => 'view', - $receipt['id'])), - datefmt($receipt['stamp']), - $receipt['comment'], - currency($receipt['ChargesReceipt']['amount']), - currency($running_total) - ); -} - -echo $this->element('table', - array('class' => 'item receipt list', - 'caption' => 'Receipts towards Charge', - 'headers' => $headers, - 'rows' => $rows, - 'column_class' => $headers)); - - -?> - -
diff --git a/site/views/contacts/view.ctp b/site/views/contacts/view.ctp index 7d7f48c..a4986a1 100644 --- a/site/views/contacts/view.ctp +++ b/site/views/contacts/view.ctp @@ -1,6 +1,6 @@ -
+
element('table', array('class' => 'item contact detail', - 'caption' => 'Tenant Info', + 'caption' => 'Contact Details', 'rows' => $rows, 'column_class' => array('field', 'value'))); +/********************************************************************** + * Contact Info Box + */ + ?> -
-
- Security Deposit: -
-
- Balance: -
+
+ +
element('table', /********************************************************************** - * Lease History + * Customers */ -$headers = array('Lease', 'Unit', 'Signed', 'Move-In', 'Move-Out', 'Rent', 'Deposit', 'Comment'); -$rows = array(); -foreach($contact['Lease'] AS $lease) { - $rows[] = array('#'.$lease['number'], - $html->link($lease['Unit']['name'], - array('controller' => 'units', - 'action' => 'view', - $lease['Unit']['id'])), - datefmt($lease['lease_date']), - datefmt($lease['movein_date']), - datefmt($lease['moveout_date']), - $lease['amount'], - $lease['deposit'], - $lease['comment']); -} - -echo $this->element('table', - array('class' => 'item lease list', - 'caption' => 'Lease History', - 'headers' => $headers, - 'rows' => $rows, - 'column_class' => $headers)); +echo $this->element('customers', array('heading' => '', + 'caption' => 'Related Customers', + 'customers' => $contact['Customer'])); -/********************************************************************** - * Ledger History - */ -foreach($contact['Lease'] AS $lease) { - $headers = array(/*'Charge/Receipt'*/'Charge', 'Date', 'Through', 'Type', 'Comment', 'Amount', 'Balance', 'Total'); - - $rows = array(); - $row_class = array(); - $running_total = 0; - $odd = 0; - foreach($lease['Charge'] AS $charge) { - $amount = $charge['total']; - - $balance = $amount; - foreach ($charge['Receipt'] AS $receipt) - $balance -= $receipt['ChargesReceipt']['amount']; - - $running_total += $balance; - - $rows[] = array($html->link('#'.$charge['id'], - array('controller' => 'charges', - 'action' => 'view', - $charge['id'])), - datefmt($charge['charge_date']), - datefmt($charge['charge_to_date']), - $charge['ChargeType']['name'], - $charge['comment'], - currency($amount), - currency($balance), - //currency($amount - $paid)); - currency($running_total)); - - $row_class[] = array('charge', (++$odd % 2) ? 'oddrow' : 'evnrow'); - - } - - echo $this->element('table', - array('class' => 'item ledger list', - 'caption' => 'Lease #'.$lease['number'].' (Unit: '.$lease['Unit']['name'].')', - 'suppress_alternate_rows' => true, - 'headers' => $headers, - 'rows' => $rows, - 'row_class' => $row_class, - 'column_class' => $headers)); -} -?> +/* End "detail supporting" DIV */ ?> +
diff --git a/site/views/customers/index.ctp b/site/views/customers/index.ctp new file mode 100644 index 0000000..b67aad4 --- /dev/null +++ b/site/views/customers/index.ctp @@ -0,0 +1,3 @@ +
+element('customers', array('heading' => '

'.$heading.'

')) ?> +
diff --git a/site/views/customers/view.ctp b/site/views/customers/view.ctp new file mode 100644 index 0000000..f55c9ec --- /dev/null +++ b/site/views/customers/view.ctp @@ -0,0 +1,189 @@ + + +
+ +element('table', + array('class' => 'item customer detail', + 'caption' => 'Tenant Info', + 'rows' => $rows, + 'column_class' => array('field', 'value'))); + + +/********************************************************************** + * Customer Info Box + */ + +?> +
+
+ Security Deposit: +
+
+ Balance: +
+
+ +
+element('contacts', + array('caption' => 'Customer Contacts', + 'contacts' => $customer['Contact'])); + + +/* foreach ($customer['Contact'] AS $contact) { */ + +/* /\********************************************************************** */ +/* * Phones */ +/* *\/ */ +/* $headers = array('Phone', 'Preference', 'Comment'); */ +/* $rows = array(); */ +/* foreach($contact['ContactPhone'] AS $phone) { */ +/* $rows[] = array(phone($phone['phone']) . */ +/* ($phone['ext'] ? " x".$phone['ext'] : ""), */ +/* $phone['ContactsMethod']['preference'] . " / " . */ +/* $phone['ContactsMethod']['type'] . " / " . */ +/* $phone['type'], */ +/* $phone['comment']); */ +/* } */ + +/* echo $this->element('table', */ +/* array('class' => 'item phone list', */ +/* 'caption' => 'Phone', */ +/* 'headers' => $headers, */ +/* 'rows' => $rows, */ +/* 'column_class' => $headers)); */ + + +/* /\********************************************************************** */ +/* * Emails */ +/* *\/ */ +/* $headers = array('Email', 'Preference', 'Comment'); */ +/* $rows = array(); */ +/* foreach($contact['ContactEmail'] AS $email) { */ +/* $rows[] = array($email['email'], */ +/* $email['ContactsMethod']['preference'] . " / " . */ +/* $email['ContactsMethod']['type'], */ +/* $email['comment']); */ +/* } */ + +/* echo $this->element('table', */ +/* array('class' => 'item email list', */ +/* 'caption' => 'Email', */ +/* 'headers' => $headers, */ +/* 'rows' => $rows, */ +/* 'column_class' => $headers)); */ + + +/* /\********************************************************************** */ +/* * Addresses */ +/* *\/ */ +/* $headers = array('Address', 'Preference', 'Comment'); */ +/* $rows = array(); */ +/* foreach($contact['ContactAddress'] AS $address) { */ +/* $rows[] = array(preg_replace("/\n/", "
\n", $address['address']) . "
\n" . */ +/* $address['city'] . ", " . */ +/* $address['state'] . " " . */ +/* $address['postcode'], */ +/* //. ? "
\n" . $address['country'], */ +/* $address['ContactsMethod']['preference'] . " / " . */ +/* $address['ContactsMethod']['type'], */ +/* $address['comment']); */ +/* } */ + +/* echo $this->element('table', */ +/* array('class' => 'item address list', */ +/* 'caption' => 'Address', */ +/* 'headers' => $headers, */ +/* 'rows' => $rows, */ +/* 'column_class' => $headers)); */ + + +/********************************************************************** + * Lease History + */ +$headers = array('Lease', 'Unit', 'Signed', 'Move-In', 'Move-Out', 'Rent', 'Deposit', 'Comment'); +$rows = array(); +foreach($customer['Lease'] AS $lease) { + $rows[] = array('#'.$lease['number'], + $html->link($lease['Unit']['name'], + array('controller' => 'units', + 'action' => 'view', + $lease['Unit']['id'])), + datefmt($lease['lease_date']), + datefmt($lease['movein_date']), + datefmt($lease['moveout_date']), + $lease['amount'], + $lease['deposit'], + $lease['comment']); +} + +echo $this->element('table', + array('class' => 'item lease list', + 'caption' => 'Lease History', + 'headers' => $headers, + 'rows' => $rows, + 'column_class' => $headers)); + + +/********************************************************************** + * Ledger History + */ +echo $this->element('ledger', + array('caption' => 'Ledger History', + 'transactions' => $customer['Transaction'], + 'ledger' => array('mix'=>1))); + +/* End "detail supporting" DIV */ ?> +
+ +
diff --git a/site/views/elements/accounts.ctp b/site/views/elements/accounts.ctp new file mode 100644 index 0000000..aaf9452 --- /dev/null +++ b/site/views/elements/accounts.ctp @@ -0,0 +1,85 @@ +'.__('Accounts',true).''; + +function currency($number) { + if ($number < 0) + return "($ " . number_format(-1*$number, 2) . ")"; + else + return "$ " . number_format($number, 2); +} + +function datefmt($date) { + $date_fmt = 'm/d/Y'; + return ($date + ? date_format(date_create($date), $date_fmt) + : null); +} + +$headers = array('Name', 'Type', 'Ext. Name', 'Ext. Account', 'Entries', 'Debits', 'Credits', 'Balance', 'Comment'); +$column_class = array(); +foreach (array_intersect($column_class, array('Debits', 'Credits', 'Balance')) AS $k => $v) { + $column_class[$k] = 'currency'; +} + +if (isset($paginator)) { + echo $paginator->counter(array( + 'format' => __('Page %page% of %pages%, showing %current% records (%start% - %end%) of %count% total', true))); + + $headers = array($paginator->sort('name'), + $paginator->sort('type'), + $paginator->sort('Ext. Name', 'external_name'), + $paginator->sort('Ext. Account', 'external_account'), + $paginator->sort('entries'), + $paginator->sort('debits'), + $paginator->sort('credits'), + $paginator->sort('balance'), + $paginator->sort('comment')); +} + +$rows = array(); +foreach ($accounts as $account) { + $extra = null; + if (isset($account[0])) { + $extra = $account[0]; + unset($account[0]); + } + if (isset($account['Account'])) + $account = $account['Account']; + + if (isset($extra)) + $account = array_merge($account, $extra); + + $rows[] = array($html->link($account['name'], + array('controller' => 'accounts', + 'action' => 'view', + $account['id'])), + $account['type'], + $account['external_name'], + $account['external_account'], + $account['entries'], + currency($account['debits']), + currency($account['credits']), + currency($account['balance']), + $account['comment'], + ); +} + +echo $this->element('table', + array('class' => 'item account list', + 'headers' => $headers, + 'rows' => $rows, + 'column_class' => $column_class)); + +if (isset($paginator)) { + echo('
' . "\n"); + echo $paginator->prev('<< '.__('previous', true), array(), null, array('class'=>'disabled')); + echo(' | '); + echo $paginator->numbers(); + echo(' | '); + echo $paginator->next(__('next', true).' >>', array(), null, array('class'=>'disabled')); + echo('
' . "\n"); +} diff --git a/site/views/elements/charges.ctp b/site/views/elements/charges.ctp deleted file mode 100644 index 461da13..0000000 --- a/site/views/elements/charges.ctp +++ /dev/null @@ -1,68 +0,0 @@ -'.__('Charges',true).''; - -function currency($number) { - if ($number < 0) - return "($ " . number_format(-1*$number, 2) . ")"; - else - return "$ " . number_format($number, 2); -} - -function datefmt($date) { - $date_fmt = 'm/d/Y'; - return ($date - ? date_format(date_create($date), $date_fmt) - : null); -} - -$headers_manual = array('ID', 'Date', 'Due', 'Type', 'Lease', 'Amount', 'Comment'); -if (isset($paginator)) { - echo $paginator->counter(array( - 'format' => __('Page %page% of %pages%, showing %current% records (%start% - %end%) of %count% total', true))); - - $headers = array($paginator->sort('id'), - $paginator->sort('Date', 'charge_date'), - $paginator->sort('Due', 'due_date'), - $paginator->sort('Type', 'charge_type'), - $paginator->sort('Lease', 'number'), - $paginator->sort('total'), - $paginator->sort('comment')); -} else { - $headers = $headers_manual; -} - - -$rows = array(); -foreach ($charges as $charge) { - $rows[] = array($html->link($charge['Charge']['id'], - array('controller' => 'charges', - 'action' => 'view', - $charge['Charge']['id'])), - datefmt($charge['Charge']['charge_date']), - datefmt($charge['Charge']['due_date']), - $charge['ChargeType']['name'], - '#'.$charge['Lease']['number'], - currency($charge['Charge']['total']), - $charge['Charge']['comment'], - ); -} - -echo $this->element('table', - array('class' => 'item charge list', - 'headers' => $headers, - 'rows' => $rows, - 'column_class' => $headers_manual)); - -if (isset($paginator)) { - echo('
' . "\n"); - echo $paginator->prev('<< '.__('previous', true), array(), null, array('class'=>'disabled')); - echo(' | '); - echo $paginator->numbers(); - echo(' | '); - echo $paginator->next(__('next', true).' >>', array(), null, array('class'=>'disabled')); - echo('
' . "\n"); -} diff --git a/site/views/elements/contacts.ctp b/site/views/elements/contacts.ctp index fca941d..54c10c3 100644 --- a/site/views/elements/contacts.ctp +++ b/site/views/elements/contacts.ctp @@ -2,44 +2,57 @@ if (isset($heading)) echo $heading; -else +elseif (!isset($caption)) echo '

'.__('Contacts',true).'

'; -$headers_manual = array('Id', 'Last Name', 'First Name', 'Company', 'Comment'); +$headers_manual = array_merge(array('Id', 'Last Name', 'First Name', 'Company'), + isset($contacts[0]['ContactsCustomer']) ? array('Type', 'Active') : array(), + array('Comment')); if (isset($paginator)) { echo $paginator->counter(array( 'format' => __('Page %page% of %pages%, showing %current% records (%start% - %end%) of %count% total', true))); - $headers = array($paginator->sort('id'), - $paginator->sort('last_name'), - $paginator->sort('first_name'), - $paginator->sort('company_name'), - //$paginator->sort('unit_id'), - $paginator->sort('comment')); + $headers = array_merge(array($paginator->sort('id'), + $paginator->sort('last_name'), + $paginator->sort('first_name'), + $paginator->sort('company_name')), + (isset($contacts[0]['ContactsCustomer']) + ? array($paginator->sort('type'), + $paginator->sort('active')) + : array()), + array($paginator->sort('comment'))); } else { $headers = $headers_manual; } $rows = array(); foreach ($contacts as $contact) { - $rows[] = array($html->link($contact['Contact']['id'], - array('controller' => 'contacts', - 'action' => 'view', - $contact['Contact']['id'])), - $html->link($contact['Contact']['last_name'], - array('controller' => 'contacts', - 'action' => 'view', - $contact['Contact']['id'])), - $html->link($contact['Contact']['first_name'], - array('controller' => 'contacts', - 'action' => 'view', - $contact['Contact']['id'])), - $contact['Contact']['company_name'], - $contact['Contact']['comment']); + if (isset($contact['Contact'])) + $contact = $contact['Contact']; + + $rows[] = array_merge(array($html->link($contact['id'], + array('controller' => 'contacts', + 'action' => 'view', + $contact['id'])), + $html->link($contact['last_name'], + array('controller' => 'contacts', + 'action' => 'view', + $contact['id'])), + $html->link($contact['first_name'], + array('controller' => 'contacts', + 'action' => 'view', + $contact['id'])), + $contact['company_name']), + (isset($contact['ContactsCustomer']) + ? array($contact['ContactsCustomer']['type'], + $contact['ContactsCustomer']['active'], + $contact['ContactsCustomer']['comment']) + : array($contact['comment']))); } echo $this->element('table', array('class' => 'item contact list', + 'caption' => isset($caption) ? $caption : null, 'headers' => $headers, 'rows' => $rows, 'column_class' => $headers_manual)); diff --git a/site/views/elements/receipts.ctp b/site/views/elements/customers.ctp similarity index 53% rename from site/views/elements/receipts.ctp rename to site/views/elements/customers.ctp index e89adbd..38cf034 100644 --- a/site/views/elements/receipts.ctp +++ b/site/views/elements/customers.ctp @@ -3,46 +3,39 @@ if (isset($heading)) echo $heading; else - echo '

'.__('Receipts',true).'

'; + echo '

'.__('Customers',true).'

'; -function currency($number) { - if ($number < 0) - return "($ " . number_format(-1*$number, 2) . ")"; - else - return "$ " . number_format($number, 2); -} - -function datefmt($date) { - $date_fmt = 'm/d/Y'; - return ($date - ? date_format(date_create($date), $date_fmt) - : null); -} - -$headers_manual = array('Id', 'Timestamp', 'Comment'); +$headers_manual = array('Id', 'Name', 'Comment'); if (isset($paginator)) { echo $paginator->counter(array( 'format' => __('Page %page% of %pages%, showing %current% records (%start% - %end%) of %count% total', true))); $headers = array($paginator->sort('id'), - $paginator->sort('Timestamp', 'stamp'), + $paginator->sort('name'), $paginator->sort('comment')); } else { $headers = $headers_manual; } $rows = array(); -foreach ($receipts as $receipt) { - $rows[] = array($html->link($receipt['Receipt']['id'], - array('controller' => 'receipts', +foreach ($customers as $customer) { + if (isset($customer['Customer'])) + $customer = $customer['Customer']; + + $rows[] = array($html->link($customer['id'], + array('controller' => 'customers', 'action' => 'view', - $receipt['Receipt']['id'])), - datefmt($receipt['Receipt']['stamp']), - $receipt['Receipt']['comment']); + $customer['id'])), + $html->link($customer['name'], + array('controller' => 'customers', + 'action' => 'view', + $customer['id'])), + $customer['comment']); } echo $this->element('table', - array('class' => 'item receipt list', + array('class' => 'item customer list', + 'caption' => isset($caption) ? $caption : null, 'headers' => $headers, 'rows' => $rows, 'column_class' => $headers_manual)); diff --git a/site/views/elements/ledger.ctp b/site/views/elements/ledger.ctp index 7e7cf04..4ae5d62 100644 --- a/site/views/elements/ledger.ctp +++ b/site/views/elements/ledger.ctp @@ -1,314 +1,80 @@ '.__('Payments',true).''; */ - -?> - -
- - -link('#'.$charge['id'], - array('controller' => 'charges', - 'action' => 'view', - $charge['id'])), - datefmt($charge['charge_date']), - datefmt($charge['charge_to_date']), - $charge['ChargeType']['name'], - $charge['comment'], - currency($amount), - currency($balance), - //currency($amount - $paid)); - currency($running_total)); - - $row_class[] = 'charge'; - } - - echo ('
' . "\n"); - echo $this->element('table', - array('class' => 'item ledger list', - 'caption' => $caption, - 'headers' => $headers, - 'rows' => $rows, - 'row_class' => $row_class, - 'column_class' => $headers)); - echo ('
' . "\n"); +$headers = array('Transaction', 'Entry', 'Date', 'Customer', 'Comment', 'Debit', 'Credit', 'Total'); +$column_class = $headers; +foreach (array_intersect($column_class, array('Transaction', 'Entry')) AS $k => $v) { + $column_class[$k] = array($column_class[$k], 'id'); } - - -/********************************************************************** - * Receipts Only - */ - -if (isset($ledger['receipts'])) { - $headers = array('Receipt', 'Date', 'Comment', 'Amount', 'Balance', 'Total'); - - $receipts = array(); - foreach ($lease['Charge'] AS $charge) { - foreach($charge['Receipt'] AS $receipt) { - if (!isset($receipts[$receipt['id']])) { - $receipts[$receipt['id']] = $receipt; - $receipts[$receipt['id']]['amount'] = 0; - $receipts[$receipt['id']]['charge'] = 0; - foreach($receipt['Payment'] AS $payment) - $receipts[$receipt['id']]['amount'] += $payment['amount']; - unset($receipts[$receipt['id']]['ChargesReceipt']); - unset($receipts[$receipt['id']]['Payment']); - } - $receipts[$receipt['id']]['charge'] += $receipt['ChargesReceipt']['amount']; - } - } - - usort($receipts, - create_function('$a, $b', - '$adate = TimeHelper::toUnix(isset($a["charge_date"]) ? $a["charge_date"] : $a["stamp"]); ' . - '$bdate = TimeHelper::toUnix(isset($b["charge_date"]) ? $b["charge_date"] : $b["stamp"]); ' . - 'return strcmp($adate, $bdate);') - ); - - $rows = array(); - $row_class = array(); - $running_total = 0; - - foreach ($receipts AS $receipt) { - $amount = $receipt['amount']; - $balance = $amount - $receipt['charge']; - $running_total += $balance; - - $rows[] = array($html->link('#'.$receipt['id'], - array('controller' => 'receipts', - 'action' => 'view', - $receipt['id'])), - datefmt($receipt['stamp']), - $receipt['comment'], - currency($amount), - currency($balance), - currency($running_total)); - - $row_class[] = 'receipt'; - } - - echo ('
' . "\n"); - echo $this->element('table', - array('class' => 'item ledger list', - 'caption' => $caption, - 'headers' => $headers, - 'rows' => $rows, - 'row_class' => $row_class, - 'column_class' => $headers)); - echo ('
' . "\n"); +foreach (array_intersect($column_class, array('Debits', 'Credits', 'Total')) AS $k => $v) { + $column_class[$k] = array($column_class[$k], 'currency'); } +/* if (isset($paginator)) { */ +/* echo $paginator->counter(array( */ +/* 'format' => __('Page %page% of %pages%, showing %current% records (%start% - %end%) of %count% total', true))); */ -/* $headers = array('Receipt', 'Date', 'Comment', 'Amount', 'Balance', 'Total'); */ - -/* $rows = array(); */ -/* $row_class = array(); */ -/* $running_total = 0; */ -/* $odd = 0; */ -/* foreach($lease['Receipt'] AS $charge) { */ -/* $amount = $charge['total']; */ - -/* $balance = $amount; */ -/* foreach ($charge['Receipt'] AS $receipt) */ -/* $balance -= $receipt['ChargesReceipt']['amount']; */ - -/* $running_total += $balance; */ - - -/* $charge_amount = 0; */ -/* $payment_amount = 0; */ -/* foreach($receipt['Charge'] AS $charge) */ -/* $charge_amount += $charge['ChargesReceipt']['amount']; */ -/* foreach($receipt['Payment'] AS $payment) */ -/* $payment_amount += $payment['amount']; */ - -/* foreach ($charge['Receipt'] AS $receipt) { */ -/* $amount = -1 * $receipt['ChargesReceipt']['amount']; */ -/* $running_total += $amount; */ -/* $rows[] = array($html->link('#'.$receipt['id'], */ -/* array('controller' => 'receipts', */ -/* 'action' => 'view', */ -/* $receipt['id'])), */ -/* datefmt($receipt['stamp']), */ -/* $receipt['comment'], */ -/* currency($amount), */ -/* currency($running_total)); */ -/* $row_class[] = array('receipt', ($odd % 2) ? 'oddrow' : 'evnrow'); */ -/* } */ - -/* $rows[] = array($html->link('#'.$charge['id'], */ -/* array('controller' => 'charges', */ -/* 'action' => 'view', */ -/* $charge['id'])), */ -/* datefmt($charge['charge_date']), */ -/* datefmt($charge['charge_to_date']), */ -/* $charge['ChargeType']['name'], */ -/* $charge['comment'], */ -/* currency($amount), */ -/* currency($balance), */ -/* //currency($amount - $paid)); */ -/* currency($running_total)); */ - -/* $row_class[] = array('charge', (++$odd % 2) ? 'oddrow' : 'evnrow'); */ +/* $headers = array($paginator->sort('Transaction', 'transaction_id'), */ +/* $paginator->sort('entry_id'), */ +/* $paginator->sort('Date', 'stamp'), */ +/* $paginator->sort('customer_id'), */ +/* $paginator->sort('comment'), */ +/* $paginator->sort('debit'), */ +/* $paginator->sort('credit'), */ +/* $paginator->sort('total')); */ /* } */ -/* echo ('
' . "\n"); */ -/* echo $this->element('table', */ -/* array('class' => 'item ledger list', */ -/* 'caption' => $caption */ -/* 'suppress_alternate_rows' => true, */ -/* 'headers' => $headers, */ -/* 'rows' => $rows, */ -/* 'row_class' => $row_class, */ -/* 'column_class' => $headers)); */ -/* echo ('
' . "\n"); */ +$rows = array(); +$running_total = 0; +foreach($entries AS $entry) { + $transaction = $entry['Transaction']; + $customer = $entry['Customer']; + $credit = $debit = null; + $running_total += $entry['balance']; -/********************************************************************** - * Mixture - */ + if (isset($entry['debit'])) + $debit = $entry['debit']; + if (isset($entry['credit'])) + $credit = $entry['credit']; -if (isset($ledger['mix'])) { - $headers = array(/*'Charge/Receipt'*/'ID', 'Date', /*'Through',*/ 'Type', 'Comment', 'Amount', 'Total'); + // Now that we've extracted top level 'entry' data + // move our variable to the meat of 'LedgerEntry' for clarity + $entry = $entry['LedgerEntry']; -/* $mix = array_merge($lease['Charge'], $receipts); */ -/* usort($mix, */ -/* create_function('$a, $b', */ -/* '$adate = TimeHelper::toUnix(isset($a["charge_date"]) ? $a["charge_date"] : $a["stamp"]); ' . */ -/* '$bdate = TimeHelper::toUnix(isset($b["charge_date"]) ? $b["charge_date"] : $b["stamp"]); ' . */ -/* 'return strcmp($adate, $bdate);') */ -/* ); */ - - $rows = array(); - $row_class = array(); - $running_total = 0; - - foreach ($transactions AS $transaction) { - $transaction_date = datefmt($transaction['stamp']); - if (isset($transaction['through_date'])) - $transaction_date .= ' - '. datefmt($transaction['through_date']); - - $comment = $transaction['comment']; - - foreach ($transaction['Entry'] AS $entry) { - if ($entry['DebitAccount']['name'] === 'A/R') { - $name = $entry['CreditAccount']['name']; - $amount = $entry['amount']; - $class = 'charge'; - } - elseif ($entry['CreditAccount']['name'] === 'A/R') { - $name = 'Payment'; - $amount = -1 * $entry['amount']; - $class = 'payment'; - } - else - continue; - - $running_total += $amount; - $rows[] = array($html->link('#'.$transaction['id'], - array('controller' => 'transactions', - 'action' => 'view', - $transaction['id'])), - $transaction_date, - $name, - $comment, - currency($amount), - currency($running_total)); - $row_class[] = $class; - } - } - - echo ('
' . "\n"); - echo $this->element('table', - array('class' => 'item ledger list', - 'caption' => $caption, - //'suppress_alternate_rows' => true, - 'headers' => $headers, - 'rows' => $rows, - 'row_class' => $row_class, - 'column_class' => $headers)); - echo ('
' . "\n"); + $rows[] = array($html->link('#'.$transaction['id'], + array('controller' => 'transactions', + 'action' => 'view', + $transaction['id'])), + $html->link('#'.$entry['id'], + array('controller' => 'ledger_entries', + 'action' => 'view', + $entry['id'])), + datefmt($transaction['stamp']), + $html->link($customer['name'], + array('controller' => 'customers', + 'action' => 'view', + $customer['id'])), + comment(array($transaction['comment'], $entry['comment'])), + currency($debit), + currency($credit), + currency($running_total) + ); } -/********************************************************************** - * Match - */ +echo $this->element('table', + array('class' => 'item account ledger list', + 'caption' => $caption, + 'headers' => $headers, + 'rows' => $rows, + 'column_class' => $column_class)); -if (isset($ledger['match'])) { - $headers = array(/*'Charge/Receipt'*/'ID', 'Date', /*'Through',*/ 'Type', 'Comment', 'Amount', 'Total'); +/* if (isset($paginator)) { */ +/* echo('
' . "\n"); */ +/* echo $paginator->prev('<< '.__('previous', true), array(), null, array('class'=>'disabled')); */ +/* echo(' | '); */ +/* echo $paginator->numbers(); */ +/* echo(' | '); */ +/* echo $paginator->next(__('next', true).' >>', array(), null, array('class'=>'disabled')); */ +/* echo('
' . "\n"); */ +/* } */ - $rows = array(); - $row_class = array(); - $running_total = 0; - $odd = 0; - foreach($lease['Charge'] AS $charge) { - $amount = $charge['total']; - $running_total += $amount; - $rows[] = array($html->link('#'.$charge['id'], - array('controller' => 'charges', - 'action' => 'view', - $charge['id'])), - datefmt($charge['charge_date']) .' - '. datefmt($charge['charge_to_date']), - $charge['ChargeType']['name'], - $charge['comment'], - currency($amount), - currency($running_total)); - $row_class[] = array('charge', (++$odd % 2) ? 'oddrow' : 'evnrow'); - - foreach ($charge['Receipt'] AS $receipt) { - $amount = -1 * $receipt['ChargesReceipt']['amount']; - $running_total += $amount; - $rows[] = array($html->link('#'.$receipt['id'], - array('controller' => 'receipts', - 'action' => 'view', - $receipt['id'])), - ' -- ' . datefmt($receipt['stamp']), - 'Payment Applied', - $receipt['comment'], - currency($amount), - currency($running_total)); - $row_class[] = array('receipt', ($odd % 2) ? 'oddrow' : 'evnrow'); - } - } - - echo ('
' . "\n"); - echo $this->element('table', - array('class' => 'item ledger list', - 'caption' => $caption, - 'suppress_alternate_rows' => true, - 'headers' => $headers, - 'rows' => $rows, - 'row_class' => $row_class, - 'column_class' => $headers)); - echo ('
' . "\n"); -} \ No newline at end of file +?> diff --git a/site/views/elements/ledgers.ctp b/site/views/elements/ledgers.ctp new file mode 100644 index 0000000..13c4219 --- /dev/null +++ b/site/views/elements/ledgers.ctp @@ -0,0 +1,77 @@ +'.__('Ledgers',true).''; + +$headers = array_merge(array('Name'), + (isset($ledgers[0]['Account']) + ? array('Account') + : array()), + array('Entries', 'Debits', 'Credits', 'Balance', 'Closed', 'Comment')); +$column_class = array(); +foreach (array_intersect($column_class, array('Comment')) AS $k => $v) { + $column_class[$k] = 'comment'; +} + +if (isset($paginator)) { + echo $paginator->counter(array( + 'format' => __('Page %page% of %pages%, showing %current% records (%start% - %end%) of %count% total', true))); + + $headers = array_merge(array($paginator->sort('name')), + (isset($ledgers[0]['Account']) + ? array($paginator->sort('Account', 'Account.name')) + : array()), + array($paginator->sort('entries'), + $paginator->sort('debits'), + $paginator->sort('credits'), + $paginator->sort('balance'), + $paginator->sort('closed'), + $paginator->sort('comment'))); +} + +$rows = array(); +foreach ($ledgers as $ledger) { + if (isset($ledger[0])) + $ledger = array_merge($ledger[0], array_diff_key($ledger, array(0=>1))); + if (isset($ledger['Ledger'])) + $ledger = array_merge($ledger['Ledger'], array_diff_key($ledger, array('Ledger'=>1))); + + if (isset($ledger['Account'])) + $account = $ledger['Account']; + + $rows[] = array_merge(array($html->link($ledger['name'], + array('controller' => 'ledgers', + 'action' => 'view', + $ledger['id']))), + (isset($ledger['Account']) + ? array($html->link($account['name'], + array('controller' => 'accounts', + 'action' => 'view', + $account['id']))) + : array()), + array($ledger['entries'], + currency($ledger['debits']), + currency($ledger['credits']), + currency($ledger['balance']), + $ledger['closed'] ? 'Closed' : 'Open', + $ledger['comment'])); +} + +echo $this->element('table', + array('class' => 'item ledger list', + 'caption' => isset($caption) ? $caption : null, + 'headers' => $headers, + 'rows' => $rows, + 'column_class' => $column_class)); + +if (isset($paginator)) { + echo('
' . "\n"); + echo $paginator->prev('<< '.__('previous', true), array(), null, array('class'=>'disabled')); + echo(' | '); + echo $paginator->numbers(); + echo(' | '); + echo $paginator->next(__('next', true).' >>', array(), null, array('class'=>'disabled')); + echo('
' . "\n"); +} diff --git a/site/views/elements/payments.ctp b/site/views/elements/payments.ctp deleted file mode 100644 index 6a8818c..0000000 --- a/site/views/elements/payments.ctp +++ /dev/null @@ -1,67 +0,0 @@ -'.__('Payments',true).''; - -function currency($number) { - if ($number < 0) - return "($ " . number_format(-1*$number, 2) . ")"; - else - return "$ " . number_format($number, 2); -} - -function datefmt($date) { - $date_fmt = 'm/d/Y'; - return ($date - ? date_format(date_create($date), $date_fmt) - : null); -} - -$headers_manual = array('ID', 'Type', 'Receipt', 'Amount', 'Comment'); -if (isset($paginator)) { - echo $paginator->counter(array( - 'format' => __('Page %page% of %pages%, showing %current% records (%start% - %end%) of %count% total', true))); - - $headers = array($paginator->sort('id'), - $paginator->sort('Type', 'payment_type'), - $paginator->sort('Receipt', 'receipt_id'), - $paginator->sort('amount'), - $paginator->sort('comment')); -} else { - $headers = $headers_manual; -} - - -$rows = array(); -foreach ($payments as $payment) { - $rows[] = array($html->link($payment['Payment']['id'], - array('controller' => 'payments', - 'action' => 'view', - $payment['Payment']['id'])), - $payment['PaymentType']['name'], - $html->link('#'.$payment['Receipt']['id'], - array('controller' => 'receipts', - 'action' => 'view', - $payment['Receipt']['id'])), - currency($payment['Payment']['amount']), - $payment['Payment']['comment'], - ); -} - -echo $this->element('table', - array('class' => 'item payment list', - 'headers' => $headers, - 'rows' => $rows, - 'column_class' => $headers_manual)); - -if (isset($paginator)) { - echo('
' . "\n"); - echo $paginator->prev('<< '.__('previous', true), array(), null, array('class'=>'disabled')); - echo(' | '); - echo $paginator->numbers(); - echo(' | '); - echo $paginator->next(__('next', true).' >>', array(), null, array('class'=>'disabled')); - echo('
' . "\n"); -} diff --git a/site/views/elements/table.ctp b/site/views/elements/table.ctp index de95c71..32bc8d5 100644 --- a/site/views/elements/table.ctp +++ b/site/views/elements/table.ctp @@ -32,7 +32,7 @@ if (isset($rows) && is_array($rows) && count($rows)) { if (!is_array($rca)) $rca = array($rca); foreach ($rca AS &$rc) - $rc = preg_replace("/ /", "-", strtolower($rc)); + $rc = preg_replace("/ /", "-", preg_replace('/\./', '', strtolower($rc))); } // Same prework for column_class @@ -40,7 +40,7 @@ if (isset($rows) && is_array($rows) && count($rows)) { if (!is_array($cca)) $cca = array($cca); foreach ($cca AS &$cc) - $cc = preg_replace("/ /", "-", strtolower($cc)); + $cc = preg_replace("/ /", "-", preg_replace('/\./', '', strtolower($cc))); } // Associate each cell with the appropriate class(es). diff --git a/site/views/elements/transactions.ctp b/site/views/elements/transactions.ctp new file mode 100644 index 0000000..abf2535 --- /dev/null +++ b/site/views/elements/transactions.ctp @@ -0,0 +1,65 @@ +'.__('Transactions',true).''; + +$headers = array('Id', 'Timestamp', 'Comment'); +$column_class = array(); +foreach (array_intersect($headers, array('Comment')) AS $k => $v) { + $column_class[$k] = 'comment'; +} +foreach (array_intersect($headers, array('Id')) AS $k => $v) { + $column_class[$k] = 'id'; +} + +if (isset($paginator)) { + echo $paginator->counter(array( + 'format' => __('Page %page% of %pages%, showing %current% records (%start% - %end%) of %count% total', true))); + + $headers = array($paginator->sort('id'), + $paginator->sort('customer_id'), + $paginator->sort('Timestamp', 'stamp'), + $paginator->sort('Through', 'through_date'), + $paginator->sort('Due', 'due_date'), + $paginator->sort('comment')); +} + +$rows = array(); +foreach ($transactions as $transaction) { + $customer = $transaction['Customer']; + + if (isset($transaction['Transaction'])) + $transaction = $transaction['Transaction']; + + $rows[] = array($html->link('#'.$transaction['id'], + array('controller' => 'transactions', + 'action' => 'view', + $transaction['id'])), + $html->link($customer['name'], + array('controller' => 'customers', + 'action' => 'view', + $customer['id'])), + datefmt($transaction['stamp']), + datefmt($transaction['through_date']), + datefmt($transaction['due_date']), + $transaction['comment']); +} + +echo $this->element('table', + array('class' => 'item transaction list', + 'caption' => isset($caption) ? $caption : null, + 'headers' => $headers, + 'rows' => $rows, + 'column_class' => $column_class)); + +if (isset($paginator)) { + echo('
' . "\n"); + echo $paginator->prev('<< '.__('previous', true), array(), null, array('class'=>'disabled')); + echo(' | '); + echo $paginator->numbers(); + echo(' | '); + echo $paginator->next(__('next', true).' >>', array(), null, array('class'=>'disabled')); + echo('
' . "\n"); +} diff --git a/site/views/ledgers/index.ctp b/site/views/ledgers/index.ctp new file mode 100644 index 0000000..ad27c94 --- /dev/null +++ b/site/views/ledgers/index.ctp @@ -0,0 +1,14 @@ +
+ +element('ledgers', array('heading' => '

'.$heading.'

')) ?> +
diff --git a/site/views/ledgers/view.ctp b/site/views/ledgers/view.ctp new file mode 100644 index 0000000..63320e3 --- /dev/null +++ b/site/views/ledgers/view.ctp @@ -0,0 +1,98 @@ + + +
+ +link($ledger['Account']['name'], + array('controller' => 'accounts', + 'action' => 'view', + $ledger['Account']['id']))), + array('Closed', $ledger['Ledger']['closed']), + array('Comment', $ledger['Ledger']['comment'])); + +echo $this->element('table', + array('class' => 'item ledger detail', + 'caption' => 'Ledger Detail', + 'rows' => $rows, + 'column_class' => array('field', 'value'))); + + +/********************************************************************** + * Ledger Info Box + */ + +?> + +
+
+ Ledger Balance: +
+
+ +
+element('ledger', + array('caption' => $ledger['Ledger']['name'], + 'ledger' => array('id' => $ledger['Ledger']['id'], + 'type' => $ledger['Account']['type']), + 'entries' => $ledger['LedgerEntry'])); + +/* End "detail supporting" DIV */ ?> +
+ +
diff --git a/site/views/payments/index.ctp b/site/views/payments/index.ctp deleted file mode 100644 index 4258e83..0000000 --- a/site/views/payments/index.ctp +++ /dev/null @@ -1,3 +0,0 @@ -
-element('payments', array('heading' => '

'.$heading.'

')) ?> -
diff --git a/site/views/payments/view.ctp b/site/views/payments/view.ctp deleted file mode 100644 index 7bca3fd..0000000 --- a/site/views/payments/view.ctp +++ /dev/null @@ -1,43 +0,0 @@ - - -
- -link('#'.$payment['Receipt']['id'], - array('controller' => 'receipts', - 'action' => 'view', - $payment['Receipt']['id']))), - array('Amount', currency($payment['Payment']['amount'])), - array('Comment', $payment['Payment']['comment'])); - -echo $this->element('table', - array('class' => 'item payment detail', - 'caption' => 'Payment Info', - 'rows' => $rows, - 'column_class' => array('field', 'value'))); - - -?> - -
diff --git a/site/views/receipts/index.ctp b/site/views/receipts/index.ctp deleted file mode 100644 index e6ce32d..0000000 --- a/site/views/receipts/index.ctp +++ /dev/null @@ -1,3 +0,0 @@ -
-element('receipts', array('heading' => '

'.$heading.'

')) ?> -
diff --git a/site/views/receipts/view.ctp b/site/views/receipts/view.ctp deleted file mode 100644 index 3b4c42f..0000000 --- a/site/views/receipts/view.ctp +++ /dev/null @@ -1,116 +0,0 @@ - - -
- -element('table', - array('class' => 'item receipt detail', - 'caption' => 'Receipt Info', - 'rows' => $rows, - 'column_class' => array('field', 'value'))); - - -?> -
-
- Amount Received: -
-
- Amount Applied: -
-
-link('#'.$payment['id'], - array('controller' => 'payments', - 'action' => 'view', - $payment['id'])), - $payment['PaymentType']['name'], - $payment['comment'], - currency($payment['amount']), - currency($running_total) - ); -} - -echo $this->element('table', - array('class' => 'item payment list', - 'caption' => 'Payments in Receipt', - 'headers' => $headers, - 'rows' => $rows, - 'column_class' => $headers)); - - -/********************************************************************** - * Charges - */ - -$headers = array('ID', 'Date', /*'Due',*/ 'Type', 'Lease', 'Comment', 'Amount' /*, 'Tax', 'Subtotal'*/, 'Applied', /*'Total'*/); -$rows = array(); -$running_total = 0; -foreach($receipt['Charge'] AS $charge) { - $amount = $charge['total']; - $running_total += $amount; - $rows[] = array($html->link('#'.$charge['id'], - array('controller' => 'charges', - 'action' => 'view', - $charge['id'])), - datefmt($charge['charge_date']) .' - '. datefmt($charge['charge_to_date']), - //datefmt($charge['due_date']), - $charge['ChargeType']['name'], - '#'.$charge['Lease']['number'], - $charge['comment'], - //currency($charge['amount']), - //currency($charge['tax']), - currency($charge['total']), - currency($charge['ChargesReceipt']['amount']), - //currency($running_total) - ); -} - -echo $this->element('table', - array('class' => 'item charge list', - 'caption' => 'Charges Applied Towards', - 'headers' => $headers, - 'rows' => $rows, - 'column_class' => $headers)); - - - -?> - -
diff --git a/site/views/transactions/index.ctp b/site/views/transactions/index.ctp new file mode 100644 index 0000000..16f1c5c --- /dev/null +++ b/site/views/transactions/index.ctp @@ -0,0 +1,13 @@ +
+ + + +element('transactions', array('heading' => '

'.$heading.'

')) ?> +
diff --git a/site/views/transactions/view.ctp b/site/views/transactions/view.ctp new file mode 100644 index 0000000..3a9e87f --- /dev/null +++ b/site/views/transactions/view.ctp @@ -0,0 +1,102 @@ + + +
+ +element('table', + array('class' => 'item transaction detail', + 'caption' => 'Transaction Info', + 'rows' => $rows, + 'column_class' => array('field', 'value'))); + + +/********************************************************************** + * Transaction Info Box + */ + +?> +
+
+ Debits: +
+
+ Credits: +
+
+ +
+link($entry['DebitLedger']['name'], + array('controller' => 'ledgers', + 'action' => 'view', + $entry['DebitLedger']['id'])), + $html->link($entry['CreditLedger']['name'], + array('controller' => 'ledgers', + 'action' => 'view', + $entry['CreditLedger']['id'])), + $entry['comment'], + currency($entry['amount']), + currency($running_total) + ); +} + +echo $this->element('table', + array('class' => 'item entry list', + 'caption' => 'Entries in Transaction', + 'headers' => $headers, + 'rows' => $rows, + 'column_class' => $headers)); + + +/* End "detail supporting" DIV */ ?> +
+ +
diff --git a/site/views/units/view.ctp b/site/views/units/view.ctp index 04a84a8..5bc79ce 100644 --- a/site/views/units/view.ctp +++ b/site/views/units/view.ctp @@ -1,6 +1,6 @@ -
+
element('table', 'column_class' => array('field', 'value'))); +/********************************************************************** + * Unit Info Box + */ + ?> -
+
Security Deposit:
@@ -42,7 +51,17 @@ echo $this->element('table', Balance:
+ +
link($lease['Contact'][0]['display_name'], - array('controller' => 'contacts', + $html->link($lease['Customer']['name'], + array('controller' => 'customers', 'action' => 'view', - $lease['Contact'][0]['id'])), + $lease['Customer']['id'])), datefmt($lease['lease_date']), datefmt($lease['movein_date']), datefmt($lease['moveout_date']), @@ -76,12 +95,15 @@ echo $this->element('table', * Ledger History */ foreach($unit['Lease'] AS $lease) { - $caption = 'Lease #'.$lease['number'].' (Tenant: '.$lease['Contact'][0]['display_name'].')'; + pr($lease); + $caption = 'Lease #'.$lease['number'].' (Tenant: '.$lease['Customer']['name'].')'; echo $this->element('ledger', - array('lease' => $lease, - 'caption' => $caption, - 'ledger' => array('charges'=>1, 'receipts'=>1, 'match'=>1, 'zmix'=>1))); + array('caption' => $caption, + 'entries' => $lease['Customer']['Transaction'], + 'ledger' => array('mix'=>1))); } -?> + +/* End "detail supporting" DIV */ ?> +
diff --git a/site/webroot/css/layout.css b/site/webroot/css/layout.css index b814585..3f7e015 100644 --- a/site/webroot/css/layout.css +++ b/site/webroot/css/layout.css @@ -60,45 +60,16 @@ tr.evnrow { background: #f4f4f4; } /************************************************************ ************************************************************ - * Item table formats + * Item detail formats + * (such as Tenant Info, Unit Info, etc) */ -/* Item listing width and borders */ -table.detail { width : 60%; } -table.list { width : 100%; } +table.detail { width : 60%; + float: left; } +table.detail td.field { width: 10em; } -/* Text alignment exceptions */ -table.list td.id { text-align: center; } +div.detail.supporting { clear : both; } -/* White spacing exceptions */ -td.comment { white-space: normal; } - -/* Detail Tables (such as Tenant Info, Unit Info, etc) */ -table.detail { float: left; } -table.detail td.field { width: 10em; } - -/* List Tables (listing multiple items of one type) */ -table.list { clear: both; } - -/* Contact methods */ -table.list.phone td.preference , -table.list.email td.preference , -table.list.address td.preference { width: 18em; } -table.list.phone td.phone , -table.list.email td.email , -table.list.address td.address { width: 15em; } -table.list.phone td.comment , -table.list.email td.comment , -table.list.address td.comment { width: auto; } - -/* Leases */ -table.list.lease td.comment { width : 99%; } - -/* Ledger Entries */ -table.list.ledger td { border-top : 1px dashed #ccc; } -table.list.ledger td.date.receipt { padding-left: 1em; } -table.list.ledger td.evnrow { background: #f4f4f4; } -table.list.ledger td.comment { width : 99%; } /************************************************************ @@ -123,6 +94,48 @@ div.summary { color: #993; } +/************************************************************ + ************************************************************ + * Item table formats + * (listing multiple items of one type) + */ + +/* Item listing width and borders */ +table.list { width : 100%; } + +/* Text alignment exceptions */ +table.list td.id { text-align: center; } +table.list td.currency { text-align: right; } + +/* White spacing exceptions */ +td.comment { white-space: normal; } + +/* Contacts */ +table.list.contact td.comment { width : 66%; } + +/* Contact methods */ +table.list.phone td.preference , +table.list.email td.preference , +table.list.address td.preference { width: 18em; } +table.list.phone td.phone , +table.list.email td.email , +table.list.address td.address { width: 15em; } +table.list.phone td.comment , +table.list.email td.comment , +table.list.address td.comment { width: auto; } + +/* Leases */ +table.list.lease td.comment { width : 99%; } + +/* Ledger Entries */ +table.list.ledger td { border-top : 1px dashed #ccc; } +table.list.ledger td.date.receipt { padding-left: 1em; } +table.list.ledger td.evnrow { background: #f4f4f4; } +table.list.ledger td.comment { width : 99%; } + +/* Account Ledger Entries */ + + /************************************************************ ************************************************************ * General Style Info