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
This commit is contained in:
abijah
2009-06-06 20:18:56 +00:00
parent 30b934823c
commit f3ffa3c079
54 changed files with 3066 additions and 2125 deletions

View File

@@ -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' => ''
)
),
);
}

View File

@@ -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);

View File

@@ -1,53 +0,0 @@
<?php
class Charge extends AppModel {
var $name = 'Charge';
var $validate = array(
'id' => array('numeric'),
'charge_type_id' => array('numeric'),
'lease_id' => array('numeric'),
'charge_date' => array('date'),
'charge_to_date' => array('date'),
'due_date' => array('date'),
'amount' => array('money'),
'tax' => array('money'),
'total' => array('money')
);
var $belongsTo = array(
'ChargeType' => array(
'className' => 'ChargeType',
'foreignKey' => 'charge_type_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Lease' => array(
'className' => 'Lease',
'foreignKey' => 'lease_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
var $hasAndBelongsToMany = array(
'Receipt' => array(
'className' => 'Receipt',
'joinTable' => 'charges_receipts',
'foreignKey' => 'charge_id',
'associationForeignKey' => 'receipt_id',
'unique' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
)
);
}
?>

View File

@@ -1,39 +0,0 @@
<?php
class ChargeType extends AppModel {
var $name = 'ChargeType';
var $validate = array(
'id' => array('numeric'),
'name' => array('notempty'),
'account_id' => array('numeric')
);
//The Associations below have been created with all possible keys, those that are not needed can be removed
/* var $belongsTo = array( */
/* 'Account' => array( */
/* 'className' => 'Account', */
/* 'foreignKey' => 'account_id', */
/* 'conditions' => '', */
/* 'fields' => '', */
/* 'order' => '' */
/* ) */
/* ); */
var $hasMany = array(
'Charge' => array(
'className' => 'Charge',
'foreignKey' => 'charge_type_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
}
?>

View File

@@ -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' => '',

58
site/models/customer.php Normal file
View File

@@ -0,0 +1,58 @@
<?php
class Customer extends AppModel {
var $name = 'Customer';
var $validate = array(
'id' => 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' => ''
),
);
}
?>

View File

@@ -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' => ''
),
);
}

65
site/models/ledger.php Normal file
View File

@@ -0,0 +1,65 @@
<?php
class Ledger extends AppModel {
var $name = 'Ledger';
var $validate = array(
'id' => 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' => ''
),
);
}
?>

View File

@@ -0,0 +1,43 @@
<?php
class LedgerEntry extends AppModel {
var $name = 'LedgerEntry';
var $validate = array(
'id' => 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' => ''
),
);
}
?>

View File

@@ -0,0 +1,28 @@
<?php
class MonetarySource extends AppModel {
var $name = 'MonetarySource';
var $validate = array(
'id' => 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' => ''
)
);
}
?>

View File

@@ -1,18 +1,17 @@
<?php
class PaymentType extends AppModel {
class MonetaryType extends AppModel {
var $name = 'PaymentType';
var $name = 'MonetaryType';
var $validate = array(
'id' => array('numeric'),
'name' => array('notempty'),
'tillable' => array('boolean')
);
//The Associations below have been created with all possible keys, those that are not needed can be removed
var $hasMany = array(
'Payment' => array(
'className' => 'Payment',
'foreignKey' => 'payment_type_id',
'MonetarySource' => array(
'className' => 'MonetarySource',
'foreignKey' => 'monetary_type_id',
'dependent' => false,
'conditions' => '',
'fields' => '',

View File

@@ -1,31 +0,0 @@
<?php
class Payment extends AppModel {
var $name = 'Payment';
var $validate = array(
'id' => array('numeric'),
'receipt_id' => array('numeric'),
'payment_type_id' => array('numeric'),
'amount' => array('money')
);
//The Associations below have been created with all possible keys, those that are not needed can be removed
var $belongsTo = array(
'Receipt' => array(
'className' => 'Receipt',
'foreignKey' => 'receipt_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'PaymentType' => array(
'className' => 'PaymentType',
'foreignKey' => 'payment_type_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
}
?>

View File

@@ -1,46 +0,0 @@
<?php
class Receipt extends AppModel {
var $name = 'Receipt';
var $validate = array(
'id' => array('numeric'),
'stamp' => array('time')
);
//The Associations below have been created with all possible keys, those that are not needed can be removed
var $hasMany = array(
'Payment' => array(
'className' => 'Payment',
'foreignKey' => 'receipt_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
var $hasAndBelongsToMany = array(
'Charge' => array(
'className' => 'Charge',
'joinTable' => 'charges_receipts',
'foreignKey' => 'receipt_id',
'associationForeignKey' => 'charge_id',
'unique' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
)
);
}
?>

View File

@@ -0,0 +1,37 @@
<?php
class Transaction extends AppModel {
var $name = 'Transaction';
var $validate = array(
'id' => 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' => ''
)
);
}
?>

View File

@@ -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', */