3
* PurchaseDBO.class.php
5
* This file contains the definition for the PurchaseDBO class.
8
* @author John Diamond <jdiamond@solid-state.org>
9
* @copyright John Diamond <jdiamond@solid-state.org>
10
* @license http://www.opensource.org/licenses/gpl-license.php GNU Public License
14
require_once BASE_PATH . "solidworks/DBO.class.php";
19
* Represent a Purchase. This class is abstract, it is implemented by the
20
* DomainServicePurchase, HostingServicePurchase, and ProductPurchase classes.
23
* @author John Diamond <jdiamond@solid-state.org>
25
class PurchaseDBO extends DBO
28
* @var string Purchase date (MySQL datetime)
33
* @var string Purchase term ("1 month", "3 month", ..., "10 year")
40
* Given a Tax Rule, determine the amount of tax on this purchase
42
* @param TaxRuleDBO $taxruledbo Tax rule
43
* @return float Amount of tax
45
function calculateTax( $taxruledbo )
47
return $this->getPrice() * ($taxruledbo->getRate() / 100.00);
53
* @return string Purchase date (MySQL datetime)
63
* @return float Price of this purchase
65
function getPrice() { return 0; }
70
* @return float Setup fee
72
function getSetupFee() { return 0; }
77
* @return array An array of tax rules that apply to this purchase
83
if( !$this->isTaxable() )
89
"country=" . $DB->quote_smart( $this->accountdbo->getCountry() ) . " AND (" .
90
"allstates=" . $DB->quote_smart( "YES" ) . " OR " .
91
"state=" . $DB->quote_smart( $this->accountdbo->getState() ) . ")";
92
$taxes = load_array_TaxRuleDBO( $filter );
94
return $taxes == null ? array() : $taxes;
100
* @return string Purchase term (as string: "1 month", "3 month", etc.)
102
function getTerm() { return $this->term; }
105
* Get Purchase Term (in months)
107
* Gives the length of the purchase terms in months.
109
* @return integer Length of the purchase term in months
111
function getTermMonths()
113
switch( $this->getTerm() )
115
case "1 month": return 1;
116
case "3 month": return 3;
117
case "6 month": return 6;
119
case "1 year": return 12;
120
case "2 year": return 24;
121
case "3 year": return 36;
122
case "4 year": return 48;
123
case "5 year": return 60;
124
case "6 year": return 72;
125
case "7 year": return 84;
126
case "8 year": return 96;
127
case "9 year": return 108;
128
case "10 year": return 120;
134
* Get Product/Service Title
136
* @return string Product/Service title
138
function getTitle() { return null; }
141
* Is Billable This Term
143
* Takes two timestamps: the beginning of an invoice term and the end of an
144
* invoice term. If this purchase is billable during the period, return true.
146
* @param integer $periodBeginTS The beginning of the billing period (timestamp)
147
* @param integer $periodEndTS The end of the billing period (timestamp)
148
* @return boolean True if this purchase should be billed
150
function isBillable( $periodBeginTS, $periodEndTS )
154
$purchaseTS = $DB->datetime_to_unix( $this->getDate() );
156
if( $periodEndTS < $purchaseTS )
158
// This invoice bills before this purchases existed
161
if( $this->isNewThisTerm( $periodBeginTS, $periodEndTS ) )
163
// This purchase is new this billing term
167
if( !$this->isRecurring() )
169
// Only recurring purchases are tested beyond this point
173
// Calcuate the distance (in months) between the purchase date and the beginning
174
// (and end) of the invoice period
175
$yearDiff1 = date('y', $periodBeginTS) - date('y', $purchaseTS) ;
176
$monthDiff1 = date('m', $periodBeginTS) - date('m', $purchaseTS) + ($yearDiff * 12);
177
$monthDiff1 = $monthDiff1 < 0 ? $monthDiff1 + 12 : $monthDiff1;
179
$yearDiff2 = date('y', $periodEndTS) - date('y', $purchaseTS) ;
180
$monthDiff2 = date('m', $periodEndTS) - date('m', $purchaseTS) + ($yearDiff * 12);
181
$monthDiff2 = $monthDiff2 < 0 ? $monthDiff2 + 12 : $monthDiff2;
183
// These truths help determine if the purchases recurs during the invoice period
185
$purchasedSameMonthButBeforePeriodBegins =
186
($monthDiff1 == 0) && (date( 'j', $purchaseTS ) < date( 'j', $periodBeginTS ));
188
$recursAfterPeriodBegins =
189
(($monthDiff1 % $this->getTermMonths() == 0) &&
190
(date( 'j', $purchaseTS ) >= date( 'j', $periodBeginTS ))) ||
191
(($monthDiff1 % $this->getTermMonths() == 0 ||
192
$monthDiff2 % $this->getTermMonths() == 0 ||
193
$monthDiff1 % $this->getTermMonths() == $monthDiff1) &&
194
(date( 'j', $purchaseTS ) < date( 'j', $periodBeginTS )));
196
$recursBeforePeriodEnds =
197
(($monthDiff2 % $this->getTermMonths() == 0) &&
198
(date( 'j', $purchaseTS ) < date( 'j', $periodEndTS ))) ||
199
(($monthDiff2 % $this->getTermMonths() == 0 ||
200
$monthDiff2 % $this->getTermMonths() == 1) &&
201
(date( 'j', $purchaseTS ) >= date( 'j', $periodEndTS )));
203
// Usefull for debugging
205
echo $this->getTitle() . ": " .
206
!$purchasedSameMonthButBeforePeriodBegins . "/" .
207
$recursAfterPeriodBegins . "/" .
208
$recursBeforePeriodEnds . " monthDiff2: " . $monthDiff2 . "\n";
211
// Test if this purchase recurs during the invoice period using the truths
213
return (!$purchasedSameMonthButBeforePeriodBegins) &&
214
($recursAfterPeriodBegins && $recursBeforePeriodEnds);
218
* Is New Purchase This Term
220
* Takes two timestamps: the beginning of an invoice term and then end of an
221
* invoice term. If this purchase was made during the period, return true.
223
* @param integer $periodBeginTS The beginning of the billing period (timestamp)
224
* @param integer $periodEndTS The end of the billing period (timestamp)
225
* @return boolean True if this purchase should be billed
227
function isNewThisTerm( $periodBeginTS, $periodEndTS )
231
$purchaseTS = $DB->datetime_to_unix( $this->getDate() );
232
return ($purchaseTS >= $periodBeginTS) && ($purchaseTS < $periodEndTS);
238
* @return boolean True if this purchase is a recurring purchase
240
function isRecurring() { return $this->getTermMonths() > 0; }
245
* @return boolean True if this purchase is taxable
247
function isTaxable() { return false; }
252
* @param string $date Purchase date (MySQL datetime)
254
function setDate( $date ) { $this->date = $date; }
259
* @param string $term Purchase term ("1 year", "2 year" ... "10 year")
261
function setTerm( $term ) { $this->term = $term; }