2008-11-26 22:50:40 +00:00
< ? php
/**
* AgileBill - Open Billing Software
*
* This body of work is free software ; you can redistribute it and / or
* modify it under the terms of the Open AgileBill License
* License as published at http :// www . agileco . com / agilebill / license1 - 4. txt
*
* For questions , help , comments , discussion , etc . , please join the
* Agileco community forums at http :// forum . agileco . com /
*
* @ link http :// www . agileco . com /
* @ copyright 2004 - 2008 Agileco , LLC .
* @ license http :// www . agileco . com / agilebill / license1 - 4. txt
* @ author Tony Landis < tony @ agileco . com >
* @ package AgileBill
* @ version 1.4 . 93
*/
/**
* The main AgileBill Invoice Class
*/
class invoice
{
/** Enable summary invoice view that rolls multiple instances of the same sku w/identical base&setup price & attributes into one line item */
var $summarizeInvoice = true ;
/**
* Holds sku ' s of line items to exclude from invoice summarys ( pdf view only )
*
* @ var array
*/
var $summarizeInvoiceExclude ;
/** Invoice type, 0=new, 1=recurr */
var $type = 0 ;
/** Invoice Creation Timestamp */
var $date_orig ;
/** Last modification Timestamp */
var $date_last ;
/** Invoice Id */
var $record_id ;
/** Invoice Item Id */
var $item_id = 1 ;
/** Parent Invoice Id for recurring */
var $parent_id ;
/** Account Id for invoice */
var $account_id ;
/** Affiliate Id of Invoice */
var $affiliate_id ;
/** Account Billing Id */
var $account_billing_id ;
/** Campaign Id */
var $campaign_id ;
/** Reseller Id */
var $reseller_id ;
/** Billed Currency Id */
var $billed_currency_id ;
/** Actual Billed Currency selected by Client */
var $actual_billed_currency_id ;
/** Checkout Plugin Id */
var $checkout_plugin_id ;
/** Array of checkout plugin data returned by checkout plugin */
var $checkout_plugin_data ;
/** Current Notice Count */
var $notice_count = 0 ;
/** Last Notice Timestamp */
var $notice_date ;
/** Due Date Timestamp */
var $due_date ;
/** Net Term Id */
var $net_term_id = false ;
/** Net Term Last Notice/Late fee Timestamp */
var $net_term_date_last ;
/** Net Term Interval Count */
var $net_term_intervals = 0 ;
/** Process Status */
var $process_status = 0 ;
/** Billing Status */
var $billing_status = 0 ;
/** Suspend Billing Status */
var $suspend_billing = 0 ;
/** Printed Invoice Status */
var $print_status = 0 ;
/** Refunded Invoice Status */
var $refund_status = 0 ;
/** Calcuate Taxes */
var $tax = true ;
/** Calculate Discounts */
var $discount = true ;
/** Total Invoice Amount */
var $total_amt = 0 ;
/** Total Amount Billed */
var $billed_amt = 0 ;
/** Actual total amount billed (converted to local) */
var $actual_billed_amt = 0 ;
/** Total Tax Amount */
var $tax_amt = 0 ;
/** Total Discount Amount */
var $discount_amt = 0 ;
/** Recurring Amount */
var $recur_amt ;
/** Recurring Array for Later Processing */
var $recur_arr ;
/** IP Address of User */
var $ip = USER_IP ;
/** Array of the Invoice items */
var $invoice_item ;
/** Array of the discounts for the Invoice items */
var $item_discount ;
/** Array of the taxes for the Invoice Items */
var $item_tax ;
/** Tracking to determine payment options */
var $any_new = false ;
var $any_trial = false ;
var $any_recurring = false ;
/** Invoice Config Global Options */
var $invoice_delivery = 1 ;
var $invoice_format = 0 ;
var $notice_max = MAX_BILLING_NOTICE ;
var $grace_period = GRACE_PERIOD ;
/**
* Get the global level invoice settings
*/
function setupGlobal () {
$db =& DB ();
$invopt = $db -> Execute ( sqlSelect ( $db , " setup_invoice " , " * " , " " ));
if ( $invopt && $invopt -> RecordCount ()) {
$this -> invoice_delivery = $invopt -> fields [ 'invoice_delivery' ];
$this -> invoice_format = $invopt -> fields [ 'invoice_show_itemized' ];
}
}
/**
* Get the account level invoice options
*
* @ param int $id Account Id
*/
function setupAccount () {
if ( ! $this -> account_id ) return ;
$db =& DB ();
$acctrs = $db -> Execute ( sqlSelect ( $db , " account " , " invoice_grace,invoice_advance_gen " , " id= $this->account_id " ));
if ( $acctrs && $acctrs -> RecordCount ()) {
$this -> advance_gen = $acctrs -> fields [ 'invoice_advance_gen' ];
if ( $this -> grace_period == GRACE_PERIOD && ! empty ( $acctrs -> fields [ 'invoice_grace' ])) $this -> grace_period = $acctrs -> fields [ 'invoice_grace' ];
}
}
/**
* Initialize new invoice creation
*
* @ param bool $type 0 = new 1 = recur
*/
function initNew ( $type = 0 ) {
$this -> type = $type ;
$this -> date_orig = time ();
$this -> date_last = time ();
global $C_list ;
$this -> net_term = $C_list -> is_installed ( 'net_term' );
// get account invoice defaults
$this -> setupAccount ();
}
/**
* Commit the current invoice / items / discounts / taxes
*
* @ param object $taxObj Object for Tax Calculation
* @ param object $discountObj Object for Discount Calculation
* @ param bool $email Send customer / admin e - mails
*/
function commitNew ( & $taxObj , & $discountObj , $email = true ) {
// init DB transaction
$db =& DB ();
$db -> BeginTrans ();
// get invoice id
if ( empty ( $this -> record_id )) $this -> record_id = sqlGenID ( $db , " invoice " );
// serialized records:
if ( is_array ( $this -> checkout_plugin_data )) $this -> checkout_plugin_data = serialize ( $this -> checkout_plugin_data );
if ( is_array ( $this -> recur_arr )) $this -> recur_arr = serialize ( $this -> recur_arr );
// dates & defaults
if ( empty ( $this -> due_date )) $this -> due_date = time ();
if ( empty ( $this -> date_orig )) $this -> date_orig = time ();
if ( empty ( $this -> date_last )) $this -> date_last = time ();
if ( empty ( $this -> notice_next_date )) $this -> notice_next_date = $this -> due_date + 86400 ;
// net terms
if ( $this -> net_term && ! $this -> billing_status && $this -> total_amt > 0 ) {
include_once ( PATH_MODULES . 'net_term/net_term.inc.php' );
$net = new net_term ;
$this -> net_term_id = $net -> termsAllowed ( $this -> account_id , $this -> checkout_plugin_id );
if ( empty ( $this -> net_term_date_last )) $this -> net_term_date_last = time ();
}
// insert invoice
$fields = Array (
'date_orig' => $this -> date_orig ,
'date_last' => $this -> date_last ,
'parent_id' => $this -> parent_id ,
'type' => $this -> type ,
'process_status' => $this -> process_status ,
'billing_status' => $this -> billing_status ,
'suspend_billing' => $this -> suspend_billing ,
'refund_status' => $this -> refund_status ,
'print_status' => $this -> print_status ,
'account_id' => $this -> account_id ,
'account_billing_id' => $this -> account_billing_id ,
'affiliate_id' => $this -> affiliate_id ,
'campaign_id' => $this -> campaign_id ,
'reseller_id' => $this -> reseller_id ,
'checkout_plugin_id' => $this -> checkout_plugin_id ,
'checkout_plugin_data' => $this -> checkout_plugin_data ,
'tax_amt' => $this -> tax_amt ,
'discount_amt' => $this -> discount_amt ,
'total_amt' => $this -> total_amt ,
'billed_amt' => $this -> billed_amt ,
'recur_amt' => $this -> recur_amt ,
'recur_arr' => $this -> recur_arr ,
'actual_billed_amt' => $this -> actual_billed_amt ,
'billed_currency_id' => $this -> billed_currency_id ,
'actual_billed_currency_id' => $this -> actual_billed_currency_id ,
'notice_count' => $this -> notice_count ,
'notice_max' => $this -> notice_max ,
'notice_next_date' => $this -> notice_next_date ,
'due_date' => $this -> due_date ,
'grace_period' => $this -> grace_period ,
'net_term_id' => $this -> net_term_id ,
'net_term_date_last' => $this -> net_term_date_last ,
'net_term_intervals' => $this -> net_term_intervals ,
'ip' => $this -> ip
);
$db -> Execute ( $sql = sqlInsert ( $db , " invoice " , $fields , $this -> record_id ));
// loop through invoice items
if ( is_array ( $this -> invoice_item )) {
foreach ( $this -> invoice_item as $id => $fields ) {
// get an invoice_item id
$invoice_item_id = sqlGenID ( $db , " invoice_item " );
// domain sku's
if ( $fields [ 'item_type' ] == 2 ) {
$fields [ 'sku' ] = " DOMAIN- " . strtoupper ( $fields [ 'domain_type' ]);
$fields [ 'price_type' ] = '0' ;
}
// build e-mail item details
if ( $email ) {
$email_instructions = '' ;
if ( $fields [ 'item_type' ] < 2 && ! empty ( $fields [ 'product_id' ])) {
// product, get email instructions and translated name
$translate_prod = $db -> Execute ( sqlSelect ( $db , " product_translate " , " email_template,name " , " product_id= { $fields [ 'product_id' ] } and language_id=:: " . SESS_LANGUAGE . " :: " ));
if ( $translate_prod && $translate_prod -> RecordCount ()) {
$instructions = $translate_prod -> fields [ 'email_template' ];
$name = $translate_prod -> fields [ 'name' ];
} else {
$name = $fields [ " sku " ];
}
} elseif ( $fields [ 'item_type' ] == 2 ) {
$name = strtoupper ( $fields [ 'domain_name' ] . " . " . $fields [ 'domain_tld' ]);
} else {
if ( ! empty ( $fields [ 'product_name' ])) $name = $fields [ 'product_name' ]; else $name = $fields [ 'sku' ];
}
// add to e-mail array
$email_arr [] = array ( 'Qty' => '(' . $fields [ " quantity " ] . ')' , 'Item' => 'SKU ' . $fields [ " sku " ], 'Price' => number_format ( $fields [ " total_amt " ], 2 ), 'Name' => $name , 'Instructions' => $instructions );
}
// insert the invoice item_id
$fields [ 'invoice_id' ] = $this -> record_id ;
$fields [ 'date_orig' ] = time ();
$attr = serialize ( $fields [ 'product_attr' ]);
$fields [ 'product_attr' ] = $fields [ 'product_attr_cart' ];
$fields [ 'product_attr_cart' ] = $attr ;
$db -> Execute ( $sql = sqlInsert ( $db , " invoice_item " , $fields , $invoice_item_id ));
// insert taxes
if ( $this -> tax && $this -> tax_amt > 0 && ! empty ( $this -> tax_arr [ $id ])) {
$taxObj -> invoice_item ( $this -> record_id , $invoice_item_id , $this -> account_id , $this -> tax_arr [ $id ]);
}
// insert discounts
if ( $this -> discount && $this -> discount_amt > 0 && ! empty ( $this -> discount_arr [ $id ])) {
$discountObj -> invoice_item ( $this -> record_id , $invoice_item_id , $this -> account_id , $this -> discount_arr [ $id ]);
}
}
}
// complete DB transaction
$db -> CompleteTrans ();
// complete building e-mail notices and send
if ( $email ) {
include_once ( PATH_MODULES . 'email_template/email_template.inc.php' );
// Create the products order list for the e-mail:
$e_itm_usr = '' ;
$e_itm_adm = '' ;
if ( is_array ( $email_arr )) {
foreach ( $email_arr as $i => $em ) {
$e_itm_usr .= $em [ 'Qty' ] . ' ' . $em [ 'Item' ] . ' (' . $em [ 'Name' ] . ') ' . $em [ 'Price' ];
$e_itm_adm .= $em [ 'Qty' ] . ' ' . $em [ 'Item' ] . ' (' . $em [ 'Name' ] . ') ' . $em [ 'Price' ] . " \r \n " ;
if ( ! empty ( $email_arr [ $i ][ 'Instructions' ])) $e_itm_usr .= " \r \n * " . $email_item_arr [ $i ][ 'Instructions' ];
$e_itm_usr .= " \r \n " ;
}
$e_arr_user = Array ( '%products%' => $e_itm_usr );
$e_arr_adm = Array ( '%products%' => $e_itm_adm );
}
// e-mail invoice creation confirmation
$mail = new email_template ;
$mail -> send ( 'invoice_confirm_user' , $this -> account_id , $this -> record_id , $this -> checkout_plugin_id , $e_arr_user );
$email = new email_template ;
$email -> send ( 'admin->invoice_confirm_admin' , $this -> account_id , $this -> record_id , $this -> checkout_plugin_id , $e_arr_adm );
}
// net terms?
if ( $this -> net_term_id ) {
$this -> approveInvoice ( array ( 'id' => $this -> record_id ), $this );
return $this -> record_id ;
}
// Determine the approval status by checkout plugin type & settings:
if ( $email && $this -> billing_status == 0 && $this -> billed_amt > 0 ) {
global $C_list ;
if ( $this -> checkout_type == 'redirect' ) {
// User e-mail alert of due invoice
$email = new email_template ;
$email -> send ( 'invoice_due_user' , $this -> account_id , $this -> record_id , $user_currency , $C_list -> date ( $this -> due_date ));
} elseif ( $this -> checkout_type == 'other' ) {
// Admin e-mail alert of manual payment processing
$email = new email_template ;
$email -> send ( 'admin->invoice_due_admin' , $this -> account_id , $this -> record_id , $admin_currency , $C_list -> date ( $this -> due_date ));
}
} elseif ( $this -> billed_amt > 0 ) {
if ( $email ) {
// User alert of payment processed
$email = new email_template ;
$email -> send ( 'invoice_paid_user' , $this -> account_id , $this -> record_id , $this -> billed_currency_id , '' );
// Admin alert of payment processed
$email = new email_template ;
$email -> send ( 'admin->invoice_paid_admin' , $this -> account_id , $this -> record_id , $this -> billed_currency_id , '' );
}
$this -> autoApproveInvoice ( $this -> record_id );
} elseif ( $this -> billed_amt == 0 && $this -> billing_status == 1 ) {
$this -> autoApproveInvoice ( $this -> record_id );
}
// return invoice id
return $this -> record_id ;
}
/**
* Add an invoice item
*
* @ param int $id Reference ID for use in Cart or false
* @ param object $taxObj Object for Tax Calculation
* @ param object $discountObj Object for Discount Calculation
* @ param int $item_type 0 / 1 = Product / Service / Hosting 2 = Domain 3 = Add Hoc
* @ param string $taxable True , False , or 'validate' to locate the specified $product id and verify
* @ param int $service_id If this is for a service upgrade , this will be defined
* @ param int $parent_id Item Parent Id
* @ param int $product_id Item Product Id
* @ param array $product_attr Item attributes from the cart / prev service
* @ param string $product_name Item product name
* @ param string $sku Item Product SKU
* @ param int $quantity Item Quantity
* @ param float $price_base Item Base price
* @ param float $price_setup Item Setup Price
* @ param float $discount_manual Ad Hoc Discount Amount
* @ param int $recurring_schedule Item recurring schedule , 0 = week , 1 = month , 2 = quarter , 3 = semi - annual , 4 = annual , 5 = bi - year
* @ param int $date_start Date service started
* @ param int $date_stop Date service stops
* @ param string $domain_name Domain name
* @ param string $domain_tld Domain TLD
* @ param int $domain_term Domain Term
* @ param string $domain_type Domain Type ( register , transfer , renew , park , ns_transfer )
*/
function addItem ( $id , & $taxObj , & $discountObj , $item_type , $taxable = false , $service_id = false , $parent_id = false , $product_id = false , $product_attr = false , $product_name = false , $sku = false , $quantity = 1 , $price_base = false , $price_setup = false , $discount_manual = false , $recurring_schedule = false , $date_start = false , $date_stop = false , $domain_name = false , $domain_tld = false , $domain_term = false , $domain_type = false ) {
$tax_amt = 0 ;
$total_amt = 0 ;
$discount_amt = 0 ;
// define correct qty
if ( $quantity <= 0 ) $quantity = 1 ;
// determine the reference id for this item
if ( $id > 0 ) {
$this -> item_id = $id ;
} else {
$this -> item_id ++ ;
}
// get the product details
if ( $product_id && $item_type < 2 ) {
$db =& DB ();
$product = $db -> Execute ( sqlSelect ( $db , " product " , " * " , " id= $product_id " ));
if ( $product && $product -> RecordCount ()) {
$taxable = $product -> fields [ 'taxable' ];
$this -> product [ " $this->item_id " ] = $product -> fields ;
}
// get the tld details
} elseif ( $item_type == 2 ) {
$db =& DB ();
$tld = $db -> Execute ( sqlSelect ( $db , " host_tld " , " * " , " name=:: $domain_tld :: " ));
if ( $tld && $tld -> RecordCount ())
$taxable = $tld -> fields [ 'taxable' ];
}
// get the product pricing details if product
$price_type = 0 ;
if ( $price_base === false && $price_setup === false && $product_id && $item_type < 2 ) {
if ( $product && $product -> RecordCount ()) {
$price_type = $product -> fields [ 'price_type' ];
$sku = $product -> fields [ 'sku' ];
include_once ( PATH_MODULES . 'product/product.inc.php' );
$productObj = new product ;
// get pricing for this product:
$prod_price = $productObj -> price_prod ( $product -> fields , $recurring_schedule , $this -> account_id );
$price_base = $prod_price [ " base " ];
$price_setup = $prod_price [ " setup " ];
// calculate any product attributes fees
$attr_price = $productObj -> price_attr ( $product -> fields , $product_attr , $recurring_schedule , $this -> account_id );
$price_base += $attr_price [ " base " ];
$price_setup += $attr_price [ " setup " ];
// determine price type for checkout
if ( $product -> fields [ " price_type " ] == '0' )
$this -> any_new = true ;
else if ( $product -> fields [ " price_type " ] == '1' )
$this -> any_recurring = true ;
else if ( $product -> fields [ " price_type " ] == '2' )
$this -> any_trial = true ;
} else {
$this -> any_new = true ;
}
} else {
$this -> any_new = true ;
}
// get the TLD pricing details if domain
if ( $price_base === false && $price_setup === false && $domain_tld && $domain_term && $domain_type ) {
include_once ( PATH_MODULES . 'host_tld/host_tld.inc.php' );
$tldObj = new host_tld ;
$tldprice = $tldObj -> price_tld_arr ( $domain_tld , $domain_type , false , false , false , $this -> account_id );
if ( $domain_type == " park " ) {
$price_base = $tldprice ;
} else {
$price_base = $tldprice [ " $domain_term " ];
$this -> tld_arr [ " $this->item_id " ] = $tldprice ;
}
}
// set total amount for this line item before attributes, taxes, or discounts
$price_base *= $quantity ;
$price_setup *= $quantity ;
$total_amt = ( $price_setup + $price_base );
// format product attributes for storage
$product_attr_cart = false ;
if (( $item_type == 0 || $item_type > 2 ) && is_array ( $product_attr )) $product_attr_cart = $this -> get_product_attr_cart ( $product_attr );
// recurring taxes and arrays
if ( $price_base > 0 && $price_type == 1 )
{
// increment the total invoice recurring amount
$this -> recur_amt += $price_base ;
// determine taxes for the recurring amount
if ( $this -> tax && $taxable && $price_base > 0 && $this -> account_id ) {
$recur_tax_arr = $taxObj -> calculate ( $price_base , $this -> country_id , $this -> state );
if ( is_array ( $recur_tax_arr )) foreach ( $recur_tax_arr as $tx ) $this -> recur_amt += $tx [ 'rate' ];
}
// get the recurring arrays for price and invoice
if ( $product && $product -> RecordCount ()) {
$this -> price_arr [ " $this->item_id " ] = $productObj -> price_recurr_arr ( $product -> fields , $this -> account_id );
$this -> recur_arr [] = Array (
'price' => $price_base * $quantity ,
'recurr_schedule' => $recurring_schedule ,
'recurr_type' => $product -> fields [ 'price_recurr_type' ],
'recurr_weekday' => $product -> fields [ 'price_recurr_weekday' ],
'recurr_week' => $product -> fields [ 'price_recurr_week' ]
);
}
}
// calculate any ad-hoc line item level (admin) discounts
if ( $this -> discount && $discount_manual > 0 ) {
$total_amt -= $discount_manual ;
$discount_amt += $discount_manual ;
$this -> discount_amt += $discount_amt ;
$discountObj -> add_manual_discount ( $discount_manual , 'MISC' , $this -> item_id );
}
// account level discounts
if ( $this -> discount && $this -> account_id ) {
// calculate any database level discounts for this item (both account specific and session specific)
$discount_amt = $discountObj -> calc_all_discounts ( 0 , $this -> item_id , $product_id , $total_amt , $this -> account_id , $this -> total_amt + $total_amt );
$total_amt -= $discount_amt ;
$this -> discount_amt += $discount_amt ;
}
// add to total discount array
if ( is_array ( $discountObj -> discount_arr )) {
$this -> discount_arr [ " $this->item_id " ] = $discountObj -> discount_arr ;
}
// increment invoice total amount
$this -> total_amt += $total_amt ;
// calculate any taxes for current item
if ( $this -> tax && $taxable && $total_amt > 0 && $this -> account_id ) {
$tax_arr = $taxObj -> calculate ( $total_amt , $this -> country_id , $this -> state );
if ( is_array ( $tax_arr )) {
foreach ( $tax_arr as $tx ) $tax_amt += $tx [ 'rate' ];
$this -> item_tax [ " $this->item_id " ] = $tax_arr ;
$this -> tax_arr [ " $this->item_id " ] = $tax_arr ;
}
$this -> tax_amt += $tax_amt ;
$this -> total_amt += $tax_amt ;
}
// store the fields to an array
$this -> invoice_item [ " $this->item_id " ] = Array (
'item_type' => $item_type ,
'price_type' => $price_type ,
'taxable' => $taxable ,
'service_id' => $service_id ,
'parent_id' => $parent_id ,
'product_id' => $product_id ,
'product_attr' => $product_attr ,
'product_attr_cart' => $product_attr_cart ,
'product_name' => $product_name ,
'sku' => $sku ,
'quantity' => $quantity ,
'price_base' => $price_base ,
'price_setup' => $price_setup ,
'recurring_schedule' => $recurring_schedule ,
'date_start' => $date_start ,
'date_stop' => $date_stop ,
'domain_name' => $domain_name ,
'domain_tld' => $domain_tld ,
'domain_term' => $domain_term ,
'domain_type' => $domain_type ,
'total_amt' => $total_amt ,
'tax_amt' => $tax_amt ,
'discount_amt' => $discount_amt
);
}
/**
* Group all taxes to lump sums
*/
function group_taxes () {
if ( is_array ( $this -> tax_arr )) {
foreach ( $this -> tax_arr as $taxarr ) foreach ( $taxarr as $taxes ) $arr [ $taxes [ " name " ]] += $taxes [ " rate " ];
if ( is_array ( $arr )) {
foreach ( $arr as $a => $b ) $ret [] = Array ( 'name' => $a , 'rate' => $b );
return $ret ;
}
}
}
/**
* Group all discounts to lump sums
*/
function group_discounts () {
if ( is_array ( $this -> discount_arr )) {
foreach ( $this -> discount_arr as $discarr ) foreach ( $discarr as $discounts ) $arr [ $discounts [ " discount " ]] += $discounts [ " amount " ];
if ( is_array ( $arr )) {
foreach ( $arr as $a => $b ) $ret [] = Array ( 'name' => $a , 'total' => $b );
return $ret ;
}
}
}
/**
* Build a formatted product attribute list
*
* @ param array $attributes
* @ return string Formatted product attribute list
*/
function get_product_attr_cart ( $attributes ) {
# Set the attribute array:
if ( ! empty ( $attributes ) && is_array ( $attributes )) {
$db =& DB ();
$product_attr = false ;
foreach ( $attributes as $id => $value ) {
if ( ! empty ( $value )) {
if ( is_numeric ( $id )) {
$attr = $db -> Execute ( sqlSelect ( $db , " product_attr " , " name " , " id= $id " ));
if ( $attr && $attr -> RecordCount ()) $product_attr .= " { $attr -> fields [ 'name' ] } == " . ereg_replace ( " \r \n " , " <br> " , $value ) . " \r \n " ;
} else {
$product_attr .= " { $id } == { $value } \r \n " ;
}
}
}
}
return $product_attr ;
}
/** Custom Tracking
*/
function custom_tracking ( $VAR )
{
# Get the invoice id
if ( SESS_LOGGED == false )
return false ;
# Check if we are in the iframe
if ( empty ( $VAR [ '_escape' ]) || empty ( $VAR [ 'confirm' ]))
{
echo '<iframe id="custom_ecom_track" style="border:0px; width:0px; height:0px;"scrolling="auto" ' .
'frameborder="0" SRC="?_page=core:blank&_escape=1&confirm=1&do[]=invoice:custom_tracking&rand=' . md5 ( microtime ()) . '"></iframe>' ;
return ;
}
# Get the un-tracked invoice details
$db = & DB ();
$sql = " SELECT * FROM " . AGILE_DB_PREFIX . " invoice WHERE
( custom_affiliate_status IS NULL OR
custom_affiliate_status = 0 )
AND billing_status = " . $db->qstr (1). "
AND site_id = " . $db->qstr (DEFAULT_SITE). "
AND account_id = " . $db->qstr (SESS_ACCOUNT);
$result = $db -> Execute ( $sql );
if ( $result === false ) {
global $C_debug ;
$C_debug -> error ( '' , '' , $db -> ErrorMsg () . " \r \n \r \n " . $sql );
return false ;
}
if ( $result -> RecordCount () == 0 ) {
echo 'none' ;
return false ;
}
# Get the totals
$invoice = '' ;
$total_amount = false ;
while ( ! $result -> EOF )
{
if ( ! empty ( $invoice ))
$invoice .= '-' ;
$invoice .= $result -> fields [ 'id' ];
$amt = $result -> fields [ " total_amt " ];
$total_amount += $amt ;
$result -> MoveNext ();
}
# echo the custom tracking code to the screen:
if ( ! is_file ( PATH_FILES . 'tracking.txt' )) return false ;
$tracking = file_get_contents ( PATH_FILES . 'tracking.txt' );
$tracking = ereg_replace ( '%%amount%%' , " $total_amount " , $tracking );
$tracking = ereg_replace ( '%%invoice%%' , $invoice , $tracking );
$tracking = ereg_replace ( '%%affiliate%%' , SESS_AFFILIATE , $tracking );
$tracking = ereg_replace ( '%%campaign%%' , SESS_CAMPAIGN , $tracking );
$tracking = ereg_replace ( '%%account%%' , SESS_ACCOUNT , $tracking );
echo $tracking ;
# Update the record so it is not tracked again
$sql = " UPDATE " . AGILE_DB_PREFIX . " invoice
SET
c ustom_affiliate_status = " . $db->qstr ('1'). "
WHERE
account_id = " . $db->qstr (SESS_ACCOUNT). "
AND
billing_status = " . $db->qstr (1). "
AND
site_id = " . $db->qstr (DEFAULT_SITE);
$rs = $db -> Execute ( $sql );
if ( $rs === false ) {
global $C_debug ;
$C_debug -> error ( '' , '' , $db -> ErrorMsg () . " \r \n \r \n " . $sql );
}
return true ;
}
/** Performance : ( for the admin dashboard )
*/
function performance ( $VAR )
{
global $smarty , $C_list , $C_translate ;
# Get the period type, default to month
if ( empty ( $VAR [ 'period' ]))
$p = 'm' ;
else
$p = $VAR [ 'period' ];
# Determine the correct period language:
if ( $p == '' or $p == 'm' )
{
$pTrans = $C_translate -> translate ( 'thismonth' , 'invoice' , '' ) . ' ' .
$C_translate -> translate ( 'vs' , 'invoice' , '' ) . ' ' .
$C_translate -> translate ( 'lastmonth' , 'invoice' , '' );
$pFore = $C_translate -> translate ( 'thismonth' , 'invoice' , '' );
}
elseif ( $p == 'w' )
{
$pTrans = $C_translate -> translate ( 'thisweek' , 'invoice' , '' ) . ' ' .
$C_translate -> translate ( 'vs' , 'invoice' , '' ) . ' ' .
$C_translate -> translate ( 'lastweek' , 'invoice' , '' );
$pFore = $C_translate -> translate ( 'thisweek' , 'invoice' , '' );
}
elseif ( $p == 'y' )
{
$pTrans = $C_translate -> translate ( 'thisyear' , 'invoice' , '' ) . ' ' .
$C_translate -> translate ( 'vs' , 'invoice' , '' ) . ' ' .
$C_translate -> translate ( 'lastyear' , 'invoice' , '' );
$pFore = $C_translate -> translate ( 'thisyear' , 'invoice' , '' );
}
$smarty -> assign ( 'period_compare' , $pTrans );
$smarty -> assign ( 'period_forcast' , $pFore );
# Get the period start & end
switch ( $p ) {
case 'w' :
$dow = date ( 'w' );
$this_start = mktime ( 0 , 0 , 0 , date ( 'm' ), date ( 'd' ) - $dow , date ( 'y' ));
$this_end = mktime ( 23 , 59 , 59 , date ( 'm' ), date ( 'd' ), date ( 'y' ));
$last_start = mktime ( 0 , 0 , 0 , date ( 'm' ), date ( 'd' , $this_start ) - 7 , date ( 'y' ));
$last_end = $this_start - 1 ;
break ;
case 'm' :
$this_start = mktime ( 0 , 0 , 0 , date ( 'm' ), 1 , date ( 'y' ));
$this_end = mktime ( 23 , 59 , 59 , date ( 'm' ), date ( 'd' ), date ( 'y' ));
$last_start = mktime ( 0 , 0 , 0 , date ( 'm' , $this_start ) - 1 , 1 , date ( 'y' ));
$last_end = $this_start - 1 ;
break ;
case 'y' :
$this_start = mktime ( 0 , 0 , 0 , 1 , 1 , date ( 'y' , time ()));
$this_end = mktime ( 23 , 59 , 59 , date ( 'm' ), date ( 'd' ), date ( 'y' ));
$last_start = mktime ( 0 , 0 , 0 , 1 , 1 , date ( 'y' , $this_start ) - 1 );
$last_end = $this_start - 1 ;
break ;
}
##############################
# Get sales for this period
##############################
$db = & DB ();
$this_amt = 0 ;
$sql = 'SELECT total_amt FROM ' . AGILE_DB_PREFIX . ' invoice WHERE
date_orig >= ' . $db->qstr( $this_start ) . ' AND
date_orig <= ' . $db->qstr( $this_end ) . ' AND
site_id = ' . $db -> qstr ( DEFAULT_SITE );
$rs = $db -> Execute ( $sql );
while ( ! $rs -> EOF ) {
$this_amt += $rs -> fields [ 'total_amt' ];
$rs -> MoveNext ();
}
$smarty -> assign ( 'sales_current' , $this_amt );
###############################
# Get sales for last period
###############################
$last_amt = 0 ;
$sql = 'SELECT total_amt FROM ' . AGILE_DB_PREFIX . ' invoice WHERE
date_orig >= ' . $db->qstr( $last_start ) . ' AND
date_orig <= ' . $db->qstr( $last_end ) . ' AND
site_id = ' . $db -> qstr ( DEFAULT_SITE );
$rs = $db -> Execute ( $sql );
while ( ! $rs -> EOF ) {
$last_amt += $rs -> fields [ 'total_amt' ];
$rs -> MoveNext ();
}
$smarty -> assign ( 'sales_previous' , $last_amt );
###############################
# Get sales change percentage
###############################
if ( $last_amt > 0 )
$sales_change = $this_amt / $last_amt * 100 - 100 ;
else
$sales_change = 0 ;
if ( $sales_change == 0 )
$sales_change = '' ;
elseif ( $sales_change < 0 )
$sales_change = '<font color="#990000">' . number_format ( $sales_change , 1 ) . '%</font>' ;
else
$sales_change = '+' . number_format ( $sales_change , 1 ) . '%' ;
$smarty -> assign ( 'sales_change' , $sales_change );
#################################
# Get forcast for current period
#################################
switch ( $p ) {
case 'w' :
$dow = date ( 'w' ) + 1 ;
$forcast_daily = $this_amt / $dow ;
$forcast_l_daily = $last_amt / 7 ;
@ $forcast_change = $forcast_daily / $forcast_1_daily * 100 - 100 ;
$forcast_current = $forcast_daily * 7 ;
break ;
case 'm' :
$forcast_daily = $this_amt / date ( 'd' );
$forcast_1_daily = $last_amt / date ( 't' , mktime ( 0 , 0 , 0 , date ( 'm' ) - 1 , 1 , date ( 'y' )));
@ $forcast_change = $forcast_daily / $forcast_1_daily * 100 - 100 ;
$forcast_current = $forcast_daily * date ( 't' );
break ;
case 'y' :
$forcast_daily = $this_amt / date ( 'z' );
$forcast_1_daily = $last_amt / 356 ;
@ $forcast_change = $forcast_daily / $forcast_1_daily * 100 - 100 ;
$forcast_current = $forcast_daily * 365 ;
break ;
}
$smarty -> assign ( 'forcast_current' , $forcast_current );
###############################
# Get forcast change percentage
###############################
if ( $last_amt > 0 )
@ $forcast_change = $forcast_daily / $forcast_1_daily * 100 ;
else
$forcast_change = 0 ;
if ( $forcast_change == 0 )
$forcast_change = '-' ;
elseif ( $forcast_change < 0 )
$forcast_change = '<font color="#990000">' . number_format ( $forcast_change , 1 ) . '%</font>' ;
else
$forcast_change = '+' . number_format ( $forcast_change , 1 ) . '%' ;
$smarty -> assign ( 'forcast_change' , $forcast_change );
####################################################
# Get Quota for Today to meet Forcasted sales:
####################################################
$smarty -> assign ( 'quota_current' , $forcast_daily );
##############################
# Get AR credits for this period
##############################
$this_billed_amt = 0 ;
$sql = 'SELECT billed_amt FROM ' . AGILE_DB_PREFIX . ' invoice WHERE
date_orig >= ' . $db->qstr( $this_start ) . ' AND
date_orig <= ' . $db->qstr( $this_end ) . ' AND
billed_amt > ' . $db->qstr( 0 ) . ' AND
site_id = ' . $db -> qstr ( DEFAULT_SITE );
$rs = $db -> Execute ( $sql );
while ( ! $rs -> EOF ) {
$this_billed_amt += $rs -> fields [ 'billed_amt' ];
$rs -> MoveNext ();
}
$smarty -> assign ( 'ar_credits_current' , $this_billed_amt );
###############################
# Get AR credits for last period
###############################
$last_billed_amt = 0 ;
$sql = 'SELECT billed_amt FROM ' . AGILE_DB_PREFIX . ' invoice WHERE
date_orig >= ' . $db->qstr( $last_start ) . ' AND
date_orig <= ' . $db->qstr( $last_end ) . ' AND
billed_amt > ' . $db->qstr( 0 ) . ' AND
site_id = ' . $db -> qstr ( DEFAULT_SITE );
$rs = $db -> Execute ( $sql );
while ( ! $rs -> EOF ) {
$last_billed_amt += $rs -> fields [ 'billed_amt' ];
$rs -> MoveNext ();
}
$smarty -> assign ( 'ar_credits_previous' , $last_billed_amt );
###############################
# Get AR Credits change percentage
###############################
if ( $last_billed_amt > 0 )
$ar_change = $this_billed_amt / $last_billed_amt * 100 - 100 ;
else
$ar_change = 0 ;
if ( $ar_change == 0 )
$ar_change = '-' ;
elseif ( $ar_change < 0 )
$ar_change = '<font color="#990000">' . number_format ( $ar_change , 1 ) . '%</font>' ;
else
$ar_change = '+' . number_format ( $ar_change , 1 ) . '%' ;
$smarty -> assign ( 'ar_credit_change' , $ar_change );
##########################################
# Get AR Balance
##########################################
$this_ar_balance = $this_billed_amt - $this_amt ;
$last_ar_balance = $last_billed_amt - $last_amt ;
$smarty -> assign ( 'ar_balance_current' , $this_ar_balance );
$smarty -> assign ( 'ar_balance_last' , $last_ar_balance );
#########################################
# Get Users (current)
#########################################
$sql = 'SELECT id FROM ' . AGILE_DB_PREFIX . ' account WHERE
date_orig >= ' . $db->qstr( $this_start ) . ' AND
date_orig <= ' . $db->qstr( $this_end ) . ' AND
site_id = ' . $db -> qstr ( DEFAULT_SITE );
$rs = $db -> Execute ( $sql );
$users_current = $rs -> RecordCount ();
$smarty -> assign ( 'users_current' , $users_current );
#########################################
# Get Users (previous)
#########################################
$sql = 'SELECT id FROM ' . AGILE_DB_PREFIX . ' account WHERE
date_orig >= ' . $db->qstr( $last_start ) . ' AND
date_orig <= ' . $db->qstr( $last_end ) . ' AND
site_id = ' . $db -> qstr ( DEFAULT_SITE );
$rs = $db -> Execute ( $sql );
$users_previous = $rs -> RecordCount ();
$smarty -> assign ( 'users_previous' , $users_previous );
###############################
# Get users change percentage
###############################
if ( $users_previous > 0 )
@ $users_change = $users_current / $users_current * 100 - 100 ;
else
$users_change = 0 ;
if ( $users_change == 0 )
$users_change = '-' ;
elseif ( $users_change < 0 )
$users_change = '<font color="#990000">' . number_format ( $users_change , 1 ) . '%</font>' ;
else
$users_change = '+' . number_format ( $users_change , 1 ) . '%' ;
$smarty -> assign ( 'users_change' , $users_change );
# Get Tickets
if ( $C_list -> is_installed ( 'ticket' ) )
{
$smarty -> assign ( 'show_tickets' , true );
#########################################
# Get Tickets (current)
#########################################
$sql = 'SELECT id FROM ' . AGILE_DB_PREFIX . ' ticket WHERE
date_orig >= ' . $db->qstr( $this_start ) . ' AND
date_orig <= ' . $db->qstr( $this_end ) . ' AND
site_id = ' . $db -> qstr ( DEFAULT_SITE );
$rs = $db -> Execute ( $sql );
$tickets_current = $rs -> RecordCount ();
$smarty -> assign ( 'tickets_current' , $tickets_current );
#########################################
# Get Tickets (previous)
#########################################
$sql = 'SELECT id FROM ' . AGILE_DB_PREFIX . ' ticket WHERE
date_orig >= ' . $db->qstr( $last_start ) . ' AND
date_orig <= ' . $db->qstr( $last_end ) . ' AND
site_id = ' . $db -> qstr ( DEFAULT_SITE );
$rs = $db -> Execute ( $sql );
$tickets_previous = $rs -> RecordCount ();
$smarty -> assign ( 'tickets_previous' , $tickets_previous );
###############################
# Get Tickets change percentage
###############################
if ( $tickets_previous > 0 )
@ $tickets_change = $tickets_current / $tickets_current * 100 - 100 ;
else
$tickets_change = 0 ;
if ( $tickets_change == 0 )
$tickets_change = '-' ;
elseif ( $tickets_change < 0 )
$tickets_change = '<font color="#990000">' . number_format ( $tickets_change , 1 ) . '%</font>' ;
else
$tickets_change = '+' . number_format ( $tickets_change , 1 ) . '%' ;
$smarty -> assign ( 'tickets_change' , $tickets_change );
}
# Get Affiliate stats
if ( $C_list -> is_installed ( 'affiliate' ) )
{
$smarty -> assign ( 'show_affiliates' , true );
###########################################
# Get affiliate sales for this period
###########################################
$this_amt = 0 ;
$sql = 'SELECT total_amt FROM ' . AGILE_DB_PREFIX . ' invoice WHERE
date_orig >= ' . $db->qstr( $this_start ) . ' AND
date_orig <= ' . $db->qstr( $this_end ) . ' AND
affiliate_id != ' . $db->qstr( 0 ) . ' AND
affiliate_id != ' . $db->qstr( ' ' ) . ' AND
site_id = ' . $db -> qstr ( DEFAULT_SITE );
$rs = $db -> Execute ( $sql );
while ( ! $rs -> EOF ) {
$this_amt += $rs -> fields [ 'total_amt' ];
$rs -> MoveNext ();
}
$smarty -> assign ( 'affiliate_sales_current' , $this_amt );
##########################################
# Get affiliate sales for last period
##########################################
$last_amt = 0 ;
$sql = 'SELECT total_amt FROM ' . AGILE_DB_PREFIX . ' invoice WHERE
date_orig >= ' . $db->qstr( $last_start ) . ' AND
date_orig <= ' . $db->qstr( $last_end ) . ' AND
affiliate_id != ' . $db->qstr( 0 ) . ' AND
affiliate_id != ' . $db->qstr( ' ' ) . ' AND
site_id = ' . $db -> qstr ( DEFAULT_SITE );
$rs = $db -> Execute ( $sql );
while ( ! $rs -> EOF ) {
$last_amt += $rs -> fields [ 'total_amt' ];
$rs -> MoveNext ();
}
$smarty -> assign ( 'affiliate_sales_previous' , $last_amt );
###########################################
# Get affiliate sales change percentage
###########################################
if ( $last_amt > 0 )
$sales_change = $this_amt / $last_amt * 100 - 100 ;
else
$sales_change = 0 ;
if ( $sales_change == 0 )
$sales_change = '-' ;
elseif ( $sales_change < 0 )
$sales_change = '<font color="#990000">' . number_format ( $sales_change , 1 ) . '%</font>' ;
else
$sales_change = '+' . number_format ( $sales_change , 1 ) . '%' ;
$smarty -> assign ( 'affiliate_sales_change' , $sales_change );
}
/** Get VoIP Performance Data
*/
if ( $C_list -> is_installed ( 'voip' ) )
{
# Avg. Call Duration for this period
$rs = $db -> Execute ( sqlSelect ( $db , " voip_cdr " , " avg(ceiling(billsec/60)) " , " disposition='ANSWERED' AND date_orig >= $this_start AND date_orig <= $this_end " ));
if ( empty ( $rs -> fields [ 0 ])) $acd = 0 ; else $acd = $rs -> fields [ 0 ];
$smarty -> assign ( 'acd' , $acd );
# Avg. Call Duration for last period
$rs = $db -> Execute ( sqlSelect ( $db , " voip_cdr " , " avg(ceiling(billsec/60)) " , " disposition='ANSWERED' AND date_orig >= $last_start AND date_orig <= $last_end " ));
if ( empty ( $rs -> fields [ 0 ])) $acd_last = 0 ; else $acd_last = $rs -> fields [ 0 ];
$smarty -> assign ( 'acd_last' , $acd_last );
# Get Avg. Call Duration change Percentage
if ( $acd > 0 ) $acd_change = $acd / $acd_last * 100 - 100 ; else $acd_change = 0 ;
if ( $acd_change == 0 )
$acd_change = '-' ;
elseif ( $acd_change < 0 )
$acd_change = '<font color="#990000">' . number_format ( $acd_change , 1 ) . '%</font>' ;
else
$acd_change = '+' . number_format ( $acd_change , 1 ) . '%' ;
$smarty -> assign ( 'acd_change' , $acd_change );
# Avg. Successful Rate for this period
$rs = $db -> Execute ( sqlSelect ( $db , " voip_cdr " , " count(*) " , " disposition='ANSWERED' AND date_orig >= $this_start AND date_orig <= $this_end " ));
$rs1 = $db -> Execute ( sqlSelect ( $db , " voip_cdr " , " count(*) " , " date_orig >= $this_start AND date_orig <= $this_end " ));
if ( $rs -> fields [ 0 ])
$asr = number_format (( $rs -> fields [ 0 ] / $rs1 -> fields [ 0 ]) * 100 , 3 ) . " % " ;
else
$asr = " - " ;
$smarty -> assign ( 'asr' , $asr );
# Number of CDRs for this period
$cdrs = $rs1 -> fields [ 0 ];
$smarty -> assign ( 'cdrs' , number_format ( $cdrs , 0 ));
# Avg. Successful Rate for last period
$rs = $db -> Execute ( sqlSelect ( $db , " voip_cdr " , " count(*) " , " disposition='ANSWERED' AND date_orig >= $last_start AND date_orig <= $last_end " ));
$rs1 = $db -> Execute ( sqlSelect ( $db , " voip_cdr " , " count(*) " , " date_orig >= $last_start AND date_orig <= $last_end " ));
if ( $rs -> fields [ 0 ])
$asr_last = number_format (( $rs -> fields [ 0 ] / $rs1 -> fields [ 0 ]) * 100 , 3 ) . " % " ;
else
$asr_last = " - " ;
$smarty -> assign ( 'asr_last' , $asr_last );
# Number of CDRS for last period
$cdrs_last = $rs1 -> fields [ 0 ];
$smarty -> assign ( 'cdrs_last' , number_format ( $cdrs_last , 0 ));
# Get Avg. Successful Rate change Percentage
if ( $asr > 0 ) $asr_change = $asr / $asr_last * 100 - 100 ; else $asr_change = 0 ;
if ( $asr_change == 0 )
$asr_change = '-' ;
elseif ( $asr_change < 0 )
$asr_change = '<font color="#990000">' . number_format ( $asr_change , 1 ) . '%</font>' ;
else
$asr_change = '+' . number_format ( $asr_change , 1 ) . '%' ;
$smarty -> assign ( 'asr_change' , $asr_change );
# Get Number of CDRs change Percentage
if ( $cdrs > 0 ) $cdrs_change = $cdrs / $cdrs_last * 100 - 100 ; else $cdrs_change = 0 ;
if ( $cdrs_change == 0 )
$cdrs_change = '-' ;
elseif ( $cdrs_change < 0 )
$cdrs_change = '<font color="#990000">' . number_format ( $cdrs_change , 1 ) . '%</font>' ;
else
$cdrs_change = '+' . number_format ( $cdrs_change , 1 ) . '%' ;
$smarty -> assign ( 'cdrs_change' , $cdrs_change );
}
# Generate the Calendar Overview
include_once ( PATH_MODULES . 'core/calendar.inc.php' );
$calendar = new calendar ;
$start = $calendar -> start ;
$end = $calendar -> end ;
global $C_list ;
$C_list -> currency ( DEFAULT_CURRENCY );
$currency_symbol = $C_list -> format_currency [ DEFAULT_CURRENCY ][ 'symbol' ];
# Get the paid/due invoice statistics
$rs = $db -> Execute ( $sql = sqlSelect ( $db , " invoice " , " date_orig,total_amt,billing_status,refund_status,billed_amt,suspend_billing " , " date_orig >= $start && date_orig <= $end " ));
if ( $rs && $rs -> RecordCount ()) {
while ( ! $rs -> EOF ) {
$day = date ( " j " , $rs -> fields [ 'date_orig' ]);
if ( $rs -> fields [ 'billed_amt' ] > 0 && ( $rs -> fields [ 'billing_status' ] == 1 || $rs -> fields [ 'refund_status' ] != 1 )) {
$paid [ $day ] += $rs -> fields [ 'billed_amt' ];
}
if ( $rs -> fields [ 'billing_status' ] != 1 && $rs -> fields [ 'refund_status' ] != 1 ) {
$amt = $rs -> fields [ 'total_amt' ] - $rs -> fields [ 'billed_amt' ];
$due [ $day ] += $amt ;
}
$rs -> MoveNext ();
}
if ( is_array ( $paid ))
foreach ( $paid as $day => $item )
$calendar -> add ( " <b>Paid</b> - { $currency_symbol } " . number_format ( $item , 2 ), $day , 'green' , 'green' );
if ( is_array ( $due ))
foreach ( $due as $day => $item )
$calendar -> add ( " <b>Due</b> - { $currency_symbol } " . number_format ( $item , 2 ), $day , 'red' , 'red' );
}
# Get the upcoming due services
$rs = $db -> Execute ( $sql = sqlSelect ( $db , " service " , " date_next_invoice,price " , " price > 0 AND date_next_invoice >= $start AND date_next_invoice <= $end AND suspend_billing <> 1 " ));
if ( $rs && $rs -> RecordCount ()) {
while ( ! $rs -> EOF ) {
$day = date ( " j " , $rs -> fields [ 'date_next_invoice' ]);
$sdue [ $day ] += $rs -> fields [ 'price' ];
$rs -> MoveNext ();
}
foreach ( $sdue as $day => $item ) {
$calendar -> add ( " <b>Recurring</b> - { $currency_symbol } " . number_format ( $item , 2 ), $day , 'grey' , 'grey' );
}
}
$calout = $calendar -> generate ();
$smarty -> assign ( " calendar " , $calout );
return ;
}
/** AUTO APPROVE INVOICE
*/
function autoApproveInvoice ( $invoice_id )
{
$do = false ;
# Get the invoice details:
$db = & DB ();
$q = " SELECT * FROM " . AGILE_DB_PREFIX . " invoice WHERE
id = " . $db->qstr ( $invoice_id ). " AND
site_id = " . $db->qstr (DEFAULT_SITE);
$invoice = $db -> Execute ( $q );
if ( $invoice === false ) {
global $C_debug ;
$C_debug -> error ( 'invoice.inc.php' , 'autoApproveInvoice' , $db -> ErrorMsg ());
return false ;
}
# Get the checkout details:
$q = " SELECT * FROM " . AGILE_DB_PREFIX . " checkout WHERE
id = " . $db->qstr ( $invoice->fields ['checkout_plugin_id']). " AND
site_id = " . $db->qstr (DEFAULT_SITE);
$checkout = $db -> Execute ( $q );
if ( $checkout === false ) {
global $C_debug ;
$C_debug -> error ( 'invoice.inc.php' , 'autoApproveInvoice' , $db -> ErrorMsg ());
return false ;
}
# Get the account details:
$q = " SELECT * FROM " . AGILE_DB_PREFIX . " account WHERE
id = " . $db->qstr ( $invoice->fields ['account_id']). " AND
site_id = " . $db->qstr (DEFAULT_SITE);
$account = $db -> Execute ( $q );
if ( $account === false ) {
global $C_debug ;
$C_debug -> error ( 'invoice.inc.php' , 'autoApproveInvoice' , $db -> ErrorMsg ());
return false ;
}
# is this a recurring invoices, and is manual approvale req?
if ( $invoice -> fields [ 'type' ] == 1 && $checkout -> fields [ 'manual_approval_recur' ] != 1 ) {
$do = true ;
}
# Manual approval required for all?
if ( $invoice -> fields [ 'type' ] != 1 && $checkout -> fields [ 'manual_approval_all' ] != 1 ) {
$do = true ;
}
if ( ! $do ) {
# manual approval req. for invoice amount?
if ( ! empty ( $checkout -> fields [ 'manual_approval_amount' ]) && $do == true )
if ( $checkout -> fields [ 'manual_approval_amount' ] <= $invoice -> fields [ 'total_amt' ])
$do = false ;
# manual approval req. for user's country?
if ( ! empty ( $checkout -> fields [ 'manual_approval_country' ]) && $do == true ) {
$arr = unserialize ( $checkout -> fields [ 'manual_approval_country' ]);
for ( $i = 0 ; $i < count ( $arr ); $i ++ ) {
if ( $account -> fields [ 'country_id' ] == $arr [ $i ])
$do = false ;
}
}
# manual approval req. for user's currency?
if ( ! empty ( $checkout -> fields [ 'manual_approval_currency' ]) && $do == true ) {
$arr = unserialize ( $checkout -> fields [ 'manual_approval_currency' ]);
for ( $i = 0 ; $i < count ( $arr ); $i ++ ) {
if ( $invoice -> fields [ 'actual_billed_currency_id' ] == $arr [ $i ])
$do = false ;
}
}
# manual approval req. for user's group(s)?
if ( ! empty ( $checkout -> fields [ 'manual_approval_group' ]) && $do == true ) {
# Get the group details:
$q = " SELECT group_id FROM " . AGILE_DB_PREFIX . " account_group WHERE
account_id = " . $db->qstr ( $invoice->fields ['account_id']). " AND
active = " . $db->qstr ('1'). " AND
site_id = " . $db->qstr (DEFAULT_SITE);
$groups = $db -> Execute ( $q );
if ( $groups === false ) {
global $C_debug ;
$C_debug -> error ( 'invoice.inc.php' , 'autoApproveInvoice' , $db -> ErrorMsg ());
}
$arr = unserialize ( $checkout -> fields [ 'manual_approval_group' ]);
while ( ! $groups -> EOF ) {
for ( $i = 0 ; $i < count ( $arr ); $i ++ ) {
$idx = $groups -> fields [ " group_id " ];
if ( $idx == $arr [ $i ])
$do = false ;
}
$groups -> MoveNext ();
}
}
}
if ( $do )
{
# Approve the invoice
$arr [ 'id' ] = $invoice_id ;
$this -> approveInvoice ( $arr , $this );
}
else
{
# Admin manual approval notice
include_once ( PATH_MODULES . 'email_template/email_template.inc.php' );
$mail = new email_template ;
$mail -> send ( 'invoice_manual_auth_admin' , $invoice -> fields [ 'account_id' ], $invoice -> fields [ 'id' ], $invoice -> fields [ 'checkout_plugin_id' ], '' );
}
}
/* APPROVE INVOICE
*/
function approveInvoice ( $VAR )
{
# Get the invoice details:
$db = & DB ();
$q = " SELECT * FROM " . AGILE_DB_PREFIX . " invoice WHERE
id = " . $db->qstr ( $VAR['id'] ). " AND
site_id = " . $db->qstr (DEFAULT_SITE);
$invoice = $db -> Execute ( $q );
if ( $invoice === false ) {
global $C_debug ;
$C_debug -> error ( 'invoice.inc.php' , 'approveInvoice' , $db -> ErrorMsg ());
return false ;
}
# Validate invoice exists & needs approval:
if ( $invoice -> fields [ 'id' ] != $VAR [ 'id' ] || $invoice -> fields [ 'process_status' ] == '1' ) return false ;
# Update the invoice approval status:
$q = " UPDATE " . AGILE_DB_PREFIX . " invoice SET
date_last = " . $db->qstr (time()). " ,
process_status = " . $db->qstr ('1'). " WHERE
id = " . $db->qstr ( $VAR['id'] ). " AND
site_id = " . $db->qstr (DEFAULT_SITE);
$result = $db -> Execute ( $q );
if ( $result === false ) {
global $C_debug ;
$C_debug -> error ( 'invoice.inc.php' , 'approveInvoice' , $db -> ErrorMsg ());
return false ;
}
# Send approval notice to user:
include_once ( PATH_MODULES . 'email_template/email_template.inc.php' );
$mail = new email_template ;
$mail -> send ( 'invoice_approved_user' , $invoice -> fields [ 'account_id' ], $VAR [ 'id' ], '' , '' );
# Include the service class
include_once ( PATH_MODULES . 'service/service.inc.php' );
$srvc = new service ;
# Determine if services have already been created for this invoice:
if ( $invoice -> fields [ 'type' ] != 1 )
{
$q = " SELECT id FROM " . AGILE_DB_PREFIX . " service WHERE
invoice_id = " . $db->qstr ( $VAR['id'] ). " AND
site_id = " . $db->qstr (DEFAULT_SITE);
$service = $db -> Execute ( $q );
if ( $service === false ) {
global $C_debug ;
$C_debug -> error ( 'invoice.inc.php' , 'approveInvoice' , $db -> ErrorMsg ());
return false ;
}
if ( $service -> RecordCount () > 0 )
{
# Update services to approved status:
while ( ! $service -> EOF )
{
$srvc -> approveService ( $service -> fields [ 'id' ]);
$service -> MoveNext ();
}
return true ;
}
# Get the parent items in this invoice :
$q = " SELECT * FROM " . AGILE_DB_PREFIX . " invoice_item WHERE
( parent_id = 0 OR parent_id IS NULL OR parent_id = '' ) AND
invoice_id = " . $db->qstr ( $VAR['id'] ). " AND
site_id = " . $db->qstr (DEFAULT_SITE);
$ii = $db -> Execute ( $q );
if ( $ii === false ) {
global $C_debug ;
$C_debug -> error ( 'invoice.inc.php' , 'approveInvoice' , $db -> ErrorMsg ());
return false ;
}
while ( ! $ii -> EOF )
{
if ( empty ( $ii -> fields [ 'service_id' ]))
{
# Add the service
$srvc -> invoiceItemToService ( $ii -> fields [ 'id' ], $invoice );
# Check for any children items in this invoice:
$q = " SELECT * FROM " . AGILE_DB_PREFIX . " invoice_item WHERE
parent_id = " . $db->qstr ( $ii->fields ['id']). " AND
invoice_id = " . $db->qstr ( $VAR['id'] ). " AND
site_id = " . $db->qstr (DEFAULT_SITE);
$iii = $db -> Execute ( $q );
if ( $iii === false ) {
global $C_debug ;
$C_debug -> error ( 'invoice.inc.php' , 'approveInvoice' , $db -> ErrorMsg ());
return false ;
}
while ( ! $iii -> EOF )
{
# Add the service
$srvc -> invoiceItemToService ( $ii -> fields [ 'id' ], $invoice );
$iii -> MoveNext ();
}
}
else
{
$srvc = new service ;
if ( $ii -> fields [ 'item_type' ] == 2 && $ii -> fields [ 'domain_type' ] == 'renew' ) {
# this is a domain renewal
$srvc -> renewDomain ( $ii , $invoice -> fields [ 'account_billing_id' ] );
} else {
# this is an upgrade for an existing service
$srvc -> modifyService ( $ii , $invoice -> fields [ 'account_billing_id' ] );
}
}
$ii -> MoveNext ();
}
}
elseif ( $invoice -> fields [ 'type' ] == 1 )
{
# recurring invoice, just update assoc services
# Loop through invoice items & approve assoc services
$q = " SELECT service_id FROM " . AGILE_DB_PREFIX . " invoice_item WHERE
invoice_id = " . $db->qstr ( $VAR['id'] ). " AND
site_id = " . $db->qstr (DEFAULT_SITE);
$service = $db -> Execute ( $q );
if ( $service === false ) {
global $C_debug ;
$C_debug -> error ( 'invoice.inc.php' , 'voidInvoice' , $db -> ErrorMsg ());
return false ;
}
if ( $service -> RecordCount () > 0 )
{
# Include the service class
include_once ( PATH_MODULES . 'service/service.inc.php' );
$srvc = new service ;
# Update services to inactive status:
while ( ! $service -> EOF ) {
$srvc -> approveService ( $service -> fields [ 'service_id' ]);
$service -> MoveNext ();
}
}
}
# get account id
if ( defined ( " SESS_ACCOUNT " ))
$account_id = SESS_ACCOUNT ;
else
$account_id = 0 ;
# if approved, create a memo
$id = $db -> GenID ( AGILE_DB_PREFIX . 'invoice_memo_id' );
$q = " INSERT INTO " . AGILE_DB_PREFIX . " invoice_memo
SET
id = " . $db->qstr ( $id ). " ,
site_id = " . $db->qstr (DEFAULT_SITE). " ,
date_orig = " . $db->qstr (time()). " ,
invoice_id = " . $db->qstr ( $VAR['id'] ). " ,
account_id = " . $db->qstr ( $account_id ). " ,
type = " . $db->qstr ('approval'). " ,
memo = " . $db->qstr ('NA');
$memo = $db -> Execute ( $q );
if ( $memo === false ) {
global $C_debug ;
$C_debug -> error ( 'invoice.inc.php' , 'approveInvoice' , $db -> ErrorMsg ());
return false ;
}
return true ;
}
/** VOID INVOICE
*/
function voidInvoice ( $VAR )
{
# Update the invoice approval status:
$db = & DB ();
$q = " UPDATE " . AGILE_DB_PREFIX . " invoice SET
date_last = " . $db->qstr (time()). " ,
process_status = " . $db->qstr ('0'). " WHERE
id = " . $db->qstr ( $VAR['id'] ). " AND
site_id = " . $db->qstr (DEFAULT_SITE);
$update = $db -> Execute ( $q );
if ( $update === false ) {
global $C_debug ;
$C_debug -> error ( 'invoice.inc.php' , 'voidInvoice' , $db -> ErrorMsg ());
return false ;
}
# Determine if services have already been created for this invoice and deactivate:
$q = " SELECT id FROM " . AGILE_DB_PREFIX . " service WHERE
invoice_id = " . $db->qstr ( $VAR['id'] ). " AND
site_id = " . $db->qstr (DEFAULT_SITE);
$service = $db -> Execute ( $q );
if ( $service === false ) {
global $C_debug ;
$C_debug -> error ( 'invoice.inc.php' , 'voidInvoice' , $db -> ErrorMsg ());
return false ;
}
if ( $service -> RecordCount () > 0 )
{
# Include the service class
include_once ( PATH_MODULES . 'service/service.inc.php' );
$srvc = new service ;
# Update services to inactive status:
while ( ! $service -> EOF ) {
$srvc -> voidService ( $service -> fields [ 'id' ]);
$service -> MoveNext ();
}
}
# Loop through invoice items & delete assoc services
$q = " SELECT service_id FROM " . AGILE_DB_PREFIX . " invoice_item WHERE
invoice_id = " . $db->qstr ( $VAR['id'] ). " AND
site_id = " . $db->qstr (DEFAULT_SITE);
$service = $db -> Execute ( $q );
if ( $service === false ) {
global $C_debug ;
$C_debug -> error ( 'invoice.inc.php' , 'voidInvoice' , $db -> ErrorMsg ());
return false ;
}
if ( $service -> RecordCount () > 0 )
{
# Include the service class
include_once ( PATH_MODULES . 'service/service.inc.php' );
$srvc = new service ;
# Update services to inactive status:
while ( ! $service -> EOF ) {
$srvc -> voidService ( $service -> fields [ 'service_id' ]);
$service -> MoveNext ();
}
}
# if voided, create a memo
$id = $db -> GenID ( AGILE_DB_PREFIX . 'invoice_memo_id' );
$q = " INSERT INTO " . AGILE_DB_PREFIX . " invoice_memo
SET
id = " . $db->qstr ( $id ). " ,
site_id = " . $db->qstr (DEFAULT_SITE). " ,
date_orig = " . $db->qstr (time()). " ,
invoice_id = " . $db->qstr ( $VAR['id'] ). " ,
account_id = " . $db->qstr (SESS_ACCOUNT). " ,
type = " . $db->qstr ('void'). " ,
memo = " . $db->qstr ('NA');
$insert = $db -> Execute ( $q );
if ( $insert === false ) {
global $C_debug ;
$C_debug -> error ( 'invoice.inc.php' , 'voidInvoice' , $db -> ErrorMsg ());
return false ;
}
return true ;
}
/** RECONCILE INVOICE
*/
function reconcile ( $VAR )
{
global $C_translate , $C_debug ;
# validate amt
if ( $VAR [ 'amount' ] <= 0 ) {
$C_debug -> alert ( " Payment amount to low! " );
return false ;
}
# get the invoice details
$db = & DB ();
$sql = 'SELECT * FROM ' . AGILE_DB_PREFIX . ' invoice WHERE
id = ' . $db->qstr( $VAR[' id '] ) . ' AND
site_id = ' . $db -> qstr ( DEFAULT_SITE );
$rs = $db -> Execute ( $sql );
if ( $rs === false ) {
global $C_debug ;
$C_debug -> error ( 'invoice.inc.php' , 'reconcileInvoice' , $db -> ErrorMsg ());
return false ;
}
if ( @ $rs -> RecordCount () == 0 ) return false ;
$amt = $VAR [ 'amount' ];
$total_amt = $rs -> fields [ 'total_amt' ];
$billed_amt = $rs -> fields [ 'billed_amt' ];
$billed_currency_id = $rs -> fields [ 'billed_currency_id' ];
$actual_billed_amt = $rs -> fields [ 'actual_billed_amt' ];
$actual_billed_currency_id = $rs -> fields [ 'actual_billed_currency_id' ];
$due = $total_amt - $billed_amt ;
$overpaid = false ;
if ( $amt > $due )
{
$billed = 1 ;
$update = $total_amt ;
$overpaid = $amt - $due ;
$C_translate -> value [ 'invoice' ][ 'amt' ] = number_format ( $overpaid , 2 );
$alert = $C_translate -> translate ( 'rec_over' , 'invoice' , '' );
}
elseif ( $amt == $due )
{
$billed = 1 ;
$update = $total_amt ;
}
else
{
$billed = 0 ;
$update = $amt + $billed_amt ;
}
# Update the invoice record
$sql = 'UPDATE ' . AGILE_DB_PREFIX . ' invoice
SET
billed_amt = ' . $db->qstr( $update ) . ' ,
billing_status = ' . $db->qstr( $billed ) . '
WHERE
id = ' . $db->qstr( $VAR[' id '] ) . ' AND
site_id = ' . $db -> qstr ( DEFAULT_SITE );
$db -> Execute ( $sql );
# Create a memo
$id = $db -> GenID ( AGILE_DB_PREFIX . 'invoice_memo_id' );
$q = " INSERT INTO " . AGILE_DB_PREFIX . " invoice_memo
SET
id = " . $db->qstr ( $id ). " ,
site_id = " . $db->qstr (DEFAULT_SITE). " ,
date_orig = " . $db->qstr (time()). " ,
invoice_id = " . $db->qstr ( $VAR['id'] ). " ,
account_id = " . $db->qstr (SESS_ACCOUNT). " ,
type = " . $db->qstr ('reconcile'). " ,
memo = " . $db->qstr ('+ '.number_format( $VAR['amount'] ,2) . " \r\n " . @ $VAR['memo'] );
$db -> Execute ( $q );
# Reciept printing
include_once PATH_MODULES . 'invoice/receipt_print.php' ;
$receipt = new receipt_print ;
$receipt -> add ( $rs , number_format ( $VAR [ 'amount' ], 2 ), number_format ( $update , 2 ));
# Auto update if billed complete
if ( $billed )
{
$this -> autoApproveInvoice ( $VAR [ 'id' ]);
# Get the default currency ISO
$q = " SELECT " . AGILE_DB_PREFIX . " invoice_memo
SET
id = " . $db->qstr ( $id ). " ,
site_id = " . $db->qstr (DEFAULT_SITE). " ,
date_orig = " . $db->qstr (time()). " ,
invoice_id = " . $db->qstr ( $VAR['id'] ). " ,
account_id = " . $db->qstr (SESS_ACCOUNT). " ,
type = " . $db->qstr ('reconcile'). " ,
memo = " . $db->qstr ('+ '.number_format( $VAR['amount'] ,2) . " \r\n " . @ $VAR['memo'] );
$currency = $db -> Execute ( $q );
# User invoice creation confirmation
include_once ( PATH_MODULES . 'email_template/email_template.inc.php' );
$email = new email_template ;
$email -> send ( 'invoice_paid_user' , $rs -> fields [ 'account_id' ], $VAR [ 'id' ], $rs -> fields [ 'billed_currency_id' ], '' );
# Admin alert of payment processed
$email = new email_template ;
$email -> send ( 'admin->invoice_paid_admin' , $rs -> fields [ 'account_id' ], $VAR [ 'id' ], $rs -> fields [ 'billed_currency_id' ], '' );
}
# Redirect
if ( ! empty ( $VAR [ 'redirect' ]))
{
echo '
< script language = " JavaScript " >
window . parent . location = \ '' . $VAR [ 'redirect' ] . '\'; ' ;
if ( ! empty ( $alert ))
echo 'alert(\'' . $alert . '\');' ;
echo '</script>' ;
exit ;
}
$msg = $C_translate -> translate ( 'ref_comp' , 'invoice' , '' );
$C_debug -> alert ( $msg );
return ;
}
/** REFUND INVOICE
*/
function refund ( $VAR )
{
global $C_translate , $C_debug ;
# validate amt
if ( $VAR [ 'amount' ] <= 0 ) {
$C_debug -> alert ( " Refund amount to low! " );
return false ;
}
# get the invoice details
$db = & DB ();
$sql = 'SELECT * FROM ' . AGILE_DB_PREFIX . ' invoice WHERE
id = ' . $db->qstr( $VAR[' id '] ) . ' AND
site_id = ' . $db -> qstr ( DEFAULT_SITE );
$rs = $db -> Execute ( $sql );
if ( @ $rs -> RecordCount () == 0 ) return false ;
$amt = $VAR [ 'amount' ];
$total_amt = $rs -> fields [ 'total_amt' ];
$billed_amt = $rs -> fields [ 'billed_amt' ];
$billed_currency_id = $rs -> fields [ 'billed_currency_id' ];
$actual_billed_amt = $rs -> fields [ 'actual_billed_amt' ];
$actual_billed_currency_id = $rs -> fields [ 'actual_billed_currency_id' ];
$update = $billed_amt - $amt ;
if ( $update > 0 ) $billing_status = 1 ; else $billing_status = 0 ;
# Update the invoice record
echo $sql = 'UPDATE ' . AGILE_DB_PREFIX . ' invoice
SET
billed_amt = ' . $db->qstr( $update ) . ' ,
billing_status = '.$billing_status.' ,
suspend_billing = 1 ,
refund_status = 1
WHERE
id = ' . $db->qstr( $VAR[' id '] ) . ' AND
site_id = ' . $db -> qstr ( DEFAULT_SITE );
$update2 = $db -> Execute ( $sql );
if ( $update2 === false ) {
global $C_debug ;
$C_debug -> error ( 'invoice.inc.php' , 'refundInvoice' , $db -> ErrorMsg ());
return false ;
}
# Create a memo
$id = $db -> GenID ( AGILE_DB_PREFIX . 'invoice_memo_id' );
$q = " INSERT INTO " . AGILE_DB_PREFIX . " invoice_memo
SET
id = " . $db->qstr ( $id ). " ,
site_id = " . $db->qstr (DEFAULT_SITE). " ,
date_orig = " . $db->qstr (time()). " ,
invoice_id = " . $db->qstr ( $VAR['id'] ). " ,
account_id = " . $db->qstr (SESS_ACCOUNT). " ,
type = " . $db->qstr ('refund'). " ,
memo = " . $db->qstr ('- '.number_format( $VAR['amount'] ,2) . " \r\n " . @ $VAR['memo'] );
$insert = $db -> Execute ( $q );
if ( $insert === false ) {
global $C_debug ;
$C_debug -> error ( 'invoice.inc.php' , 'refundInvoice' , $db -> ErrorMsg ());
return false ;
}
# Void:
$this -> voidInvoice ( $VAR , $this );
# Call into the checkout plugin and attempt realtime refund
$billing = $db -> Execute ( $sql = sqlSelect ( $db , array ( 'account_billing' , 'checkout' ), 'A.*,B.checkout_plugin' ,
" A.id = :: { $rs -> fields [ 'account_billing_id' ] } :: AND A.checkout_plugin_id=B.id " ));
if ( $billing && $billing -> RecordCount () && ! empty ( $billing -> fields [ 'checkout_plugin' ])) {
$plugin_file = PATH_PLUGINS . 'checkout/' . $billing -> fields [ 'checkout_plugin' ] . '.php' ;
if ( is_file ( $plugin_file )) {
include_once ( $plugin_file );
eval ( '$PLG = new plg_chout_' . $billing -> fields [ 'checkout_plugin' ] . '("' . $billing -> fields [ 'checkout_plugin_id' ] . '");' );
if ( is_callable ( Array ( $PLG , " refund " ))) $PLG -> refund ( $rs -> fields , $billing -> fields , $amt );
}
}
# Redirect
if ( ! empty ( $VAR [ 'redirect' ])) {
echo ' <script language="JavaScript"> window.parent.location=\'' . $VAR [ 'redirect' ] . '\'; </script>' ;
return ;
}
$msg = $C_translate -> translate ( 'ref_comp' , 'invoice' , '' );
$C_debug -> alert ( $msg );
return ;
}
# Get translated/hardcoded line item description for PDF invoice
function getLineItemDesc ( $sku , $id , $domain = false , $item_name )
{
if ( ! empty ( $item_name )) return $item_name ;
global $C_translate ;
if ( ! empty ( $sku ) && $sku == 'DOMAIN-PARK' || $sku == 'DOMAIN-TRANSFER' || $sku == 'DOMAIN-REGISTER' || $sku == 'DOMAIN-RENEW' ) {
if ( $sku == 'DOMAIN-REGISTER' ) $name = $C_translate -> translate ( 'register' , 'cart' , '' );
elseif ( $sku == 'DOMAIN-TRANSFER' ) $name = $C_translate -> translate ( 'transfer' , 'cart' , '' );
elseif ( $sku == 'DOMAIN-PARK' ) $name = $C_translate -> translate ( 'park' , 'cart' , '' );
elseif ( $sku == 'DOMAIN-RENEW' ) $name = $C_translate -> translate ( 'renew' , 'cart' , '' );
if ( $domain ) return " $domain \r \n ( $name ) " ;
else return $name ;
} else {
include_once ( PATH_CORE . 'list.inc.php' );
$C_list = new CORE_list ;
if ( empty ( $this -> product_desc [ " $id " ])) {
$desc = $C_list -> translate ( " product_translate " , " name " , " product_id " , $id , " translate_product " );
$this -> product_desc [ " $id " ] = $desc [ 'name' ];
}
if ( ! empty ( $this -> product_desc [ " $id " ]))
return $this -> product_desc [ " $id " ];
else
return $sku ;
}
return $sku ;
}
/**
* Task based function to e - mail or store printable PDF of all unprinted invoices
*/
function delivery_task ()
{
# get all unprinted invoices
$db =& DB ();
$invcfg = $db -> Execute ( sqlSelect ( $db , " setup_invoice " , " * " , " id=:: " . DEFAULT_SITE . " :: " ));
$rs = $db -> SelectLimit ( $sql = sqlSelect ( $db , Array ( " invoice " , " account " ),
" A.id,B.email,B.first_name,B.last_name,B.invoice_delivery,B.invoice_show_itemized " ,
" (A.billing_status=0 OR A.billing_status IS NULL) AND (A.print_status=0 OR A.print_status=NULL) and A.account_id=B.id and (B.invoice_delivery is not null AND B.invoice_delivery>0) " ), 100 );
if ( $rs && $rs -> RecordCount ())
{
//define('FPDF_FONTPATH', PATH_INCLUDES.'pdf/font/');
require_once ( PATH_INCLUDES . 'pdf/fpdi.php' );
require_once ( PATH_INCLUDES . 'pdf/fpdf_tpl.php' );
require_once ( PATH_INCLUDES . 'pdf/fpdf.php' );
require_once ( PATH_INCLUDES . 'pdf/pdf_invoice_' . $invcfg -> fields [ 'invoice_pdf_plugin' ] . '.inc.php' );
// Send the e-mail....
require_once ( PATH_INCLUDES . " phpmailer/class.phpmailer.php " );
$mail = new PHPMailer ();
$mail -> From = SITE_EMAIL ;
$mail -> FromName = SITE_NAME ;
/*
$mail -> SMTPAuth = true ;
$mail -> Host = " smtp.domain.com " ;
$mail -> Username = " user " ;
$mail -> Password = " pass " ;
$mail -> Mailer = " smtp " ;
$mail -> Debug = true ;
*/
while ( ! $rs -> EOF )
{
$pdf = new pdf_invoice_overview ();
$pdf -> companyName = SITE_NAME ;
$pdf -> companyAddress = SITE_ADDRESS ;
$pdf -> companyCity = SITE_CITY ;
$pdf -> companyState = SITE_STATE ;
$pdf -> companyZip = SITE_ZIP ;
# load the setup_invoice fields into the pdf class
$pdf -> load_setup ( $invcfg );
$pagecount = $pdf -> setSourceFile ( $pdf -> getTemplate ());
$tplidx = $pdf -> ImportPage ( 1 );
$pdf -> addPage ();
$pdf -> useTemplate ( $tplidx );
# override the show itemized, based on the customers choice
if ( $rs -> fields [ 'invoice_show_itemized' ] == 0 || $rs -> fields [ 'invoice_show_itemized' ] == 1 )
$pdf -> show_itemized = $rs -> fields [ 'invoice_show_itemized' ];
$this -> pdfInvoiceSummary ( $rs -> fields [ 'id' ], $pdf );
$file = tempnam ( PATH_FILES , " pdf_inv_ " . $rs -> fields [ 'id' ]) . " .pdf " ;
$pdf -> Output ( $file , 'F' );
$pdf -> closeParsers ();
if ( $rs -> fields [ 'invoice_delivery' ] == 1 ) {
$mail -> AddAddress ( $rs -> fields [ 'email' ], $rs -> fields [ 'first_name' ] . ' ' . $rs -> fields [ 'last_name' ]);
$mail -> Subject = " Printable Invoice No. " . $rs -> fields [ 'id' ];
$mail -> Body = " Please find the printable version of invoice number { $rs -> fields [ 'id' ] } attached. \r \n \r \n Thank you, \r \n " . SITE_NAME ;
$mail -> AddAttachment ( $file , " INVOICE_ { $rs -> fields [ 'id' ] } .pdf " );
if ( $mail -> Send ()) {
$fields = Array ( 'print_status' => 1 );
$db -> Execute ( sqlUpdate ( $db , " invoice " , $fields , " id= " . $rs -> fields [ 'id' ]));
} else {
echo " Unable to email invoice # { $rs -> fields [ 'id' ] } to { $rs -> fields [ 'email' ] } <BR> " ;
}
$mail -> ClearAddresses ();
$mail -> ClearAttachments ();
} else if ( $rs -> fields [ 'invoice_delivery' ] == 2 ) {
if ( copy ( $file , AGILE_PDF_INVOICE_PATH . " invoice_ " . $rs -> fields [ 'id' ] . " .pdf " )) {
$fields = Array ( 'print_status' => 1 );
$db -> Execute ( sqlUpdate ( $db , " invoice " , $fields , " id= " . $rs -> fields [ 'id' ]));
}
}
// delete tmp file and clean up vars used
unlink ( $file );
unset ( $pdf -> itemsSummary );
unset ( $pdf ); unset ( $tplidx ); unset ( $pagecount );
$rs -> MoveNext ();
}
}
}
/** Display a PDF invoice
*/
function pdf ( $VAR )
{
# Check invoice
if ( empty ( $VAR [ 'id' ])) {
echo 'No Invoice Specified.' ;
return false ;
}
# Check admin authentication:
global $C_auth ;
if ( $C_auth -> auth_method_by_name ( 'invoice' , 'view' ) == false ) {
# Validate on account level
$db = & DB ();
$rs = $db -> Execute ( sqlSelect ( $db , " invoice " , " account_id " , " id = :: { $VAR [ 'id' ] } :: " ));
if ( $rs -> fields [ 'account_id' ] != SESS_ACCOUNT ) {
// todo: redirect to login page if not logged
return false ;
}
}
$db =& DB ();
$invcfg = $db -> Execute ( sqlSelect ( $db , " setup_invoice " , " * " , " id=:: " . DEFAULT_SITE . " :: " ));
if ( ! defined ( 'FPDF_FONTPATH' ))
define ( 'FPDF_FONTPATH' , PATH_INCLUDES . 'pdf/font/' );
require_once ( PATH_INCLUDES . 'pdf/fpdi.php' );
require_once ( PATH_INCLUDES . 'pdf/fpdf_tpl.php' );
require_once ( PATH_INCLUDES . 'pdf/fpdf.php' );
require_once ( PATH_INCLUDES . 'pdf/pdf_invoice_' . $invcfg -> fields [ 'invoice_pdf_plugin' ] . '.inc.php' );
ob_start ();
$pdf = new pdf_invoice_overview ();
$pdf -> companyName = SITE_NAME ;
$pdf -> companyAddress = SITE_ADDRESS ;
$pdf -> companyCity = SITE_CITY ;
$pdf -> companyState = SITE_STATE ;
$pdf -> companyZip = SITE_ZIP ;
# load the setup_invoice
$pdf -> load_setup ( $invcfg );
$pagecount = $pdf -> setSourceFile ( $pdf -> getTemplate ());
$tplidx = $pdf -> ImportPage ( 1 );
$pdf -> addPage ();
$pdf -> useTemplate ( $tplidx );
$this -> pdfInvoiceSummary ( $VAR [ 'id' ], $pdf );
$pdf -> Output ( 'invoice.pdf' , 'D' );
$pdf -> closeParsers ();
ob_end_flush ();
}
/** Export multiple invoices */
function pdfExport ( & $rs )
{
$db =& DB ();
$invcfg = $db -> Execute ( sqlSelect ( $db , " setup_invoice " , " * " , " " ));
define ( 'FPDF_FONTPATH' , PATH_INCLUDES . 'pdf/font/' );
require_once ( PATH_INCLUDES . 'pdf/fpdi.php' );
require_once ( PATH_INCLUDES . 'pdf/fpdf_tpl.php' );
require_once ( PATH_INCLUDES . 'pdf/fpdf.php' );
require_once ( PATH_INCLUDES . 'pdf/pdf_invoice_' . $invcfg -> fields [ 'invoice_pdf_plugin' ] . '.inc.php' );
ob_start ();
$pdf = new pdf_invoice_overview ();
$pdf -> companyName = SITE_NAME ;
$pdf -> companyAddress = SITE_ADDRESS ;
$pdf -> companyCity = SITE_CITY ;
$pdf -> companyState = SITE_STATE ;
$pdf -> companyZip = SITE_ZIP ;
$pdf -> load_setup ( $invcfg );
$pagecount = $pdf -> setSourceFile ( $pdf -> getTemplate ());
$tplidx = $pdf -> ImportPage ( 1 );
while ( ! $rs -> EOF ) {
$pdf -> addPage ();
$pdf -> useTemplate ( $tplidx );
$this -> pdfInvoiceSummary ( $rs -> fields [ 'id' ], $pdf );
$rs -> MoveNext ();
unset ( $pdf -> itemsSummary );
}
$pdf -> Output ();
$pdf -> closeParsers ();
ob_end_flush ();
}
function pdfInvoiceSummary ( $id , & $pdf )
{
# Invoice details:
$db = & DB ();
$invoice = $db -> Execute ( $sql = sqlSelect ( $db , array ( " invoice " , " currency " ), " A.*, B.symbol " , " A.id = :: $id :: AND B.id = A.billed_currency_id " ));
$pdf -> setInvoiceFields ( $invoice -> fields );
$pdf -> setDueAmt ( $invoice -> fields [ 'total_amt' ] - $invoice -> fields [ 'billed_amt' ]);
$pdf -> setCurrency ( $invoice -> fields [ 'symbol' ]);
$pdf -> setDateRange ( mktime ( 0 , 0 , 0 , date ( 'm' , $invoice -> fields [ 'due_date' ]) - 1 , date ( 'd' , $invoice -> fields [ 'due_date' ]), date ( 'Y' , $invoice -> fields [ 'due_date' ])), $invoice -> fields [ 'due_date' ]);
$pdf -> drawInvoiceNo ();
$pdf -> drawInvoiceDueDate ();
$pdf -> drawInvoiceTotalAmt ();
$pdf -> drawInvoiceDueAmt ();
$pdf -> drawInvoicePaidAmt ();
$pdf -> drawInvoiceDiscountAmt ();
$pdf -> drawInvoiceTaxAmt ();
$pdf -> drawInvoiceShippingAmt ();
$pdf -> drawInvoiceRange ();
if ( $invoice -> fields [ 'billing_status' ] != 1 && $invoice -> fields [ 'suspend_billing' ] != 1 && $invoice -> fields [ 'due_date' ] <= time ())
$pdf -> drawInvoiceDueNotice ();
elseif ( $invoice -> fields [ 'billing_status' ] == 1 )
$pdf -> drawInvoicePaidNotice ();
# Account details:
$account = $db -> Execute ( " SELECT * FROM " . AGILE_DB_PREFIX . " account WHERE id = " . $db -> qstr ( $invoice -> fields [ 'account_id' ]) . " AND site_id = " . $db -> qstr ( DEFAULT_SITE ));
$pdf -> setAccountFields ( $account -> fields );
$pdf -> drawAccountId ();
$pdf -> drawAccountUsername ();
$pdf -> drawAccountName ();
$pdf -> drawAccountMailing ();
# Company details:
$pdf -> drawCompanyAddress ();
$pdf -> drawCompanyLogo ();
## Get the summary items
$items = & $db -> Execute ( " select sku, item_type, product_name, product_id, sum(quantity) as quantity, (sum(total_amt)) as amount, price_setup, price_base from " . AGILE_DB_PREFIX . " invoice_item where invoice_id= " . $db -> qstr ( $id ) . " group by sku, item_type " );
$i = 0 ;
if ( $items && $items -> RecordCount ()) {
while ( ! $items -> EOF ) {
$items_arr [ $i ] = $items -> fields ;
$desc = $this -> getLineItemDesc ( $items -> fields [ 'sku' ], $items -> fields [ 'product_id' ], false , $items -> fields [ 'product_name' ]);
$items_arr [ $i ][ 'name' ] = $desc ;
$i ++ ;
if ( $items -> fields [ 'price_setup' ]) {
$items_arr [ $i ][ 'name' ] = $desc . " Set-up Charge " ;
$items_arr [ $i ][ 'amount' ] = $items -> fields [ 'price_setup' ];
$i ++ ;
}
$items -> MoveNext ();
}
}
if ( $invoice -> fields [ 'discount_amt' ]) {
$items_arr [ $i ][ 'name' ] = 'Discount' ;
$items_arr [ $i ][ 'amount' ] = - ( $invoice -> fields [ 'discount_amt' ]);
$i ++ ;
}
if ( $invoice -> fields [ 'tax_amt' ]) {
$trs = $db -> Execute ( $sql = sqlSelect ( $db , Array ( 'invoice_item_tax' , 'tax' ), " A.amount,B.description " , " A.tax_id=B.id AND A.invoice_id=:: $id :: " ));
if ( $trs && $trs -> RecordCount ()) {
unset ( $taxes );
while ( ! $trs -> EOF ) {
$taxes [ " { $trs -> fields [ 'description' ] } " ] += $trs -> fields [ " amount " ];
$trs -> MoveNext ();
}
foreach ( $taxes as $txds => $txamt ) {
$items_arr [ $i ][ 'name' ] = $txds ;
$items_arr [ $i ][ 'amount' ] = $txamt ;
$i ++ ;
}
}
}
$pdf -> drawSummaryLineItems ( $items_arr );
unset ( $items_arr );
unset ( $pdf -> itemsSummary );
## BEGIN loop for enumerating information in multiple ways on the invoice
$iteration = 0 ;
while ( $pdf -> drawLineItems_pre ( $iteration )) {
## Get the line items:
$items = & $db -> Execute ( sqlSelect ( $db , " invoice_item " , " * " , " invoice_id = :: $id :: " ) );
if ( $items && $items -> RecordCount ()) {
while ( ! $items -> EOF ) {
#$items_arr[] = $items->fields;
// get the date range if set
if ( ! empty ( $items -> fields [ 'date_start' ]) && ! empty ( $items -> fields [ 'date_stop' ])) {
global $C_translate ;
$C_translate -> value ( 'invoice' , 'start' , date ( UNIX_DATE_FORMAT , $items -> fields [ 'date_start' ]));
$C_translate -> value ( 'invoice' , 'stop' , date ( UNIX_DATE_FORMAT , $items -> fields [ 'date_stop' ]));
#$smart_items[$ii]['range'] = $C_translate->translate('recur_date_range','invoice','');
}
$cost = $items -> fields [ 'price_base' ];
$total = $cost * $items -> fields [ 'quantity' ];
$desc = $this -> getLineItemDesc ( $items -> fields [ 'sku' ], $items -> fields [ 'product_id' ], strtolower ( $items -> fields [ 'domain_name' ] . '.' . $items -> fields [ 'domain_tld' ]), $items -> fields [ 'product_name' ]);
$line = array (
" name " => $desc ,
'amount' => $cost ,
'sku' => $items -> fields [ 'sku' ],
'qty' => $items -> fields [ 'quantity' ],
'cost' => $cost ,
'attr' => $items -> fields [ 'product_attr' ],
'price_type' => $items -> fields [ 'price_type' ],
'price_base' => $items -> fields [ 'price_base' ],
'item_type' => $items -> fields [ 'item_type' ],
'total_amt' => $items -> fields [ 'total_amt' ]
);
$pdf -> drawLineItems ( $db , $line );
if ( $items -> fields [ 'price_setup' ]) {
$desc .= " Set-up Charge " ;
$total = $items -> fields [ 'price_setup' ];
$line = array ( " name " => $desc , 'amount' => $total , 'qty' => '1' , 'sku' => $items -> fields [ 'sku' ], 'cost' => $total , 'price_base' => $total , 'price_type' => 999 );
$pdf -> drawLineItems ( $db , $line );
}
$items -> MoveNext ();
}
}
if ( $invoice -> fields [ 'discount_amt' ]) {
$desc = 'Discount' ;
$total = - ( $invoice -> fields [ 'discount_amt' ]);
$line = array ( " name " => $desc , 'amount' => $total , 'qty' => '1' , 'cost' => $total , 'price_base' => $total , 'price_type' => 999 );
$pdf -> drawLineItems ( $db , $line );
}
if ( $invoice -> fields [ 'tax_amt' ]) {
$trs = $db -> Execute ( $sql = sqlSelect ( $db , Array ( 'invoice_item_tax' , 'tax' ), " A.amount,B.description " , " A.tax_id=B.id AND A.invoice_id=:: $id :: " ));
if ( $trs && $trs -> RecordCount ()) {
unset ( $taxes );
while ( ! $trs -> EOF ) {
$taxes [ " { $trs -> fields [ 'description' ] } " ] += $trs -> fields [ " amount " ];
$trs -> MoveNext ();
}
foreach ( $taxes as $txds => $txamt ) {
$line = array ( " name " => $txds , 'amount' => $txamt , 'qty' => '1' , 'cost' => $txamt , 'price_base' => $txamt , 'price_type' => 999 );
$pdf -> drawLineItems ( $db , $line );
}
}
}
# Increment the iteration
++ $iteration ;
}
# Custom functions:
$pdf -> drawCustom ();
unset ( $db );
}
/** RESEND DUE NOTICE
*/
function resend ( $VAR )
{
global $C_debug ;
# User invoice creation confirmation
include_once ( PATH_MODULES . 'email_template/email_template.inc.php' );
$mail = new email_template ;
$mail -> send ( 'invoice_resend' , $VAR [ 'account_id' ], $VAR [ 'id' ], '' , '' );
# Alert
$C_debug -> alert ( 'Sent payment due notice to user' );
# Update invoice
$db = & DB ();
$q = " SELECT notice_count FROM " . AGILE_DB_PREFIX . " invoice WHERE
id = " . $db->qstr ( $VAR['id'] ). " AND
site_id = " . $db->qstr (DEFAULT_SITE);
$rs = $db -> Execute ( $q );
$count = $rs -> fields [ 'notice_count' ] + 1 ;
$q = " UPDATE " . AGILE_DB_PREFIX . " invoice SET
notice_count = " . $db->qstr ( $count ). " WHERE
id = " . $db->qstr ( $VAR['id'] ). " AND
site_id = " . $db->qstr (DEFAULT_SITE);
$rs = $db -> Execute ( $q );
}
/**
* Generate all invoices for recurring services / charges / domains
*/
function generate () {
// check if charge module installed
global $C_list ;
$charge_installed = $C_list -> is_installed ( 'charge' );
// get services to be billed grouped by account and date
if ( MAX_INV_GEN_PERIOD <= 0 ) $max_date = time () + 86400 ; else $max_date = time () + ( MAX_INV_GEN_PERIOD * 86400 );
$p = AGILE_DB_PREFIX ; $s = DEFAULT_SITE ;
$ids = false ;
$account = false ;
$date = false ;
$invoice = false ;
$sql = " SELECT DISTINCT service.id as serviceId, account.id as accountId, invoice.id as invoiceId, from_unixtime(service.date_next_invoice,'%Y-%m-%d') as dayGroup
FROM { $p } service as service
JOIN { $p } account as account ON ( service . account_id = account . id and account . site_id = { $s } )
LEFT JOIN { $p } invoice as invoice ON ( service . invoice_id = invoice . id and invoice . site_id = { $s } )
WHERE service . site_id = { $s }
AND service . active = 1
AND ( service . suspend_billing IS NULL OR service . suspend_billing = 0 )
AND ( service . date_next_invoice > 0 AND service . date_next_invoice IS NOT NULL )
AND
((
( account . invoice_advance_gen != '' OR account . invoice_advance_gen is not null ) AND service . date_next_invoice <= ( UNIX_TIMESTAMP ( CURDATE ()) + ( account . invoice_advance_gen * 86400 ))
) OR (
( account . invoice_advance_gen = '' OR account . invoice_advance_gen is null ) AND service . date_next_invoice <= { $max_date }
))
ORDER BY accountId , dayGroup , serviceId " ;
$db =& DB ();
#$db->debug=true;
$rs = $db -> Execute ( $sql );
if ( $rs === false ) { global $C_debug ; $C_debug -> error ( 'invoice.inc.php' , 'generate()' , $sql . " \r \n \r \n " . @ $db -> ErrorMsg ()); }
if ( $rs && $rs -> RecordCount ()) {
while ( ! $rs -> EOF ) {
if ( $ids && ( $rs -> fields [ 'accountId' ] != $account ) || ( $rs -> fields [ 'dayGroup' ] != $date ) ) {
$this -> generateInvoices ( $ids , $account , $invoice , $charge_installed );
$ids = false ;
}
// set the current account and date
$account = $rs -> fields [ 'accountId' ];
$invoice = $rs -> fields [ 'invoiceId' ];
$date = $rs -> fields [ 'dayGroup' ];
// add to id list
if ( $ids ) $ids .= " , " ;
$ids .= $rs -> fields [ 'serviceId' ];
$rs -> MoveNext ();
}
if ( $ids ) $this -> generateInvoices ( $ids , $account , $invoice , $charge_installed );
}
// Generate invoices for any domains expiring in X days.
if ( $C_list -> is_installed ( 'host_tld' )) $this -> generateDomains ();
return true ;
}
function generateInvoices ( $ids , $account_id , $invoice_id , $charge_installed = false ) {
if ( empty ( $ids )) return false ;
# load required elements
include_once ( PATH_MODULES . 'service/service.inc.php' );
include_once ( PATH_MODULES . 'discount/discount.inc.php' );
include_once ( PATH_MODULES . 'tax/tax.inc.php' );
$taxObj = new tax ;
$serviceObj = new service ;
# start a transaction
$db =& DB ();
#$db->debug=true;
if ( AGILE_DB_TYPE == 'mysqlt' ) {
$db -> StartTrans ();
if ( ! $db -> hasTransactions ) {
global $C_debug ;
$msg = " Transactions not supported in 'mysql' driver. Use 'mysqlt' or 'mysqli' driver " ;
$C_debug -> alert ( $msg );
$C_debug -> error ( 'invoice.inc.php' , 'generateInvoices()' , " Transactions not supported in 'mysql' driver. Use 'mysqlt' or 'mysqli' driver " );
return false ;
}
}
# generate an invoice id
$invoice = sqlGenID ( $db , 'invoice' );
# check for any discounts for the parent invoice or account_id
# applied at checkout and should continue to be applied if recurring type discount
$discountObj = new discount ;
$discountObj -> available_discounts ( $account_id , 1 , $invoice_id );
# beginning totals
$sub_total = 0 ;
$taxable_amount = 0 ;
$tax_amt = 0 ;
$discount_amt = 0 ;
# get the full account and service and invoice details
$p = AGILE_DB_PREFIX ; $s = DEFAULT_SITE ;
$sql = " SELECT DISTINCT
service . id , service . parent_id , service . invoice_id , service . invoice_item_id , service . account_id , service . account_billing_id , service . product_id ,
service . sku , service . active , service . bind , service . type , service . price , service . price_type , service . taxable , service . date_last_invoice , service . date_next_invoice ,
service . recur_type , service . recur_schedule , service . recur_weekday , service . recur_week , service . domain_name ,
service . domain_tld , service . domain_type , service . domain_term , service . prod_attr , service . prod_attr_cart ,
account . currency_id , account . first_name , account . last_name , account . country_id , account . state , account . invoice_grace , account . invoice_advance_gen , account . affiliate_id as account_affiliate_id ,
invoice . affiliate_id , invoice . campaign_id , invoice . reseller_id , invoice . checkout_plugin_id , invoice . checkout_plugin_data , invoice . billed_currency_id , invoice . actual_billed_currency_id
FROM { $p } service as service
JOIN { $p } account as account ON ( service . account_id = account . id and account . site_id = { $s } )
LEFT JOIN { $p } invoice as invoice ON ( service . invoice_id = invoice . id and invoice . site_id = { $s } )
WHERE service . id in ({ $ids }) " ;
$service = $db -> Execute ( $sql );
if ( $service === false ) { global $C_debug ; $C_debug -> error ( 'invoice.inc.php' , 'generateInvoices()1' , $sql . " \r \n \r \n " . @ $db -> ErrorMsg ()); $db -> FailTrans (); return false ; }
if ( $service && $service -> RecordCount ()) {
while ( ! $service -> EOF ) {
if ( empty ( $service -> fields [ 'billed_currency_id' ])) $service -> fields [ 'billed_currency_id' ] = DEFAULT_CURRENCY ;
if ( empty ( $service -> fields [ 'actual_billed_currency_id' ])) $service -> fields [ 'actual_billed_currency_id' ] = $service -> fields [ 'billed_currency_id' ];
$this -> account_id = $service -> fields [ 'account_id' ];
$this -> parent_id = $service -> fields [ 'invoice_id' ];
$this -> account_billing_id = $service -> fields [ 'account_billing_id' ];
if ( ! empty ( $service -> fields [ 'account_affiliate_id' ]))
$this -> affiliate_id = $service -> fields [ 'account_affiliate_id' ];
else
$this -> affiliate_id = $service -> fields [ 'affiliate_id' ];
$this -> campaign_id = $service -> fields [ 'campaign_id' ];
$this -> reseller_id = $service -> fields [ 'reseller_id' ];
$this -> checkout_plugin_id = $service -> fields [ 'checkout_plugin_id' ];
$this -> checkout_plugin_data = $service -> fields [ 'checkout_plugin_data' ];
$this -> billed_currency_id = $service -> fields [ 'billed_currency_id' ];
$this -> actual_billed_currency_id = $service -> fields [ 'actual_billed_currency_id' ];
$this -> invoice_grace = $service -> fields [ 'invoice_grace' ];
$item_tax_amt = 0 ;
$item_total_amt = 0 ;
$item_discount_amt = 0 ;
# gen item_id
$item = sqlGenID ( $db , " invoice_item " );
# Calculate any recurring discounts for this item
$item_total_amt = $service -> fields [ 'price' ];
$item_discount_amt = $discountObj -> calc_all_discounts ( 1 , $item , $service -> fields [ 'product_id' ], $service -> fields [ 'price' ], $service -> fields [ 'account_id' ], $sub_total + $service -> fields [ 'price' ]);
$item_total_amt -= $item_discount_amt ;
$sub_total += $item_total_amt ;
$discount_amt += $item_discount_amt ;
# calculate any taxes for this item
if ( $service -> fields [ 'taxable' ] == 1 ) {
$item_tax_amt = 0 ;
$item_tax_arr = $taxObj -> calculate ( $item_total_amt , $service -> fields [ 'country_id' ], $service -> fields [ 'state' ]);
if ( is_array ( $item_tax_arr )) foreach ( $item_tax_arr as $tx ) $item_tax_amt += $tx [ 'rate' ];
$tax_amt += $item_tax_amt ;
}
# Calculate next invoice date
$next_invoice = $serviceObj -> calcNextInvoiceDate ( $service -> fields [ 'date_next_invoice' ], $service -> fields [ 'recur_schedule' ], $service -> fields [ 'recur_type' ], $service -> fields [ 'recur_weekday' ]);
$due_date = $service -> fields [ 'date_next_invoice' ];
$recur_schedule = 0 ;
if ( ! empty ( $service -> fields [ 'recur_schedule' ])) $recur_schedule = $service -> fields [ 'recur_schedule' ];
// create the invoice item
$sql = " INSERT INTO { $p } invoice_item SET
id = $item ,
site_id = $s ,
date_orig = " .time(). " ,
invoice_id = $invoice ,
account_id = { $service -> fields [ 'account_id' ]},
service_id = { $service -> fields [ 'id' ]},
product_id = { $service -> fields [ 'product_id' ]},
product_attr = " . $db->qstr ( $service->fields ['prod_attr']). " ,
product_attr_cart = " . $db->qstr ( $service->fields ['prod_attr_cart']). " ,
sku = " . $db->qstr ( $service->fields ['sku']). " ,
quantity = 1 ,
item_type = 0 ,
price_type = { $service -> fields [ 'price_type' ]},
price_base = { $service -> fields [ 'price' ]},
price_setup = 0 ,
recurring_schedule = { $recur_schedule },
date_start = { $service -> fields [ 'date_next_invoice' ]},
date_stop = $next_invoice ,
domain_name = " . $db->qstr ( $service->fields ['domain_name']). " ,
domain_tld = " . $db->qstr ( $service->fields ['domain_tld']). " ,
domain_type = " . $db->qstr ( $service->fields ['domain_type']). " ,
tax_amt = $tax_amt ,
total_amt = $item_total_amt ,
discount_amt = $item_discount_amt " ;
$itemrs = $db -> Execute ( $sql );
if ( $itemrs === false ) { global $C_debug ; $C_debug -> error ( 'invoice.inc.php' , 'generateInvoices()2' , $sql . " \r \n \r \n " . @ $db -> ErrorMsg ()); $db -> FailTrans (); return false ; }
// Insert tax records
$taxObj -> invoice_item ( $invoice , $item , $service -> fields [ 'account_id' ], @ $item_tax_arr );
# Insert discount records
$discountObj -> invoice_item ( $invoice , $item , $service -> fields [ 'account_id' ], @ $discountObj -> discount_arr );
// Update the last & next invoice date for this service
$sql = " UPDATE { $p } service
SET
date_last_invoice = { $service -> fields [ 'date_next_invoice' ]},
date_next_invoice = $next_invoice
WHERE
site_id = $s AND id = { $service -> fields [ 'id' ]} " ;
$srvsrs = $db -> Execute ( $sql );
if ( $srvsrs === false ) { global $C_debug ; $C_debug -> error ( 'invoice.inc.php' , 'generateInvoices()3' , $sql . " \r \n \r \n " . @ $db -> ErrorMsg ()); $db -> FailTrans (); return false ; }
// get any charges for this service and create them as invoice items
if ( $charge_installed ) {
$sql = " SELECT * FROM " . AGILE_DB_PREFIX . " charge WHERE (status=0 or status is null) and site_id= " . DEFAULT_SITE . " AND service_id = " . $service -> fields [ 'id' ] . " AND date_orig < " . $service -> fields [ 'date_next_invoice' ];
$charge = $db -> Execute ( $sql );
if ( $charge && $charge -> RecordCount ()) {
while ( ! $charge -> EOF ) {
$item_tax_amt = 0 ;
$item_total_amt = 0 ;
$item_discount_amt = 0 ;
// Calculate any recurring discounts for this charge item
$item_total_amt = ( $charge -> fields [ 'quantity' ] * $charge -> fields [ 'amount' ]);
$item_discount_amt = $discountObj -> calc_all_discounts ( 1 , $item , $charge -> fields [ 'product_id' ], $item_total_amt , $service -> fields [ 'account_id' ], $sub_total + $item_total_amt );
$item_total_amt -= $item_discount_amt ;
$sub_total += $item_total_amt ;
$discount_amt += $item_discount_amt ;
// calculate any taxes for this item
if ( $charge -> fields [ 'taxable' ] == 1 ) {
$item_tax_amt = 0 ;
$item_tax_arr = $taxObj -> calculate ( $chargeamt , $service -> fields [ 'country_id' ], $service -> fields [ 'state' ]);
if ( is_array ( $item_tax_arr )) foreach ( $item_tax_arr as $tx ) $item_tax_amt += $tx [ 'rate' ];
$tax_amt += $item_tax_amt ;
}
// create the invoice item
$charge_item_id = sqlGenID ( $db , 'invoice_item' );
$sql = " INSERT INTO { $p } invoice_item SET
id = $charge_item_id ,
site_id = $s ,
charge_id = { $charge -> fields [ 'id' ]},
date_orig = " .time(). " ,
invoice_id = $invoice ,
account_id = " . $this->account_id . " ,
service_id = " . $db->qstr ( $service->fields ['id']). " ,
product_id = " . $db->qstr ( $charge->fields ['product_id']). " ,
product_attr = " . $db->qstr ( $charge->fields ['attributes']). " ,
sku = " . $db->qstr ( $service->fields ['sku']). " ,
price_base = " . $db->qstr ( $charge->fields ['amount']). " ,
quantity = " . $charge->fields ['quantity']. " ,
item_type = 5 ,
price_type = 0 ,
price_setup = 0 ,
tax_amt = $item_tax_amt ,
total_amt = $item_total_amt ,
discount_amt = $item_discount_amt " ;
$itemrs = $db -> Execute ( $sql );
if ( $itemrs === false ) { global $C_debug ; $C_debug -> error ( 'invoice.inc.php' , 'generateInvoices()4' , $sql . " \r \n \r \n " . @ $db -> ErrorMsg ()); $db -> FailTrans (); return false ; }
# Insert tax records
$taxObj -> invoice_item ( $invoice , $charge_item_id , $charge -> fields [ 'account_id' ], @ $item_tax_arr );
# Insert discount records
$discountObj -> invoice_item ( $invoice , $charge_item_id , $charge -> fields [ 'account_id' ], @ $discountObj -> discount_arr );
# update charge status
$chargers = $db -> Execute ( " UPDATE " . AGILE_DB_PREFIX . " charge set status=1 WHERE id= { $charge -> fields [ 'id' ] } AND site_id= " . DEFAULT_SITE );
if ( $chargers === false ) { global $C_debug ; $C_debug -> error ( 'invoice.inc.php' , 'generateInvoices()2' , $sql . " \r \n \r \n " . @ $db -> ErrorMsg ()); $db -> FailTrans (); return false ; }
$charge -> MoveNext ();
}
}
}
$service -> MoveNext ();
}
// add any taxes
@ $total = $sub_total + $tax_amt ;
// get invoice grace period from global/account
if ( ! empty ( $this -> invoice_grace )) $grace_period = $this -> invoice_grace ; else $grace_period = GRACE_PERIOD ;
$sql = " INSERT INTO { $p } invoice SET
id = $invoice ,
site_id = $s ,
date_orig = " .time(). " ,
date_last = " .time(). " ,
notice_next_date = " .time(). " ,
type = 1 ,
process_status = 0 ,
billing_status = 0 ,
suspend_billing = 0 ,
print_status = 0 ,
refund_status = 0 ,
billed_amt = 0 ,
actual_billed_amt = 0 ,
notice_count = 0 ,
parent_id = " . $db->qstr ( $this->parent_id ). " ,
account_id = { $this -> account_id },
account_billing_id = " . $db->qstr ( $this->account_billing_id ). " ,
affiliate_id = " . $db->qstr ( $this->affiliate_id ). " ,
campaign_id = " . $db->qstr ( $this->campaign_id ). " ,
reseller_id = " . $db->qstr ( $this->reseller_id ). " ,
checkout_plugin_id = " . $db->qstr ( $this->checkout_plugin_id ). " ,
checkout_plugin_data = " . $db->qstr ( $this->checkout_plugin_data ). " ,
actual_billed_currency_id = " . $db->qstr ( $this->actual_billed_currency_id ). " ,
billed_currency_id = " . $db->qstr ( $this->billed_currency_id ). " ,
notice_max = " . $db->qstr (MAX_BILLING_NOTICE). " ,
grace_period = " . $db->qstr ( $grace_period ). " ,
tax_amt = " . $tax_amt . " ,
discount_amt = " . $discount_amt . " ,
total_amt = " . $total . " ,
due_date = $due_date " ;
$invoicers = $db -> Execute ( $sql );
if ( $invoicers === false ) { global $C_debug ; $C_debug -> error ( 'invoice.inc.php' , 'generateInvoices()2' , $sql . " \r \n \r \n " . @ $db -> ErrorMsg ()); $db -> FailTrans (); return false ; }
}
if ( AGILE_DB_TYPE == 'mysqlt' ) $db -> CompleteTrans ();
}
/** Invoice expiring domains
*/
function generateDomains ()
{
$db = & DB ();
define ( 'DEFAULT_DOMAIN_INVOICE' , 30 ); //how far out to generate expiring domain invoices
$expire = time () + ( DEFAULT_DOMAIN_INVOICE * 86400 );
### Get domains expiring soon:
$rs = $db -> Execute ( sqlSelect ( $db , 'service' , '*' , " active=1 AND domain_date_expire <= $expire AND type = 'domain' AND queue = 'none' AND
( domain_type = 'register' OR domain_type = 'transfer' OR domain_type = 'renew' ) AND
( suspend_billing = 0 OR suspend_billing IS NULL ) " ) );
if ( $rs && $rs -> RecordCount () > 0 ) {
while ( ! $rs -> EOF ) {
# Check that this domain has not already been invoiced
$invoiced = $db -> Execute ( sqlSelect ( $db , Array ( 'invoice_item' , 'invoice' ), Array ( 'A.*' , 'B.*' ),
" A.invoice_id = B.id AND A.service_id = { $rs -> fields [ 'id' ] } AND A.sku = 'DOMAIN-RENEW' AND domain_type = 'renew' AND
date_start = { $rs -> fields [ 'date_last_invoice' ]} AND date_stop = { $rs -> fields [ 'domain_date_expire' ]} " ) );
if ( $invoiced && $invoiced -> RecordCount () == 0 ) {
# Not previously invoiced, generate now!
$this -> generatedomaininvoice ( $rs -> fields , $this );
}
$rs -> MoveNext ();
}
}
}
/** Invoice expiring domains p2
*/
function generatedomaininvoice ( $VAR )
{
include_once ( PATH_MODULES . 'tax/tax.inc.php' );
$taxObj = new tax ;
$db = & DB ();
if ( is_array ( $VAR ) ) {
$expire = time ();
$rs = $db -> Execute ( sqlSelect ( $db , 'service' , '*' , " id = :: { $VAR [ 'id' ] } :: AND active=1
AND type = 'domain' AND queue = 'none' AND
( domain_type = 'register' OR domain_type = 'transfer' OR domain_type = 'renew' ) AND
( suspend_billing = 0 OR suspend_billing IS NULL ) " ));
$service = $rs -> fields ;
} else {
$service = $VAR ;
}
if ( empty ( $service [ 'id' ])) {
global $C_debug ;
$C_debug -> alert ( " Unable to generate domain renweal invoice due to domain status. " );
return false ;
}
# Get the parent invoice details:
if ( ! empty ( $service [ 'invoice_id' ])) {
$rs = $db -> Execute ( sqlSelect ( $db , 'invoice' , '*' , " id = { $service [ 'invoice_id' ] } " , " " ) );
$invoice = $rs -> fields ;
} else {
$invoice = false ;
}
# Get the account details:
$rs = $db -> Execute ( sqlSelect ( $db , 'account' , '*' , " id = { $service [ 'account_id' ] } " , " " ) );
$account = $rs -> fields ;
# Get the account price
include_once ( PATH_MODULES . 'host_tld/host_tld.inc.php' );
$tldObj = new host_tld ;
$tld_arr = $tldObj -> price_tld_arr ( $service [ 'domain_tld' ], 'renew' , false , false , false , $service [ 'account_id' ]);
foreach ( $tld_arr as $term => $price ) break ;
# Calculate taxes:
$rs = $db -> Execute ( $sql = sqlSelect ( $db , " host_tld " , " taxable " , " name = :: { $service [ 'domain_tld' ] } :: " ));
if ( $service [ 'taxable' ] || @ $rs -> fields [ 'taxable' ] ) {
$tax_arr = $taxObj -> calculate ( $price , $account [ " country_id " ], $account [ " state " ]);
} else {
$tax_arr = false ;
}
$total = $price ;
$tax_amt = 0 ;
if ( is_array ( $tax_arr )) {
foreach ( $tax_arr as $tx ) {
$tax_amt += $tx [ 'rate' ];
}
$total += $tax_amt ;
}
# calculate the dates
$expire = $service [ 'domain_date_expire' ] + ( $term * 86400 );
$due_date = $service [ 'domain_date_expire' ] - ( 86400 * 3 );
# Create the invoice
$id = sqlGenID ( $db , " invoice " );
$insert = $db -> Execute ( $sql = sqlInsert ( $db , " invoice " ,
Array (
'date_orig' => time (),
'date_last' => time (),
'type' => 2 ,
'process_status' => 0 ,
'billing_status' => 0 ,
'suspend_billing' => 0 ,
'print_status' => 0 ,
'parent_id' => $service [ 'invoice_id' ],
'account_id' => $service [ 'account_id' ],
'account_billing_id' => $service [ 'account_billing_id' ],
'affiliate_id' => @ $invoice [ 'affiliate_id' ],
'campaign_id' => @ $invoice [ 'campaign_id' ],
'reseller_id' => @ $invoice [ 'reseller_id' ],
'checkout_plugin_id' => @ $invoice [ 'checkout_plugin_id' ],
'tax_amt' => $tax_amt ,
'discount_arr' => serialize ( @ $discount_arr ),
'discount_amt' => @ $discount_amt ,
'total_amt' => $total ,
'billed_amt' => 0 ,
'billed_currency_id' => DEFAULT_CURRENCY ,
'actual_billed_amt' => 0 ,
'actual_billed_currency_id' => @ $invoice [ 'actual_billed_currency_id' ],
'notice_count' => 0 ,
'notice_next_date' => time (),
'notice_max' => MAX_BILLING_NOTICE ,
'grace_period' => 0 ,
'due_date' => $due_date
), $id ) ) ;
# create the invoice item:
if ( $insert ) {
$db -> Execute ( $idx = sqlInsert ( $db , " invoice_item " ,
Array (
'date_orig' => time (),
'invoice_id' => $id ,
'account_id' => $service [ 'account_id' ],
'service_id' => $service [ 'id' ],
'sku' => 'DOMAIN-RENEW' ,
'quantity' => 1 ,
'item_type' => 2 ,
'price_type' => 0 ,
'price_base' => $price ,
'price_setup' => 0 ,
'domain_type' => 'renew' ,
'date_start' => $service [ 'domain_date_expire' ],
'date_stop' => $expire ,
'domain_name' => $service [ 'domain_name' ],
'domain_tld' => $service [ 'domain_tld' ],
'domain_term' => $term ,
'tax_amt' => $tax_amt ,
'total_amt' => $price
) ) );
# Insert tax records
$taxObj -> invoice_item ( $id , $idx , $service [ 'account_id' ], @ $item_tax_arr );
# Update the service record
$fields = Array ( 'active' => 0 );
$db -> Execute ( sqlUpdate ( $db , " service " , $fields , " id = { $service [ 'id' ] } " ));
global $C_debug ;
$C_debug -> alert ( " Generated domain renewal invoice for { $service [ 'domain_name' ] } . { $service [ 'domain_tld' ] } " );
return $id ;
}
}
/** Run AutoBilling and Due Notices
*/
function autobill ( $VAR )
{
global $VAR , $C_debug , $C_list ;
# User invoice creation confirmation
include_once ( PATH_MODULES . 'email_template/email_template.inc.php' );
$mail = new email_template ;
# get all due invoices
$db = & DB ();
#$db->debug = true;
if ( empty ( $VAR [ 'invoice_id' ]))
{
$this -> bill_one = false ;
$sql = 'SELECT * FROM ' . AGILE_DB_PREFIX . ' invoice
WHERE notice_next_date <= ' . $db->qstr( time() ) . '
AND (
billing_status = 0 OR
billing_status IS NULL
) AND (
suspend_billing = 0 OR
suspend_billing IS NULL
)
AND site_id = ' . $db -> qstr ( DEFAULT_SITE );
$invoice = $db -> Execute ( $sql );
if ( $invoice -> RecordCount () == 0 ) {
$C_debug -> alert ( 'No Invoices to Autobill' );
return false ;
}
} else {
# get the specified invoice:
$this -> bill_one = true ;
$sql = 'SELECT * FROM ' . AGILE_DB_PREFIX . ' invoice
WHERE (
billing_status = 0 OR
billing_status IS NULL
)
AND id = ' . $db->qstr($VAR[' invoice_id ']) . '
AND site_id = ' . $db -> qstr ( DEFAULT_SITE );
$invoice = $db -> Execute ( $sql );
}
# Check for results
if ( $invoice -> RecordCount () == 0 ) {
$C_debug -> alert ( 'Invoice could not be billed!' );
return false ;
}
# Loop through results
while ( ! $invoice -> EOF )
{
$db -> StartTrans ();
$due = true ;
# get currency code
$cyid = $invoice -> fields [ 'actual_billed_currency_id' ];
$billed_currency_id = $invoice -> fields [ 'billed_currency_id' ];
if ( empty ( $this -> currency_iso [ $cyid ]))
{
$q = " SELECT three_digit,convert_array FROM " . AGILE_DB_PREFIX . " currency WHERE
id = " . $db->qstr ( $cyid ). " AND
site_id = " . $db->qstr (DEFAULT_SITE);
$currb = $db -> Execute ( $q );
$this -> format_currency [ $cyid ] = Array ( 'convert' => unserialize ( $currb -> fields [ " convert_array " ]),
'iso' => $currb -> fields [ " three_digit " ]);
}
# get the currency codes (default)
if ( empty ( $this -> format_currency [ $billed_currency_id ]))
{
# Get the billed currency id currency info:
$q = " SELECT three_digit,convert_array FROM " . AGILE_DB_PREFIX . " currency WHERE
id = " . $db->qstr ( $billed_currency_id ). " AND
site_id = " . $db->qstr (DEFAULT_SITE);
$currb = $db -> Execute ( $q );
$this -> format_currency [ $billed_currency_id ] = Array ( 'convert' => unserialize ( $currb -> fields [ " convert_array " ]),
'iso' => $currb -> fields [ " three_digit " ]);
}
# attempt to autobill?
if ( ! empty ( $invoice -> fields [ 'account_billing_id' ] ))
{
# get checkout plugin details:
$billing =& $db -> Execute ( $sql = sqlSelect ( $db , array ( 'account_billing' , 'checkout' ), 'A.*,B.checkout_plugin' ,
" A.id = :: { $invoice -> fields [ 'account_billing_id' ] } :: AND A.checkout_plugin_id=B.id " ));
if ( $billing && $billing -> RecordCount () == 1 && ! empty ( $billing -> fields [ 'checkout_plugin' ])) {
$plugin_file = PATH_PLUGINS . 'checkout/' . $billing -> fields [ 'checkout_plugin' ] . '.php' ;
if ( ! is_file ( $plugin_file )) {
$err = $plugin_file . ' missing when autobilling invoice id ' . $invoice -> fields [ 'id' ];
$C_debug -> error ( 'invoice.inc.php' , 'autobill()' , $err );
} else {
include_once ( $plugin_file );
eval ( '$PLG = new plg_chout_' . $billing -> fields [ 'checkout_plugin' ] . '("' . $billing -> fields [ 'checkout_plugin_id' ] . '");' );
}
} else {
$err = 'account_billing.id ' . $invoice -> fields [ 'account_billing_id' ] . ' empty or not associated with a checkout plugin when autobilling invoice id ' . $invoice -> fields [ 'id' ];
$C_debug -> error ( 'invoice.inc.php' , 'autobill()' , $err );
}
}
# get the actual billed amount
$amount = $invoice -> fields [ 'total_amt' ] - $invoice -> fields [ 'billed_amt' ];
$billed_amt = $invoice -> fields [ 'total_amt' ];
$actual_billed_amt = $invoice -> fields [ 'total_amt' ];
if ( $amount <= 0 ) $due = false ;
if ( ! empty ( $PLG ) && is_object ( $PLG ) && $PLG -> type == 'gateway' && $amount > 0 )
{
# attempt autobilling if account billing exists and gateway plugin
if ( $invoice -> fields [ 'account_billing_id' ] > 0 )
{
/* get the account details */
$account = $db -> Execute ( sqlSelect ( $db , " account " , " id,email " , " id=:: { $invoice -> fields [ 'account_id' ] } " ));
/* Convert the invoice amount to the actual billed currency amount */
if ( $cyid != $invoice -> fields [ 'billed_currency_id' ]) {
$conversion = $this -> format_currency [ $billed_currency_id ][ " convert " ][ $cyid ][ " rate " ];
$amount *= $conversion ;
$actual_billed_amt = $invoice -> fields [ 'actual_billed_amt' ] + $amount ;
}
/* load the billing details from the database */
$PLG -> setBillingFromDBObj ( $billing , true );
/* attempt to auto-bill */
if ( ! $checkout_plugin_data = $PLG -> bill_checkout ( number_format ( $amount , 2 ), $invoice -> fields [ 'id' ], $this -> format_currency [ $cyid ][ 'iso' ], $account -> fields , 0 , 0 ) ) {
$due = true ;
$email = new email_template ;
$email -> send ( 'invoice_decline_user' , $invoice -> fields [ 'account_id' ], $invoice -> fields [ 'id' ], $C_list -> format_currency ( $invoice -> fields [ 'total_amt' ], $cyid ), $C_list -> date ( $invoice -> fields [ 'due_date' ]));
$email = new email_template ;
$email -> send ( 'admin->invoice_decline_admin' , $invoice -> fields [ 'account_id' ], $invoice -> fields [ 'id' ], $C_list -> format_currency ( $invoice -> fields [ 'total_amt' ], '' ), $C_list -> date ( $invoice -> fields [ 'due_date' ]));
} else {
$due = false ;
}
}
}
# send proper alert & manage services
if ( $due )
{
# determine if overdue
$due = $invoice -> fields [ 'due_date' ];
$grace = $invoice -> fields [ 'grace_period' ];
if ( time () < $due + ( 86400 * $grace ))
{
if ( $invoice -> fields [ 'notice_count' ] <= 0 )
{
# send out first alert - new invoice created!
$email = new email_template ;
$email -> send ( 'invoice_recur_user' , $invoice -> fields [ 'account_id' ], $invoice -> fields [ 'id' ], $C_list -> format_currency ( $invoice -> fields [ 'total_amt' ], $cyid ), $C_list -> date ( $invoice -> fields [ 'due_date' ]));
$email = new email_template ;
$email -> send ( 'admin->invoice_recur_admin' , $invoice -> fields [ 'account_id' ], $invoice -> fields [ 'id' ], $C_list -> format_currency ( $invoice -> fields [ 'total_amt' ], '' ), $C_list -> date ( $invoice -> fields [ 'due_date' ]));
}
else
{
# send out payment due notice
if ( empty ( $PLG ) || $PLG -> type == 'gateway' ) {
$email = new email_template ;
$email -> send ( 'invoice_due_user' , $invoice -> fields [ 'account_id' ], $invoice -> fields [ 'id' ], $this -> format_currency [ $cyid ][ " iso " ], $C_list -> date ( $invoice -> fields [ 'due_date' ]));
$email = new email_template ;
$email -> send ( 'admin->invoice_due_admin' , $invoice -> fields [ 'account_id' ], $invoice -> fields [ 'id' ], $this -> format_currency [ $billed_currency_id ][ " iso " ], $C_list -> date ( $invoice -> fields [ 'due_date' ]));
}
elseif ( $PLG -> type == 'redirect' ) {
$email = new email_template ;
$email -> send ( 'invoice_due_user' , $invoice -> fields [ 'account_id' ], $invoice -> fields [ 'id' ], $this -> format_currency [ $cyid ][ " iso " ], $C_list -> date ( $invoice -> fields [ 'due_date' ]));
} elseif ( $PLG -> type == 'other' ) {
$email = new email_template ;
$email -> send ( 'admin->invoice_due_admin' , $invoice -> fields [ 'account_id' ], $invoice -> fields [ 'id' ], $this -> format_currency [ $billed_currency_id ][ " iso " ], $C_list -> date ( $invoice -> fields [ 'due_date' ]));
}
}
# increment notice counter
$sql = 'UPDATE ' . AGILE_DB_PREFIX . ' invoice SET
notice_count = ' . $db->qstr($invoice->fields[' notice_count ']+1) . ' ,
notice_next_date = ' . $db->qstr(time()+86400*3) . '
WHERE
id = ' . $db->qstr( $invoice->fields[' id '] ) . ' AND
site_id = ' . $db -> qstr ( DEFAULT_SITE );
$db -> Execute ( $sql );
}
else
{
# send service cancelation notice
$email = new email_template ;
$email -> send ( 'service_suspend_user' , $invoice -> fields [ 'account_id' ], $invoice -> fields [ 'id' ], $C_list -> format_currency ( $invoice -> fields [ 'total_amt' ], $cyid ), $C_list -> date ( $invoice -> fields [ 'due_date' ]));
$email = new email_template ;
$email -> send ( 'admin->service_suspend_admin' , $invoice -> fields [ 'account_id' ], $invoice -> fields [ 'id' ], $C_list -> format_currency ( $invoice -> fields [ 'total_amt' ], '' ), $C_list -> date ( $invoice -> fields [ 'due_date' ]));
# overdue - cancel services
$vara [ 'id' ] = $invoice -> fields [ 'id' ];
$this -> voidInvoice ( $vara , $this );
# suspend billing activity
$sql = 'UPDATE ' . AGILE_DB_PREFIX . ' invoice SET
notice_count = ' . $db->qstr($invoice->fields[' notice_count ']+1) . ' ,
suspend_billing = ' . $db->qstr(' 1 ') . '
WHERE
id = ' . $db->qstr( $invoice->fields[' id '] ) . ' AND
site_id = ' . $db -> qstr ( DEFAULT_SITE );
$db -> Execute ( $sql );
}
}
else
{
# update billing stauts
$sql = 'UPDATE ' . AGILE_DB_PREFIX . ' invoice SET
notice_count = ' . $db->qstr($invoice->fields[' notice_count ']+1) . ' ,
billing_status = ' . $db->qstr(' 1 ') . ' ,
billed_amt = ' . $db->qstr($billed_amt) . ' ,
actual_billed_amt = ' . $db->qstr($actual_billed_amt) . '
WHERE
id = ' . $db->qstr( $invoice->fields[' id '] ) . ' AND
site_id = ' . $db -> qstr ( DEFAULT_SITE );
$db -> Execute ( $sql );
# update invoice via autoapproveInvoice
$this -> autoApproveInvoice ( $invoice -> fields [ 'id' ]);
# User alert of payment processed
$email = new email_template ;
$email -> send ( 'invoice_paid_user' , $invoice -> fields [ 'account_id' ], $invoice -> fields [ 'id' ], $this -> format_currency [ $cyid ][ 'iso' ], '' );
# Admin alert of payment processed
$email = new email_template ;
$email -> send ( 'admin->invoice_paid_admin' , $invoice -> fields [ 'account_id' ], $invoice -> fields [ 'id' ], $this -> format_currency [ $billed_currency_id ][ 'iso' ], '' );
}
$invoice -> MoveNext ();
unset ( $PLG );
/* finish transaction */
$db -> CompleteTrans ();
}
}
/**
* Find out if a user has unpaid invoices
*/
function has_unpaid ( $VAR ) {
if ( ! SESS_LOGGED ) return false ;
$db =& DB ();
$inv = $db -> Execute ( $sql = sqlSelect ( $db , " invoice " , " SUM(total_amt-billed_amt) as total " ,
" account_id= " . SESS_ACCOUNT . " AND billing_status=0 AND refund_status=0 " ));
if ( $inv && $inv -> RecordCount () && $inv -> fields [ 'total' ] > 0 ) {
global $smarty , $C_list ;
//$act= $db->Execute(sqlSelect($db,"account","currency_id","id=));
$smarty -> assign ( 'has_unpaid' , $C_list -> format_currency_num ( $inv -> fields [ 'total' ], SESS_CURRENCY ));
}
}
/**
* Get the totals for multiple invoices or for a group of invoices stored in temp
*/
function multiple_invoice_total ( $invoice , $account_id = SESS_ACCOUNT )
{
$db = & DB ();
if ( empty ( $invoice ) || eregi ( " , " , $invoice )) {
$id_list = '' ;
if ( ! empty ( $invoice )) {
$id = split ( ',' , $invoice );
for ( $i = 0 ; $i < count ( $id ); $i ++ ) {
if ( $id [ $i ] != '' ) {
if ( $i == 0 ) {
$id_list .= " id = " . $db -> qstr ( $id [ $i ]) . " " ;
$ii ++ ;
} else {
$id_list .= " OR id = " . $db -> qstr ( $id [ $i ]) . " " ;
$ii ++ ;
}
}
}
if ( ! empty ( $id_list )) $id_list = " ( $id_list ) AND " ;
}
// get invoice totals
$total = 0 ;
$inv = $db -> Execute ( $sql = sqlSelect ( $db , " invoice " , " id,total_amt,billed_amt " , " $id_list account_id= " . SESS_ACCOUNT . " AND billing_status=0 AND refund_status=0 " ));
if ( $inv && $inv -> RecordCount ()) {
while ( ! $inv -> EOF ) {
$this -> invoice [] = $inv -> fields [ 'id' ];
$total += ( $inv -> fields [ 'total_amt' ] - $inv -> fields [ 'billed_amt' ]);
$inv -> MoveNext ();
}
return $total ;
} else {
return false ;
}
} else {
// get total from temp data
$inv = $db -> Execute ( $sql = sqlSelect ( $db , " temporary_data " , " data,field1 as total " , " field2=:: $invoice :: " ));
if ( $inv && $inv -> RecordCount () && $inv -> fields [ 'total' ] > 0 ) {
if ( ! empty ( $inv -> fields [ 'field2' ])) $this -> invoice = unserialize ( $inv -> fields [ 'data' ]);
return $inv -> fields [ 'total' ];
} else {
return false ;
}
}
return false ;
}
/**
* Preview checkout of multiple invoices
*/
function checkout_multiple_preview ( $VAR )
{
global $smarty , $C_list ;
if ( ! SESS_LOGGED ) return false ;
$db =& DB ();
$total = $this -> multiple_invoice_total ( @ $VAR [ 'id' ], SESS_ACCOUNT );
if ( $total > 0 && count ( $this -> invoice ) > 1 )
{
// get country id for checkout options
$account = sqlSelect ( $db , " account " , " country_id " , " id= " . SESS_ACCOUNT );
// get payment options
include_once ( PATH_MODULES . 'checkout/checkout.inc.php' );
$checkout = new checkout ;
$checkoutoptions = $checkout -> get_checkout_options ( SESS_ACCOUNT , $total , false , $account -> fields [ 'country_id' ], true );
// get a temporary id (48 hours)
$id = sqlGenID ( $db , " temporary_data " );
$invoice [ " id " ] = " MULTI- $id " ;
$invoice [ " total " ] = $total ;
$fields = Array ( 'date_orig' => time (), 'date_expire' => time () + 86400 * 3 , 'field2' => $invoice [ 'id' ], 'field1' => $total , 'data' => serialize ( $this -> invoice ));
$id = & $db -> Execute ( sqlInsert ( $db , " temporary_data " , $fields ));
$smarty -> assign ( 'invoice' , $invoice );
$smarty -> assign ( 'total' , $C_list -> format_currency_num ( $total , SESS_CURRENCY ));
$smarty -> assign ( 'checkoutoptions' , $checkoutoptions );
} elseif ( count ( $this -> invoice ) == 1 ) {
$id = $this -> invoice [ 0 ];
echo " <script language=javascript>document.location.href='?_page=invoice:user_view&id= " . $id . " ';</script> " ;
} else {
echo " No due invoices selected for payment. " ;
}
}
/** Run checkout plugin for billing
*/
function checkoutnow ( $VAR )
{
global $C_translate , $smarty , $C_list , $VAR ;
# Validate user logged in:
if ( SESS_LOGGED != '1' ) {
echo '<script language="JavaScript">alert("You must be logged in to complete this purchase! Please refresh this page in your browser to login now...");</script>' ;
return false ;
}
$db = & DB ();
if ( eregi ( " MULTI- " , @ $VAR [ 'invoice_id' ])) {
// get multi-invoice details
$total = $this -> multiple_invoice_total ( @ $VAR [ 'invoice_id' ], SESS_ACCOUNT );
if ( ! $total ) return false ;
$recur_amt = false ;
$recur_arr = false ;
$account_id = SESS_ACCOUNT ;
$this -> invoice [] = $VAR [ 'invoice_id' ];
$this -> invoice_id = $VAR [ 'invoice_id' ];
$CURRENCY = DEFAULT_CURRENCY ;
$multi = true ;
} else {
# Validate the invoice selected, & get the totals:
$sql = 'SELECT * FROM ' . AGILE_DB_PREFIX . 'invoice WHERE site_id = ' . $db -> qstr ( DEFAULT_SITE ) . ' AND id = ' . $db -> qstr ( $VAR [ 'invoice_id' ]);
$result = $db -> Execute ( $sql );
if ( ! $result || $result -> RecordCount () == 0 ) return false ;
# Determine the price & currency
if ( $result -> fields [ 'billed_currency_id' ] != $result -> fields [ 'actual_billed_currency_id' ]) {
global $C_list ;
$CURRENCY = $result -> fields [ 'actual_billed_currency_id' ];
if ( $result -> fields [ 'billed_amt' ] <= 0 )
$total = $C_list -> format_currency_decimal ( $result -> fields [ 'total_amt' ], $CURRENCY );
else
$total = $C_list -> format_currency_decimal ( $result -> fields [ 'total_amt' ], $CURRENCY ) - $result -> fields [ 'actual_billed_amt' ];
} else {
$CURRENCY = $result -> fields [ 'billed_currency_id' ];
$total = $result -> fields [ 'total_amt' ] - $result -> fields [ 'billed_amt' ];
}
$recur_amt = $result -> fields [ 'recur_amt' ];
if ( $recur_amt > 0 ) $recur_amt = $C_list -> format_currency_decimal ( $recur_amt , $CURRENCY );
@ $recur_arr = unserialize ( $result -> fields [ 'recur_arr' ]);
$account_id = $result -> fields [ 'account_id' ];
$this -> invoice_id = $result -> fields [ 'id' ];
$this -> invoice [] = $result -> fields [ 'id' ];
$multi = false ;
}
$amount = round ( $total , 2 );
# Get the account details:
$sql = 'SELECT * FROM ' . AGILE_DB_PREFIX . 'account WHERE site_id = ' . $db -> qstr ( DEFAULT_SITE ) . ' AND id = ' . $db -> qstr ( $account_id );
$account = $db -> Execute ( $sql );
if ( ! $account || ! $account -> RecordCount ()) return false ;
# Validate checkout option selected is allowed for purchase:
$q = " SELECT * FROM " . AGILE_DB_PREFIX . " checkout WHERE site_id = " . $db -> qstr ( DEFAULT_SITE ) . " AND id = " . $db -> qstr ( @ $VAR [ 'option' ]) . " AND active = 1 AND " ;
if ( $recur_amt > 0 && @ $billed_amt == 0 ) $q .= " allow_recurring = 1 " ; else $q .= " allow_new = 1 " ;
$chopt = $db -> Execute ( $q );
if ( ! $chopt || ! $chopt -> RecordCount ()) return false ;
if ( $chopt && $chopt -> RecordCount ()) {
$show = true ;
if ( @ $chopt -> fields [ " total_maximum " ] != " " && $total > $chopt -> fields [ " total_maximum " ] ) $show = false ;
if ( @ $chopt -> fields [ " total_miniumum " ] != " " && $total < $chopt -> fields [ " total_miniumum " ] ) $show = false ;
}
if ( ! $show ) {
echo '<script language=Javascript> alert("Unable to checkout with the selected method, please select another."); </script> ' ;
return false ;
}
# Load the checkout plugin:
$plugin_file = PATH_PLUGINS . 'checkout/' . $chopt -> fields [ " checkout_plugin " ] . '.php' ;
include_once ( $plugin_file );
eval ( '$PLG = new plg_chout_' . $chopt -> fields [ " checkout_plugin " ] . '("' .@ $VAR [ " option " ] . '");' );
if ( ! empty ( $VAR [ 'account_billing_id' ]) && @ $VAR [ 'new_card' ] == 2 ) {
/* validate credit card on file details */
$account_billing_id = $VAR [ 'account_billing_id' ];
if ( ! $PLG -> setBillingFromDB ( $account_id , $account_billing_id , $VAR [ 'option' ])) {
global $C_debug ;
$C_debug -> alert ( " Sorry, we cannot use that billing record for this purchase. " );
return false ;
}
} else {
/* use passed in vars */
$PLG -> setBillingFromParams ( $VAR );
}
# Set Invoice Vars:
$this -> total_amt = $amount ;
$this -> currency_iso = $C_list -> currency_iso ( $CURRENCY );
$this -> currency_iso_admin = $C_list -> currency_iso ( $CURRENCY );
$this -> account_id = $account_id ;
$this -> actual_billed_currency_id = $CURRENCY ;
$this -> billed_currency_id = $CURRENCY ;
$this -> checkout_plugin_id = @ $VAR [ " option " ];
# Run the plugin bill_checkout() method:
$this -> checkout_plugin_data = $PLG -> bill_checkout ( $amount , $this -> invoice_id , $this -> currency_iso , $account -> fields , $recur_amt , $recur_arr );
# redirect
if ( ! empty ( $this -> checkout_plugin_data [ 'redirect' ])) echo $this -> checkout_plugin_data [ 'redirect' ];
# determine results
if ( $this -> checkout_plugin_data === false ) {
if ( ! empty ( $PLG -> redirect )) echo $PLG -> redirect ;
return false ;
} elseif ( $PLG -> type == " gateway " && empty ( $PLG -> redirect )) {
if ( empty ( $this -> admin_checkout )) {
$VAR [ '_page' ] = " invoice:thankyou " ;
} else {
$VAR [ '_page' ] = " invoice:view " ;
}
} elseif ( $PLG -> type == " redirect " ) {
echo " <html><head></head><body><center>
Please wait while we redirect you to the secure payment site ....
{ $PLG -> redirect } </ center ></ body ></ html > " ;
}
# Call the Plugin method for storing the checkout data, if new data entered:
$this -> account_billing_id = $PLG -> store_billing ( $VAR , $PLG );
# Load the email template module
include_once ( PATH_MODULES . 'email_template/email_template.inc.php' );
$mail = new email_template ;
# Update billing details for this invoice, if realtime billing succeeded:
if ( $PLG -> type == 'gateway' || $amount == 0 ) {
$q = " UPDATE " . AGILE_DB_PREFIX . " invoice
SET
account_billing_id = " . $db->qstr ( $this->account_billing_id ). " ,
billing_status = " . $db->qstr (1). " ,
billed_amt = " . $db->qstr ( $total ). " ,
actual_billed_amt = " . $db->qstr ( $amount ). " ,
date_last = " . $db->qstr (time()). " ,
checkout_plugin_id = " . $db->qstr ( $this->checkout_plugin_id ) . " ,
checkout_plugin_data = " . $db->qstr (serialize( $this->checkout_plugin_data )). "
WHERE
site_id = " . $db->qstr (DEFAULT_SITE). " AND
id = " . $db->qstr ( $this->invoice_id );
$rst = $db -> Execute ( $q );
if ( $rst === false ) {
global $C_debug ;
$C_debug -> error ( 'invoice.inc.php' , 'checkoutnow' , $db -> ErrorMsg ());
return false ;
}
// loop through each invoice paid
foreach ( $this -> invoice as $this -> invoice_id ) {
# Send billed e-mail notice to user
$email = new email_template ;
$email -> send ( 'invoice_paid_user' , $this -> account_id , $this -> invoice_id , $this -> currency_iso , '' );
# Admin alert of payment processed
$email = new email_template ;
$email -> send ( 'admin->invoice_paid_admin' , $this -> account_id , $this -> invoice_id , $this -> currency_iso_admin , '' );
# Submit the invoice for approval
$arr [ 'id' ] = $this -> invoice_id ;
$this -> approveInvoice ( $arr , $this );
}
} else {
# Just update the last_date and plugin data
$q = " UPDATE " . AGILE_DB_PREFIX . " invoice
SET
account_billing_id = " . $db->qstr ( $this->account_billing_id ). " ,
date_last = " . $db->qstr (time()). " ,
checkout_plugin_id = " . $db->qstr ( $this->checkout_plugin_id ) . " ,
checkout_plugin_data = " . $db->qstr (serialize( $this->checkout_plugin_data )). "
WHERE
site_id = " . $db->qstr (DEFAULT_SITE). " AND
id = " . $db->qstr ( $this->invoice_id );
$rst = $db -> Execute ( $q );
if ( $rst === false ) {
global $C_debug ;
$C_debug -> error ( 'invoice.inc.php' , 'checkoutnow' , $db -> ErrorMsg ());
return false ;
}
# Admin e-mail alert of manual payment processing
if ( $PLG -> name == 'MANUAL' ) {
$date_due = $C_list -> date ( time ());
foreach ( $this -> invoice as $this -> invoice_id ) {
$email = new email_template ;
$email -> send ( 'admin->invoice_due_admin' , $this -> account_id , $this -> invoice_id , '' , $date_due );
}
global $C_debug ;
$C_debug -> alert ( $C_translate -> translate ( 'manual_alert' , 'checkout' ));
}
}
}
/** create modified array for invoice summarization
*/
function summarizeLineItems ( $smart_items )
{
//$ignore['SKU']=true;
$sum = false ;
if ( is_array ( $smart_items )) {
foreach ( $smart_items as $it ) {
if ( empty ( $sum [ " { $it [ " sku " ] } " ])) {
// unique line item
if ( empty ( $ignore [ " { $it [ " sku " ] } " ])) $sum [ " { $it [ " sku " ] } " ][] = $it ;
} else {
// is unique price/attributes?
$unique = true ;
foreach ( $sum [ " { $it [ " sku " ] } " ] as $sid => $flds ) {
if ( $flds [ " price_base " ] == $it [ " price_base " ] && $flds [ " price_setup " ] == $it [ " price_setup " ] && $flds [ 'product_attr' ] == $it [ 'product_attr' ] ) {
$sum [ " { $it [ " sku " ] } " ][ " $sid " ][ " quantity " ] += 1 ;
$unique = false ;
break ;
}
}
// unique line item
if ( $unique ) $sum [ " { $it [ " sku " ] } " ][] = $it ;
}
}
}
if ( ! empty ( $sum )) {
unset ( $smart_items );
foreach ( $sum as $sku => $item ) foreach ( $item as $sitem ) $smart_items [] = $sitem ;
return $smart_items ;
}
}
/** VIEW
*/
function view ( $VAR )
{
global $C_translate , $C_list ;
$this -> invoice_construct ();
$type = " view " ;
$this -> method [ " $type " ] = split ( " , " , $this -> method [ " $type " ]);
$db = & DB ();
# set the field list for this method:
$arr = $this -> method [ $type ];
# loop through the field list to create the sql queries
$field_list = '' ;
$i = 0 ;
while ( list ( $key , $value ) = each ( $arr ))
{
if ( $i == 0 )
{
$field_var = $this -> table . '_' . $value ;
$field_list .= $value ;
}
else
{
$field_var = $this -> table . '_' . $value ;
$field_list .= " , " . $value ;
}
$i ++ ;
}
if ( isset ( $VAR [ " id " ]))
{
$id = split ( ',' , $VAR [ " id " ]);
for ( $i = 0 ; $i < count ( $id ); $i ++ )
{
if ( $id [ $i ] != '' )
{
if ( $i == 0 )
{
$id_list .= " id = " . $db -> qstr ( $id [ $i ]) . " " ;
$ii ++ ;
}
else
{
$id_list .= " OR id = " . $db -> qstr ( $id [ $i ]) . " " ;
$ii ++ ;
}
}
}
}
if ( $ii > 0 )
{
$any_trial = false ;
$any_recurring = false ;
$any_new = false ;
# generate the full query
$q = " SELECT
$field_list
FROM
" .AGILE_DB_PREFIX. " $this -> table
WHERE
$id_list
AND site_id = '" . DEFAULT_SITE . "'
ORDER BY $this -> order_by
LIMIT 0 , 1 " ;
$result = $db -> Execute ( $q );
if ( $result === false )
{
global $C_debug ;
$C_debug -> error ( 'invoice.inc.php' , 'view' , $db -> ErrorMsg ());
if ( isset ( $this -> trigger [ " $type " ]))
{
include_once ( PATH_CORE . 'trigger.inc.php' );
$trigger = new CORE_trigger ;
$trigger -> trigger ( $this -> trigger [ " $type " ], 0 , $VAR );
}
return ;
}
### Set it as a class variable:
$this -> result = $result ;
# put the results into a smarty accessable array
$i = 0 ;
$ii = 0 ;
$class_name = TRUE ;
while ( ! $result -> EOF )
{
$smart [ $i ] = $result -> fields ;
## get the product plugin name
if ( ! empty ( $result -> fields [ 'checkout_plugin_id' ])) {
$cplg = $db -> Execute ( sqlSelect ( $db , " checkout " , " name " , " id = { $result -> fields [ 'checkout_plugin_id' ] } " ));
if ( $cplg && $cplg -> RecordCount ()) $smart [ $i ][ 'checkout_plugin' ] = $cplg -> fields [ 'name' ];
}
if ( $result -> fields [ 'total_amt' ] == 0 )
$smart [ $i ][ 'balance' ] = 0 ;
else
$smart [ $i ][ 'balance' ] = $result -> fields [ 'total_amt' ] - $result -> fields [ 'billed_amt' ];
## Get the tax details
if ( ! empty ( $result -> fields [ 'tax_amt' ]) ) {
$trs = $db -> Execute ( $sql = sqlSelect ( $db , Array ( 'invoice_item_tax' , 'tax' ), " A.amount,B.description " , " A.tax_id=B.id AND A.invoice_id= { $result -> fields [ 'id' ] } " ));
if ( $trs && $trs -> RecordCount ()) {
while ( ! $trs -> EOF ) {
$taxes [ " { $trs -> fields [ 'description' ] } " ] += $trs -> fields [ " amount " ];
$trs -> MoveNext ();
}
foreach ( $taxes as $txds => $txamt )
$smart [ $i ][ " tax_arr " ][] = Array ( 'description' => $txds , 'amount' => $txamt );
}
}
## Get the discount details
if ( ! empty ( $result -> fields [ 'discount_amt' ]) ) {
$drs = $db -> Execute ( $sql = sqlSelect ( $db , 'invoice_item_discount' , " amount,discount " , " invoice_id= { $result -> fields [ 'id' ] } " ));
if ( $drs && $drs -> RecordCount ()) {
while ( ! $drs -> EOF ) {
$discounts [ " { $drs -> fields [ 'discount' ] } " ] += $drs -> fields [ " amount " ];
$drs -> MoveNext ();
}
$dhtml = '' ;
foreach ( $discounts as $dsds => $dsamt ) $dhtml .= '<a href=\'?_page=core:search&module=discount&discount_name=' . $dsds . '\'>' . $dsds . '</a> - ' . number_format ( $dsamt , 2 ) . " <br> " ;
$smart [ $i ][ 'discount_popup' ] = $dhtml ;
$dhtml = '' ;
foreach ( $discounts as $dsds => $dsamt ) $dhtml .= $dsds . ' - ' . number_format ( $dsamt , 2 ) . " <br> " ;
$smart [ $i ][ 'discount_popup_user' ] = $dhtml ;
}
}
## Get the checkout plugin details:
if ( ! empty ( $result -> fields [ 'checkout_plugin_data' ])) {
$plugin_data = unserialize ( $result -> fields [ 'checkout_plugin_data' ]);
if ( is_array ( $plugin_data )) {
$smart [ $i ][ 'checkout_plugin_data' ] = $plugin_data ;
} else {
$smart [ $i ][ 'checkout_plugin_data' ] = Array ( 0 => $result -> fields [ 'checkout_plugin_data' ]);
}
}
## Get the line items:
$q = " SELECT * FROM " . AGILE_DB_PREFIX . " invoice_item WHERE
invoice_id = " . $db->qstr ( $result->fields ['id']). " AND
site_id = " . $db->qstr (DEFAULT_SITE);
if ( $C_list -> is_installed ( 'voip' )) {
$q .= " AND item_type!=5 " ;
}
$items = $db -> Execute ( $q );
if ( $items === false ) {
global $C_debug ;
$C_debug -> error ( 'invoice.inc.php' , 'view' , $db -> ErrorMsg ());
return false ;
}
$ii = 0 ;
while ( ! $items -> EOF )
{
$smart_items [ $ii ] = $items -> fields ;
// get the product attribs
if ( ! empty ( $items -> fields [ 'product_attr' ]))
{
@ $attrib = explode ( " \r \n " , $items -> fields [ 'product_attr' ]);
$js = '' ;
for ( $attr_i = 0 ; $attr_i < count ( $attrib ); $attr_i ++ )
{
$attributei = explode ( '==' , $attrib [ $attr_i ]);
if ( ! empty ( $attributei [ 0 ]) && ! empty ( $attributei [ 1 ])) {
$js .= " <u> " . $attributei [ 0 ] . " </u> : " . $attributei [ 1 ] . " <BR> " ;
}
}
$smart_items [ $ii ][ 'attribute_popup' ] = $js ;
}
// get the date range if set
if ( ! empty ( $items -> fields [ 'date_start' ]) && ! empty ( $items -> fields [ 'date_stop' ]))
{
$C_translate -> value ( 'invoice' , 'start' , date ( UNIX_DATE_FORMAT , $items -> fields [ 'date_start' ]));
$C_translate -> value ( 'invoice' , 'stop' , date ( UNIX_DATE_FORMAT , $items -> fields [ 'date_stop' ]));
$smart_items [ $ii ][ 'range' ] = $C_translate -> translate ( 'recur_date_range' , 'invoice' , '' );
}
// Set charge type for payment option list:
$any_new = true ;
if ( $items -> fields [ " price_type " ] == '1' && ! empty ( $result -> fields [ 'recurr_arr' ]) && is_array ( unserialize ( $result -> fields [ 'recurr_arr' ])))
$any_recurring = true ;
$items -> MoveNext ();
$ii ++ ;
}
## Create a summary (for duplicate skus w/identical price,and attributes, roll into a single value
if ( $this -> summarizeInvoice ) {
$tmp = $smart_items ;
unset ( $smart_items );
$smart_items = $this -> summarizeLineItems ( $tmp );
}
### GET THE CHECKOUT (PAYMENT) OPTIONS
if ( $VAR [ '_page' ] != 'invoice:view' )
{
# get the converted amount due:
if ( $result -> fields [ 'billed_currency_id' ] != $result -> fields [ 'actual_billed_currency_id' ])
{
global $C_list ;
$CURRENCY = $result -> fields [ 'actual_billed_currency_id' ];
if ( $result -> fields [ 'billed_amt' ] <= 0 )
$total = $C_list -> format_currency_decimal ( $result -> fields [ 'total_amt' ], $CURRENCY );
else
$total = $C_list -> format_currency_decimal ( $result -> fields [ 'total_amt' ], $CURRENCY ) - $result -> fields [ 'actual_billed_amt' ];
} else {
$CURRENCY = $result -> fields [ 'billed_currency_id' ];
$total = $result -> fields [ 'total_amt' ] - $result -> fields [ 'billed_amt' ];
}
$q = " SELECT * FROM " . AGILE_DB_PREFIX . " checkout WHERE site_id = " . DEFAULT_SITE . " AND active = 1 " ;
if ( $any_trial ) $q .= " AND allow_trial = " . $db -> qstr ( '1' );
if ( $any_recurring ) $q .= " AND allow_recurring = " . $db -> qstr ( '1' );
if ( $any_new ) $q .= " AND allow_new = " . $db -> qstr ( '1' );
$chopt = $db -> Execute ( $q );
if ( $chopt === false ) {
global $C_debug ;
$C_debug -> error ( 'invoice.inc.php' , 'view' , $db -> ErrorMsg ());
return false ;
}
if ( $chopt != false && $chopt -> RecordCount () > 0 ) {
while ( ! $chopt -> EOF ) {
$show = true ;
# Check that the cart total is not to high:
if ( $chopt -> fields [ " total_maximum " ] != " " &&
$result -> fields [ 'total_amt' ] >= $chopt -> fields [ " total_maximum " ] ) {
$show = false ;
}
# Check that the cart total is not to low:
if ( $chopt -> fields [ " total_miniumum " ] != " " &&
$result -> fields [ 'total_amt' ] <= $chopt -> fields [ " total_miniumum " ] ) {
$show = false ;
}
# Check that the group requirement is met:
if ( $show && ! empty ( $chopt -> fields [ " required_groups " ] ) ) {
global $C_auth ;
$arr = unserialize ( $chopt -> fields [ " required_groups " ] );
if ( count ( $arr ) > 0 && ! empty ( $arr [ 0 ])) $show = false ;
for ( $i = 0 ; $i < count ( $arr ); $i ++ ) {
if ( $C_auth -> auth_group_by_id ( $arr [ $i ])) {
$show = true ;
$i = count ( $arr );
}
}
}
# Check that the customer is not ordering a blocked SKU:
if ( $show && ! empty ( $chopt -> fields [ " excluded_products " ] ) ) {
$arr = unserialize ( $chopt -> fields [ " excluded_products " ] );
if ( count ( $arr ) > 0 ) {
for ( $i = 0 ; $i < count ( $smart_items ); $i ++ ) {
for ( $isk = 0 ; $isk < count ( $arr ); $isk ++ ) {
if ( $smart_items [ $i ][ 'product_id' ] == $arr [ $isk ] && ! empty ( $arr [ $isk ]) && ! empty ( $smart_items [ $i ][ 'product_id' ]) ) {
$show = false ;
$i = count ( $smart );
$isk = count ( $arr );
}
}
}
}
}
$list_ord = 100 ;
if ( $show ) {
# Check if this method should be the default method:
# By Amount:
if ( ! empty ( $chopt -> fields [ " default_when_amount " ] ) ) {
$arr = unserialize ( $chopt -> fields [ " default_when_amount " ] );
for ( $idx = 0 ; $idx < count ( $arr ); $idx ++ ) {
if ( $total >= $arr [ $idx ] ) $list_ord -- ;
$idx = count ( $arr );
}
}
# By Currency
if ( ! empty ( $chopt -> fields [ " default_when_currency " ] ) ) {
$arr = unserialize ( $chopt -> fields [ " default_when_currency " ] );
for ( $idx = 0 ; $idx < count ( $arr ); $idx ++ ) {
if ( $CURRENCY == $arr [ $idx ] ) $list_ord -- ;
$idx = count ( $arr );
}
}
# By Group
if ( ! empty ( $chopt -> fields [ " default_when_group " ] ) ) {
$arr = unserialize ( $chopt -> fields [ " default_when_group " ] );
global $C_auth ;
for ( $idx = 0 ; $idx < count ( $arr ); $idx ++ ) {
if ( $C_auth -> auth_group_by_id ( $arr [ $idx ] ) ) $list_ord -- ;
$idx = count ( $arr );
}
}
# By Country
if ( ! empty ( $chopt -> fields [ " default_when_country " ] ) ) {
$arr = unserialize ( $chopt -> fields [ " default_when_country " ] );
for ( $idx = 0 ; $idx < count ( $arr ); $idx ++ ) {
if ( $account -> fields [ " country_id " ] == $arr [ $idx ] ) $list_ord -- ;
$idx = count ( $arr );
}
}
# Add to the array
$checkout_optionsx [] = Array ( 'sort' => $list_ord ,
'fields' => $chopt -> fields );
}
$chopt -> MoveNext ();
}
# Sort the checkout_options array by the [fields] element
if ( count ( $checkout_optionsx ) > 0 ) {
foreach ( $checkout_optionsx as $key => $row )
$sort [ $key ] = $row [ " sort " ];
array_multisort ( $sort , SORT_ASC , $checkout_optionsx );
}
}
}
$result -> MoveNext ();
$i ++ ;
}
# get the result count:
$results = $result -> RecordCount ();
### No results:
if ( $result -> RecordCount () == 0 )
{
global $C_debug ;
$C_debug -> error ( " CORE:database.inc.php " , " view() " , " The selected record does not
exist any longer , or your account is not authorized to view it " );
return ;
}
# define the DB vars as a Smarty accessible block
global $smarty ;
# define the results
$smarty -> assign ( 'cart' , $smart_items );
$smarty -> assign ( $this -> table , $smart );
#$smarty->assign('results', $search->results);
$smarty -> assign ( 'checkoutoptions' , $checkout_optionsx );
}
}
/** UPDATE
*/
function update ( $VAR )
{
$this -> invoice_construct ();
$type = " update " ;
$this -> method [ " $type " ] = split ( " , " , $this -> method [ " $type " ]);
$db = new CORE_database ;
$db -> update ( $VAR , $this , $type );
}
/** DELETE
*/
function delete ( $VAR )
{
$this -> invoice_construct ();
$dbx = new CORE_database ;
$db = & DB ();
### Get the array
if ( isset ( $VAR [ " delete_id " ]))
$id = split ( ',' , $VAR [ " delete_id " ]);
elseif ( isset ( $VAR [ " id " ]))
$id = split ( ',' , $VAR [ " id " ]);
### Load the service module
include_once ( PATH_MODULES . 'service/service.inc.php' );
$service = new service ;
### Loop:
for ( $i = 0 ; $i < count ( $id ); $i ++ )
{
### Loop through all services for this invoice and delete:
$q = " SELECT * FROM " . AGILE_DB_PREFIX . " service WHERE
invoice_id = " . $db->qstr ( $id[$i] ). " AND
site_id = " . $db->qstr (DEFAULT_SITE);;
$rs = $db -> Execute ( $q );
if ( $rs === false ) {
global $C_debug ;
$C_debug -> error ( 'invoice.inc.php' , 'delete' , $db -> ErrorMsg ());
return false ;
}
if ( @ $rs -> RecordCount () > 0 ) {
while ( ! $rs -> EOF ) {
$arr [ 'id' ] = $rs -> fields [ 'id' ];
$service -> delete ( $arr , $service );
$rs -> MoveNext ();
}
}
### Delete the service record
$arr [ 'id' ] = $id [ $i ];
$this -> associated_DELETE [] = Array ( 'table' => 'invoice_commission' , 'field' => 'invoice_id' );
$this -> associated_DELETE [] = Array ( 'table' => 'invoice_item' , 'field' => 'invoice_id' );
$this -> associated_DELETE [] = Array ( 'table' => 'invoice_memo' , 'field' => 'invoice_id' );
$this -> associated_DELETE [] = Array ( 'table' => 'service' , 'field' => 'invoice_id' );
$this -> associated_DELETE [] = Array ( 'table' => 'invoice_item_tax' , 'field' => 'invoice_id' );
$this -> associated_DELETE [] = Array ( 'table' => 'invoice_item_discount' , 'field' => 'invoice_id' );
$dbx -> mass_delete ( $arr , $this , " " );
}
}
/** SEARCH FORM
*/
function search_form ( $VAR )
{
$this -> invoice_construct ();
$type = " search " ;
$this -> method [ " $type " ] = split ( " , " , $this -> method [ " $type " ]);
$db = new CORE_database ;
$db -> search_form ( $VAR , $this , $type );
}
/** SEARCH
*/
function search ( $VAR )
{
$this -> invoice_construct ();
$type = " search " ;
$this -> method [ " $type " ] = split ( " , " , $this -> method [ " $type " ]);
$db = & DB ();
include_once ( PATH_CORE . 'validate.inc.php' );
$validate = new CORE_validate ;
# set the search criteria array
$arr = $VAR ;
# convert invoice_discount_arr
if ( ! empty ( $VAR [ 'invoice_discount_arr' ]))
$arr [ 'invoice_discount_arr' ] = '%"' . $VAR [ 'invoice_discount_arr' ] . '"%' ;
# loop through the submitted field_names to get the WHERE statement
$where_list = '' ;
$i = 0 ;
while ( list ( $key , $value ) = each ( $arr ))
{
if ( $i == 0 )
{
if ( $value != '' )
{
$pat = " ^ " . $this -> module . " _ " ;
if ( eregi ( $pat , $key ))
{
$field = eregi_replace ( $pat , " " , $key );
if ( eregi ( '%' , $value ))
{
# do any data conversion for this field (date, encrypt, etc...)
if ( isset ( $this -> field [ " $field " ][ " convert " ]) && $this -> field [ " $field " ][ " convert " ] != 'array' )
{
$value = $validate -> convert ( $field , $value , $this -> field [ " $field " ][ " convert " ]);
}
$where_list .= " WHERE " . AGILE_DB_PREFIX . " invoice. " . $field . " LIKE " . $db -> qstr ( $value , get_magic_quotes_gpc ());
$i ++ ;
}
else
{
# check if array
if ( is_array ( $value ))
{
for ( $i_arr = 0 ; $i_arr < count ( $value ); $i_arr ++ )
{
if ( $value [ " $i_arr " ] != '' )
{
# determine any field options (=, >, <, etc...)
$f_opt = '=' ;
$pat_field = $this -> module . '_' . $field ;
$VAR [ 'field_option' ][ " $pat_field " ][ " $i_arr " ];
if ( isset ( $VAR [ 'field_option' ][ " $pat_field " ][ " $i_arr " ]))
{
$f_opt = $VAR [ 'field_option' ][ " $pat_field " ][ " $i_arr " ];
# error checking, safety precaution
if ( $f_opt != '=' && $f_opt != '>' && $f_opt != '<' && $f_opt != '>=' && $f_opt != '<=' && $f_opt != '!=' )
$f_opt = '=' ;
}
# do any data conversion for this field (date, encrypt, etc...)
if ( isset ( $this -> field [ " $field " ][ " convert " ]) && $this -> field [ " $field " ][ " convert " ] != 'array' )
{
$value [ " $i_arr " ] = $validate -> convert ( $field , $value [ " $i_arr " ], $this -> field [ " $field " ][ " convert " ]);
}
if ( $i_arr == 0 )
{
$where_list .= " WHERE " . AGILE_DB_PREFIX . " invoice. " . $field . " $f_opt " . $db -> qstr ( $value [ " $i_arr " ], get_magic_quotes_gpc ());
$i ++ ;
}
else
{
$where_list .= " AND " . AGILE_DB_PREFIX . " invoice. " . $field . " $f_opt " . $db -> qstr ( $value [ " $i_arr " ], get_magic_quotes_gpc ());
$i ++ ;
}
}
}
}
else
{
$where_list .= " WHERE " . AGILE_DB_PREFIX . " invoice. " . $field . " = " . $db -> qstr ( $value , get_magic_quotes_gpc ());
$i ++ ;
}
}
}
}
}
else
{
if ( $value != '' )
{
$pat = " ^ " . $this -> module . " _ " ;
if ( eregi ( $pat , $key ))
{
$field = eregi_replace ( $pat , " " , $key );
if ( eregi ( '%' , $value ))
{
# do any data conversion for this field (date, encrypt, etc...)
if ( isset ( $this -> field [ " $field " ][ " convert " ]) && $this -> field [ " $field " ][ " convert " ] != 'array' )
{
$value = $validate -> convert ( $field , $value , $this -> field [ " $field " ][ " convert " ]);
}
$where_list .= " AND " . AGILE_DB_PREFIX . " invoice. " . $field . " LIKE " . $db -> qstr ( $value , get_magic_quotes_gpc ());
$i ++ ;
}
else
{
# check if array
if ( is_array ( $value ))
{
for ( $i_arr = 0 ; $i_arr < count ( $value ); $i_arr ++ )
{
if ( $value [ " $i_arr " ] != '' )
{
# determine any field options (=, >, <, etc...)
$f_opt = '=' ;
$pat_field = $this -> module . '_' . $field ;
if ( isset ( $VAR [ 'field_option' ][ " $pat_field " ][ " $i_arr " ]))
{
$f_opt = $VAR [ 'field_option' ][ " $pat_field " ][ " $i_arr " ];
# error checking, safety precaution
if ( $f_opt != '=' && $f_opt != '>' && $f_opt != '<' && $f_opt != '>=' && $f_opt != '<=' && $f_opt != '!=' )
$f_opt = '=' ;
}
# do any data conversion for this field (date, encrypt, etc...)
if ( isset ( $this -> field [ " $field " ][ " convert " ]) && $this -> field [ " $field " ][ " convert " ] != 'array' )
{
$value [ " $i_arr " ] = $validate -> convert ( $field , $value [ " $i_arr " ], $this -> field [ " $field " ][ " convert " ]);
}
$where_list .= " AND " . AGILE_DB_PREFIX . " invoice. " . $field . " $f_opt " . $db -> qstr ( $value [ " $i_arr " ], get_magic_quotes_gpc ());
$i ++ ;
}
}
}
else
{
$where_list .= " AND " . AGILE_DB_PREFIX . " invoice. " . $field . " = " . $db -> qstr ( $value , get_magic_quotes_gpc ());
$i ++ ;
}
}
}
}
}
}
# Code for attribute searches:
if ( ! empty ( $VAR [ 'join_product_id' ]) && ! empty ( $VAR [ 'item_attributes' ]))
{
$attr_arr = $VAR [ 'item_attributes' ];
for ( $ati = 0 ; $ati < count ( $attr_arr ); $ati ++ )
{
if ( ! empty ( $attr_arr [ $ati ][ '0' ]))
{
if ( $where_list == '' )
$where_list .= ' WHERE ' ;
else
$where_list .= ' AND ' ;
$where_list .= AGILE_DB_PREFIX . " invoice_item.product_attr LIKE " .
$db -> qstr ( " % { $attr_arr [ $ati ][ '0' ] } == { $attr_arr [ $ati ][ '1' ] } % " );
}
}
}
# get limit type
if ( isset ( $VAR [ 'limit' ]))
{
$limit = $VAR [ 'limit' ];
}
else
{
$limit = $this -> limit ;
}
# get order by
if ( isset ( $VAR [ 'order_by' ]))
{
$order_by = $VAR [ 'order_by' ];
}
else
{
$order_by = $this -> order_by ;
}
## SELECT FROM
$p = AGILE_DB_PREFIX ;
$q = " SELECT DISTINCT { $p } invoice.id FROM " . AGILE_DB_PREFIX . " invoice " ;
$q_save = " SELECT DISTINCT %%fieldList%%, { $p } invoice.id FROM { $p } invoice " ;
## LEFT JOIN
if ( ! empty ( $VAR [ 'join_product_id' ]) || ! empty ( $VAR [ 'join_service_id' ]) ||
! empty ( $VAR [ 'join_domain_name' ]) || ! empty ( $VAR [ 'join_domain_tld' ]) ||
! empty ( $VAR [ 'join_memo_text' ]) )
{
# JOIN ON PRODUCT DETAILS:
if ( ! empty ( $VAR [ 'join_product_id' ]) || ! empty ( $VAR [ 'join_service_id' ]) || ! empty ( $VAR [ 'join_domain_name' ]) || ! empty ( $VAR [ 'join_domain_tld' ]))
{
$q .= " LEFT JOIN { $p } invoice_item ON { $p } invoice_item.invoice_id = { $p } invoice.id " ;
$q_save .= " LEFT JOIN { $p } invoice_item ON { $p } invoice_item.invoice_id = { $p } invoice.id " ;
if ( $where_list == '' ) {
$q .= " WHERE { $p } invoice_item.site_id = " . $db -> qstr ( DEFAULT_SITE );
$q_save .= " WHERE { $p } invoice_item.site_id = " . $db -> qstr ( DEFAULT_SITE );
} else {
$q .= $where_list . " AND { $p } invoice_item.site_id = " . $db -> qstr ( DEFAULT_SITE );
$q_save .= $where_list . " AND { $p } invoice_item.site_id = " . $db -> qstr ( DEFAULT_SITE );
}
# AND (invoice_item.product_id)
if ( ! empty ( $VAR [ 'join_product_id' ])) {
$q .= " AND { $p } invoice_item.product_id = " . $db -> qstr ( $VAR [ 'join_product_id' ]);
$q_save .= " AND { $p } invoice_item.product_id = " . $db -> qstr ( $VAR [ 'join_product_id' ]);
}
# AND (invoice_item.service_id)
if ( ! empty ( $VAR [ 'join_service_id' ])) {
$q .= " AND { $p } invoice_item.service_id = " . $db -> qstr ( $VAR [ 'join_service_id' ]);
$q_save .= " AND { $p } invoice_item.service_id = " . $db -> qstr ( $VAR [ 'join_service_id' ]);
}
# AND (invoice_item.domain_name)
if ( ! empty ( $VAR [ 'join_domain_name' ])) {
if ( ! ereg ( '%' , $VAR [ 'join_domain_name' ]) ) $qtype = ' = ' ; else $qtype = ' LIKE ' ;
$q .= " AND { $p } invoice_item.domain_name $qtype " . $db -> qstr ( $VAR [ 'join_domain_name' ]);
$q_save .= " AND { $p } invoice_item.domain_name $qtype " . $db -> qstr ( $VAR [ 'join_domain_name' ]);
}
# AND (invoice_item.domain_tld)
if ( ! empty ( $VAR [ 'join_domain_tld' ])) {
if ( ! ereg ( '%' , $VAR [ 'join_domain_tld' ]) ) $qtype = ' = ' ; else $qtype = ' LIKE ' ;
$q .= " AND { $p } invoice_item.domain_tld $qtype " . $db -> qstr ( $VAR [ 'join_domain_tld' ]);
$q_save .= " AND { $p } invoice_item.domain_tld $qtype " . $db -> qstr ( $VAR [ 'join_domain_tld' ]);
}
}
# JOIN ON MEMO TEXT:
if ( ! empty ( $VAR [ 'join_memo_text' ]))
{
$q .= " LEFT JOIN { $p } invoice_memo ON { $p } invoice_memo.invoice_id = { $p } invoice.id " ;
$q_save .= " LEFT JOIN { $p } invoice_memo ON { $p } invoice_memo.invoice_id = { $p } invoice.id " ;
if ( $where_list == '' ) {
$q .= " WHERE { $p } invoice_memo.site_id = " . $db -> qstr ( DEFAULT_SITE );
$q_save .= " WHERE { $p } invoice_memo.site_id = " . $db -> qstr ( DEFAULT_SITE );
} else {
$q .= $where_list . " AND { $p } invoice_memo.site_id = " . $db -> qstr ( DEFAULT_SITE );
$q_save .= $where_list . " AND { $p } invoice_memo.site_id = " . $db -> qstr ( DEFAULT_SITE );
}
$q .= " AND { $p } invoice_memo.memo LIKE " . $db -> qstr ( '%' . $VAR [ 'join_memo_text' ] . '%' );
$q_save .= " AND { $p } invoice_memo.memo LIKE " . $db -> qstr ( '%' . $VAR [ 'join_memo_text' ] . '%' );
}
$q .= " AND { $p } invoice.site_id = " . DEFAULT_SITE ;
$q_save .= ' AND ' ;
}
else
{
if ( $where_list == '' ) {
$q .= " WHERE { $p } invoice.site_id = " . DEFAULT_SITE ;
$q_save .= ' WHERE ' ;
}
else
{
$q .= $where_list . " AND { $p } invoice.site_id = " . DEFAULT_SITE ;
$q_save .= $where_list . ' AND ' ;
}
}
///////////////// debug
#echo $q;
#exit;
# run the database query
$result = $db -> Execute ( $q );
# error reporting
if ( $result === false )
{
global $C_debug ;
$C_debug -> error ( 'invoice.inc.php' , 'search' , $db -> ErrorMsg ());
return false ;
}
# get the result count:
$results = $result -> RecordCount ();
# get the first record id:
if ( $results == 1 ) $record_id = $result -> fields [ 'id' ];
# define the DB vars as a Smarty accessible block
global $smarty ;
# Create the definition for fast-forwarding to a single record:
if ( $results == 1 && ! isset ( $this -> fast_forward ))
{
$smarty -> assign ( 'record_id' , $record_id );
}
# create the search record:
if ( $results > 0 )
{
# create the search record
include_once ( PATH_CORE . 'search.inc.php' );
$search = new CORE_search ;
$arr [ 'module' ] = $this -> module ;
$arr [ 'sql' ] = $q_save ;
$arr [ 'limit' ] = $limit ;
$arr [ 'order_by' ] = $order_by ;
$arr [ 'results' ] = $results ;
$search -> add ( $arr );
# define the search id and other parameters for Smarty
$smarty -> assign ( 'search_id' , $search -> id );
# page:
$smarty -> assign ( 'page' , '1' );
# limit:
$smarty -> assign ( 'limit' , $limit );
# order_by:
$smarty -> assign ( 'order_by' , $order_by );
}
# define the result count
$smarty -> assign ( 'results' , $results );
}
/** SEARCH SHOW
*/
function search_show ( $VAR )
{
$this -> invoice_construct ();
$type = " search " ;
$this -> method [ " $type " ] = split ( " , " , $this -> method [ " $type " ]);
# set the field list for this method:
$arr = $this -> method [ $type ];
$field_list = '' ;
$i = 0 ;
while ( list ( $key , $value ) = each ( $arr ))
{
if ( $i == 0 )
{
$field_var = $this -> table . '_' . $value ;
$field_list .= AGILE_DB_PREFIX . " invoice " . " . " . $value ;
// determine if this record is linked to another table/field
if ( $this -> field [ $value ][ " asso_table " ] != " " )
{
$this -> linked [] = array ( 'field' => $value , 'link_table' => $this -> field [ $value ][ " asso_table " ], 'link_field' => $this -> field [ $value ][ " asso_field " ]);
}
}
else
{
$field_var = $this -> table . '_' . $value ;
$field_list .= " , " . AGILE_DB_PREFIX . " invoice " . " . " . $value ;
// determine if this record is linked to another table/field
if ( $this -> field [ $value ][ " asso_table " ] != " " )
{
$this -> linked [] = array ( 'field' => $value , 'link_table' => $this -> field [ $value ][ " asso_table " ], 'link_field' => $this -> field [ $value ][ " asso_field " ]);
}
}
$i ++ ;
}
# get the search details:
if ( isset ( $VAR [ 'search_id' ])) {
include_once ( PATH_CORE . 'search.inc.php' );
$search = new CORE_search ;
$search -> get ( $VAR [ 'search_id' ]);
} else {
# invalid search!
echo '<BR> The search terms submitted were invalid!' ; # translate... # alert
if ( isset ( $this -> trigger [ " $type " ])) {
include_once ( PATH_CORE . 'trigger.inc.php' );
$trigger = new CORE_trigger ;
$trigger -> trigger ( $this -> trigger [ " $type " ], 0 , $VAR );
}
}
# get the sort order details:
if ( isset ( $VAR [ 'order_by' ]) && $VAR [ 'order_by' ] != " " ) {
$order_by = ' ORDER BY ' . $VAR [ 'order_by' ];
$smarty_order = $VAR [ 'order_by' ];
} else {
$order_by = ' ORDER BY ' . $this -> order_by ;
$smarty_order = $search -> order_by ;
}
# determine the sort order
if ( isset ( $VAR [ 'desc' ])) {
$order_by .= ' DESC' ;
$smarty_sort = 'desc=' ;
} else if ( isset ( $VAR [ 'asc' ])) {
$order_by .= ' ASC' ;
$smarty_sort = 'asc=' ;
} else {
if ( ! eregi ( 'date' , $smarty_order )) {
$order_by .= ' ASC' ;
$smarty_sort = 'asc=' ;
} else {
$order_by .= ' DESC' ;
$smarty_sort = 'desc=' ;
}
}
# determine the offset & limit
$current_page = 1 ;
$offset =- 1 ;
if ( ! empty ( $VAR [ 'page' ])) $current_page = $VAR [ 'page' ];
if ( empty ( $search -> limit )) $search -> limit = 25 ;
if ( $current_page > 1 ) $offset = (( $current_page * $search -> limit ) - $search -> limit );
# generate the full query
$db = & DB ();
$q = eregi_replace ( " %%fieldList%% " , $field_list , $search -> sql );
$q = eregi_replace ( " %%tableList%% " , AGILE_DB_PREFIX . $construct -> table , $q );
$q = eregi_replace ( " %%whereList%% " , " " , $q );
$q .= " " . AGILE_DB_PREFIX . " invoice.site_id = ' " . DEFAULT_SITE . " ' " ;
$q .= $order_by ;
//////////////////
#echo "<BR> $q <BR>";
$result = $db -> SelectLimit ( $q , $search -> limit , $offset );
# error reporting
if ( $result === false )
{
global $C_debug ;
$C_debug -> error ( 'invoice.inc.php' , 'search' , $db -> ErrorMsg ());
if ( isset ( $this -> trigger [ " $type " ]))
{
include_once ( PATH_CORE . 'trigger.inc.php' );
$trigger = new CORE_trigger ;
$trigger -> trigger ( $this -> trigger [ " $type " ], 0 , $VAR );
}
return ;
}
# put the results into a smarty accessable array
$i = 0 ;
$class_name = TRUE ;
while ( ! $result -> EOF ) {
$smart [ $i ] = $result -> fields ;
$amount += $result -> fields [ 'total_amt' ];
if ( $class_name )
{
$smart [ $i ][ '_C' ] = 'row1' ;
$class_name = FALSE ;
} else {
$smart [ $i ][ '_C' ] = 'row2' ;
$class_name = TRUE ;
}
$result -> MoveNext ();
$i ++ ;
}
# get any linked fields
if ( $i > 0 )
{
$db_join = new CORE_database ;
$this -> result = $db_join -> join_fields ( $smart , $this -> linked );
}
else
{
$this -> result = $smart ;
}
# get the result count:
$results = $result -> RecordCount ();
# define the DB vars as a Smarty accessible block
global $smarty ;
# define the results
$smarty -> assign ( $this -> table , $this -> result );
$smarty -> assign ( 'page' , $VAR [ 'page' ]);
$smarty -> assign ( 'order' , $smarty_order );
$smarty -> assign ( 'sort' , $smarty_sort );
$smarty -> assign ( 'limit' , $search -> limit );
$smarty -> assign ( 'search_id' , $search -> id );
$smarty -> assign ( 'results' , $search -> results );
global $C_list ;
$smarty -> assign ( 'total_amount' , $C_list -> format_currency ( $amount , DEFAULT_CURRENCY ));
# get the total pages for this search:
if ( empty ( $search -> limit ))
$this -> pages = 1 ;
else
$this -> pages = intval ( $search -> results / $search -> limit );
if ( $search -> results % $search -> limit ) $this -> pages ++ ;
# total pages
$smarty -> assign ( 'pages' , $this -> pages );
# current page
$smarty -> assign ( 'page' , $current_page );
$page_arr = '' ;
for ( $i = 0 ; $i <= $this -> pages ; $i ++ )
{
if ( $this -> page != $i ) $page_arr [] = $i ;
}
# page array for menu
$smarty -> assign ( 'page_arr' , $page_arr );
}
/** USER SEARCH
*/
function user_search ( $VAR )
{
if ( ! SESS_LOGGED ) return false ;
$VAR [ 'invoice_account_id' ] = SESS_ACCOUNT ;
$this -> invoice_construct ();
$type = " search " ;
$this -> method [ " $type " ] = split ( " , " , $this -> method [ " $type " ]);
$db = new CORE_database ;
$db -> search ( $VAR , $this , $type );
}
/** USER SEARCH SHOW
*/
function user_search_show ( $VAR )
{
if ( ! SESS_LOGGED ) return false ;
$this -> invoice_construct ();
$type = " search " ;
$this -> method [ " $type " ] = split ( " , " , $this -> method [ " $type " ]);
$db = new CORE_database ;
$db -> search_show ( $VAR , $this , $type );
}
/** USER VIEW
*/
function user_view ( $VAR )
{
global $C_auth ;
if ( ! SESS_LOGGED ) return false ;
// verify the account_id for this order is the SESS_ACCOUNT
if ( $C_auth -> auth_method_by_name ( 'invoice' , 'view' ) == false )
{
$id = split ( ',' , $VAR [ 'id' ]);
$db = & DB ();
$q = " SELECT account_id FROM " . AGILE_DB_PREFIX . " invoice WHERE
id = " . $db->qstr ( $id[0] ). " AND
site_id = " . $db->qstr (DEFAULT_SITE);
$rs = $db -> Execute ( $q );
if ( $rs === false ) {
global $C_debug ;
$C_debug -> error ( 'invoice.inc.php' , 'user_view' , $db -> ErrorMsg ());
return false ;
}
if ( $rs -> fields [ 'account_id' ] != SESS_ACCOUNT ) return false ;
}
$this -> view ( $VAR , $this );
}
/** SEARCH EXPORT
*/
function search_export ( $VAR )
{
$this -> invoice_construct ();
# require the export class
require_once ( PATH_CORE . " export.inc.php " );
# Call the correct export function for inline browser display, download, email, or web save.
if ( $VAR [ " format " ] == " excel " )
{
$type = " export_excel " ;
$this -> method [ " $type " ] = split ( " , " , $this -> method [ " $type " ]);
$export = new CORE_export ;
$export -> search_excel ( $VAR , $this , $type );
}
else if ( $VAR [ " format " ] == " pdf " )
{
$type = " export_pdf " ;
$this -> method [ " $type " ] = split ( " , " , $this -> method [ " $type " ]);
$export = new CORE_export ;
$export -> pdf_invoice ( $VAR , $this , $type );
}
else if ( $VAR [ " format " ] == " xml " )
{
$type = " export_xml " ;
$this -> method [ " $type " ] = split ( " , " , $this -> method [ " $type " ]);
$export = new CORE_export ;
$export -> search_xml ( $VAR , $this , $type );
}
else if ( $VAR [ " format " ] == " csv " )
{
$type = " export_csv " ;
$this -> method [ " $type " ] = split ( " , " , $this -> method [ " $type " ]);
$export = new CORE_export ;
$export -> search_csv ( $VAR , $this , $type );
}
else if ( $VAR [ " format " ] == " tab " )
{
$type = " export_tab " ;
$this -> method [ " $type " ] = split ( " , " , $this -> method [ " $type " ]);
$export = new CORE_export ;
$export -> search_tab ( $VAR , $this , $type );
}
}
function invoice_construct ()
{
$this -> module = " invoice " ;
$this -> xml_construct = PATH_MODULES . " " . $this -> module . " / " . $this -> module . " _construct.xml " ;
include_once ( PATH_CORE . 'xml.inc.php' );
$C_xml = new CORE_xml ;
$construct = $C_xml -> xml_to_array ( $this -> xml_construct );
$this -> method = $construct [ " construct " ][ " method " ];
$this -> trigger = $construct [ " construct " ][ " trigger " ];
$this -> field = $construct [ " construct " ][ " field " ];
$this -> table = $construct [ " construct " ][ " table " ];
$this -> module = $construct [ " construct " ][ " module " ];
$this -> cache = $construct [ " construct " ][ " cache " ];
$this -> order_by = $construct [ " construct " ][ " order_by " ];
$this -> limit = $construct [ " construct " ][ " limit " ];
}
}
2009-01-05 00:22:54 +00:00
?>