* @copyright 2009 Deon George * @link http://osb.leenooks.net * * @link http://www.agileco.com/ * @copyright 2004-2008 Agileco, LLC. * @license http://www.agileco.com/agilebill/license1-4.txt * @author Tony Landis * @package AgileBill * @subpackage Modules:Invoice */ /** * The main AgileBill Net Term Class * * @package AgileBill * @subpackage Modules:Invoice */ class net_term extends OSB_module { var $taxable=1; # @todo (to move to net_term) are late fees taxable? 0/1 # Does this term period determine that the service should be suspended private $toSuspend = false; # Does this term period determine that the invoice should be sent private $sendInv = false; # Which notice number should be sent. private $notice = false; # Should we send the final notice private $lastNotice = false; private function getTermDetails($tid) { static $CACHE = array(); if (! isset($CACHED[$tid])) { $db = &DB(); $CACHED[$tid] = $db->Execute(sqlSelect($db,'net_term','*',sprintf('status=1 AND id=%s',$tid))); } return $CACHED[$tid]; } /** * Set the TermID of this object * From this we can work out if what interval this is * @return boolean true if this term is valid, false if not valid */ public function checkTermDetails($tid,$date,$prepaid=false) { # If date > today and prepaid, then suspend if ($prepaid && time()-$date > 0) { $this->toSuspend = true; return true; } $rs = $this->getTermDetails($tid); if ($rs && $rs->RecordCount()==1) { $terms = explode(',',$rs->fields['terms']); sort($terms); # If the date is outside the first term date, then we'll return here if (time()-$date < $terms[0]*86400) return false; $c = -1; foreach ($terms as $i => $d) { $dd = time()-$d*86400; # If this is prepaid, is this our last notice? if ($prepaid && (isset($terms[$i+1]) && (time()-$date > $terms[$i+1]*86400))) { $this->lastNotice = true; break; } # If we matched a term period, we need to exit if ($date >= $dd || ($prepaid && $d > 0)) break; $c++; } if ($this->lastNotice) return true; # If we went 1 loop only, then this must be the first match and thus an invoice needs to go out. if ($c==0) $this->sendInv = true; # If we came out with no matches, then we must be in the suspend time elseif ((! $prepaid && ($date < $dd)) || ($prepaid && $d > 0)) $this->toSuspend = true; else $this->notice = $c; return true; } return false; } /** * Return if this term deterimes that the service should be suspended. */ public function getSuspend() { return $toSuspend; } /** * Return if this term deterimes that the invoice should be generated. */ public function sendInvoice() { return $sendInv; } /** * Return the notice number */ public function getNoticeNumber() { return $this->notice; } /** * Get an array of the term dates, including invoice creation and suspension * * Optionally pass the invoice created date. */ public function getTermDates($id,$created=null,$due=null) { $td = array(); $db = &DB(); $query = $db->Execute(sqlSelect($db,'net_term','terms',sprintf('id=%s',$id))); if ($query && $query->RecordCount()) { $terms = explode(',',$query->fields['terms']); sort($terms); if (is_null($due)) $due = time(); if (! is_null($created)) array_push($td,array('date'=>$created,'desc'=>'Invoice Created')); $duedate = false; foreach ($terms as $index => $days) { if ($created && $created >= $due+$days*86400) continue; if (! $duedate && $days>0) array_push($td,array('date'=>$due-$days*86400,'desc'=>'Invoice Due')); if ($days == 0) { $desc = 'Invoice Due'; $duedate = true; } elseif ($index == 0 && ! count($td)) $desc = 'Invoice Created'; elseif ($index == count($terms)-1) $desc = 'Service Suspension'; else $desc = 'Notice'; array_push($td,array('date'=>$due+$days*86400,'desc'=>$desc)); $i++; } } return $td; } # Check usergroup&checkout plugin to determin if net terms available (get best) public function termsAllowed($account_id,$checkout_plugin_id) { $db=&DB(); $rs=&$db->Execute($sql=sqlSelect($db,"net_term","*","status=1 AND checkout_id=$checkout_plugin_id","fee ASC")); if($rs && $rs->RecordCount() > 0) { global $C_auth; while(!$rs->EOF) { $availarr = unserialize($rs->fields['group_avail']); if(is_array($availarr)) { foreach($availarr as $g) { if($C_auth->auth_group_by_account_id($account_id,$g)) return $rs->fields['id']; } } } } return 0; } # Task to generate late charges & insert into charge module: function task($VAR) { require_once(PATH_MODULES.'email_template/email_template.inc.php'); require_once(PATH_MODULES.'invoice/invoice.inc.php'); $invoice = new invoice; # get active net terms $db=&DB(); $rs=&$db->Execute($sql=sqlSelect($db,"net_term","*","status=1")); if($rs && $rs->RecordCount() > 0) { // loop through net terms while(!$rs->EOF) { $id = $rs->fields['id']; $last_interval = mktime(0,0,0,date('m'), date('d')-$rs->fields['terms'], date('Y')); $i=&$db->Execute($sql=sqlSelect($db,"invoice", "id,account_id,total_amt,billed_amt,due_date,net_term_date_last,net_term_intervals", "net_term_id = $id AND (suspend_billing = 0 OR suspend_billing IS NULL) AND (billing_status = 0 OR billing_status IS NULL) AND due_date <= $last_interval AND net_term_date_last <= $last_interval")); if($i && $i->RecordCount() > 0) { // loop through invoices while(!$i->EOF) { $terms = $rs->fields['terms']; echo "
" . $start_interval = $i->fields['net_term_date_last']; echo "
" . $stop_interval = $start_interval+(86400*$terms); echo "
". date(UNIX_DATE_FORMAT,$start_interval); // charge or suspend? if(!empty($i->fields['net_term_intervals']) && $rs->fields['suspend_intervals'] < $i->fields['net_term_intervals']) { // suspend invoice $arr['id'] = $i->fields['id']; $na =& $invoice->voidInvoice($arr,$invoice); // suspend billing status $fields=Array('suspend_billing'=>1); $db->Execute($sql=sqlUpdate($db,"invoice",$fields,"id = {$i->fields['id']}")); // send suspend e-mail if($rs->fields['enable_emails']) { $email = new email_template; $email->send('net_term_suspend', $i->fields['account_id'], $i->fields['id'], $rs->fields['suspend_intervals'], $i->fields['net_term_intervals']); } } else { // calc late fee if($rs->fields['fee_type'] == 2) $fee = $rs->fields['fee']; elseif($rs->fields['fee_type'] == 1) $fee = ($i->fields['total_amt'] - $i->fields['billed_amt']) * $rs->fields['fee']; // create late charge if($fee>0) { $fields=Array( 'date_orig'=> time(), 'status'=> 0, 'account_id'=> $i->fields['account_id'], 'amount'=> $fee, 'sweep_type'=> $rs->fields['sweep_type'], 'taxable'=> $this->taxable, 'quantity' => 1, 'attributes'=> "Name=={$rs->fields['name']}\r\nInterval==".date(UNIX_DATE_FORMAT,$start_interval)." - ".date(UNIX_DATE_FORMAT,$stop_interval), // todo: translate 'description'=> $rs->fields['sku']); $db->Execute($sql=sqlInsert($db,"charge",$fields)); // update invoice $_fields['net_term_intervals'] = $i->fields['net_term_intervals']+1; $_fields['net_term_date_last'] = $stop_interval; $db->Execute($sql=sqlUpdate($db,"invoice",$_fields,"id={$i->fields['id']}")); echo "

$sql"; } // send late fee/payment reminder e-mail: if($rs->fields['enable_emails']){ $email = new email_template; $email->send('net_term_late_notice', $i->fields['account_id'], $i->fields['id'], number_format($fee,2), number_format($rs->fields['suspend_intervals']-$i->fields['net_term_intervals'])); } } $i->MoveNext(); } } $rs->MoveNext(); } } } } ?>