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
2009-08-03 04:10:16 +00:00
*
* Originally authored by Tony Landis , AgileBill LLC
*
* Recent modifications by Deon George
*
* @ author Deon George < deonATleenooksDOTnet >
* @ copyright 2009 Deon George
* @ link http :// osb . leenooks . net
2008-11-26 22:50:40 +00:00
*
* @ link http :// www . agileco . com /
* @ copyright 2004 - 2008 Agileco , LLC .
* @ license http :// www . agileco . com / agilebill / license1 - 4. txt
2009-08-03 04:10:16 +00:00
* @ author Tony Landis < tony @ agileco . com >
2008-11-26 22:50:40 +00:00
* @ package AgileBill
2009-08-03 04:10:16 +00:00
* @ subpackage Modules : Invoice
2008-11-26 22:50:40 +00:00
*/
2009-08-03 04:10:16 +00:00
2008-11-26 22:50:40 +00:00
/**
2009-08-03 04:10:16 +00:00
* The main AgileBill Invoice Class
*
* @ package AgileBill
* @ subpackage Modules : Invoice
2008-11-26 22:50:40 +00:00
*/
2009-08-03 04:10:16 +00:00
class invoice extends OSB_module {
2010-11-29 22:41:08 +00:00
# Hold the invoice items associated with this invoice
private $items = array ();
2009-08-03 04:10:16 +00:00
# Array holding all our print information
public $print = array ();
# Enable summary invoice view that rolls multiple instances of the same sku w/identical base&setup price & attributes into one line item
private $summarizeInvoice = true ;
2008-11-26 22:50:40 +00:00
/**
2010-11-29 22:41:08 +00:00
* Delete an invoice
*
* @ uses service
2008-11-26 22:50:40 +00:00
*/
2010-11-29 22:41:08 +00:00
public function delete ( $VAR ) {
2009-08-03 04:10:16 +00:00
$db = & DB ();
2010-11-29 22:41:08 +00:00
# Get the array
if ( isset ( $VAR [ 'delete_id' ]))
$ids = explode ( ',' , preg_replace ( '/,$/' , '' , $VAR [ 'delete_id' ]));
elseif ( isset ( $VAR [ 'id' ]))
$ids = explode ( ',' , preg_replace ( '/,$/' , '' , $VAR [ 'id' ]));
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Load the service module
include_once ( PATH_MODULES . 'service/service.inc.php' );
$so = new service ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
foreach ( $ids as $id ) {
# Loop through all services for this invoice and delete:
$rs = $db -> Execute ( sqlSelect ( 'service' , array ( 'where' => array ( 'invoice_id' => $id ))));
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( ! $rs ) {
global $C_debug ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$C_debug -> error ( __FILE__ , __METHOD__ , $db -> ErrorMsg ());
return false ;
}
if ( $rs -> RecordCount ()) {
while ( ! $rs -> EOF ) {
$so -> delete ( $rs -> fields [ 'id' ]);
$rs -> MoveNext ();
}
}
# Delete the service record
$this -> associated_DELETE = array ();
array_push ( $this -> associated_DELETE , array ( 'table' => 'invoice_commission' , 'field' => 'invoice_id' ));
array_push ( $this -> associated_DELETE , array ( 'table' => 'invoice_item' , 'field' => 'invoice_id' ));
array_push ( $this -> associated_DELETE , array ( 'table' => 'invoice_memo' , 'field' => 'invoice_id' ));
// array_push($this->associated_DELETE,array('table'=>'service','field'=>'invoice_id'));
array_push ( $this -> associated_DELETE , array ( 'table' => 'invoice_item_tax' , 'field' => 'invoice_id' ));
array_push ( $this -> associated_DELETE , array ( 'table' => 'invoice_item_discount' , 'field' => 'invoice_id' ));
$result = parent :: delete ( $VAR );
}
2009-08-03 04:10:16 +00:00
}
/**
2010-11-29 22:41:08 +00:00
* View an Invoice
* Shown both in the admin pages and after checkout
2009-08-03 04:10:16 +00:00
*
2010-11-29 22:41:08 +00:00
* @ uses net_term
2009-08-03 04:10:16 +00:00
*/
2010-11-29 22:41:08 +00:00
public function view ( $VAR ) {
global $C_translate , $C_list ;
2009-08-03 04:10:16 +00:00
$db = & DB ();
2010-11-29 22:41:08 +00:00
if ( $smart = parent :: view ( $VAR )) {
# Get the product checkout plugin name
if ( ! empty ( $smart [ 'checkout_plugin_id' ])) {
$rs = $db -> Execute ( sqlSelect ( 'checkout' , 'name' , array ( 'where' => array ( 'id' => $smart [ 'checkout_plugin_id' ]))));
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( $rs && $rs -> RecordCount ())
$smart [ 'checkout_plugin' ] = $rs -> fields [ 'name' ];
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$smart [ 'balance' ] = ( $smart [ 'total_amt' ] == 0 ) ? 0 : $smart [ 'total_amt' ] - $smart [ 'billed_amt' ] - $smart [ 'credit_amt' ];
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Get the tax details
if ( ! empty ( $smart [ 'tax_amt' ])) {
$rs = $db -> Execute ( sqlSelect ( $db , array ( 'invoice_item_tax' , 'tax' ), 'A.amount,B.description' , sprintf ( 'A.tax_id=B.id AND A.invoice_id=%s' , $smart [ 'id' ])));
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( $rs && $rs -> RecordCount ()) {
$taxes = array ();
while ( ! $rs -> EOF ) {
@ $taxes [ $rs -> fields [ 'description' ]] += $rs -> fields [ 'amount' ];
$rs -> MoveNext ();
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$smart [ 'tax_arr' ] = array ();
foreach ( $taxes as $txds => $txamt )
array_push ( $smart [ 'tax_arr' ], array ( 'description' => $txds , 'amount' => $txamt ));
}
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Get the discount details
if ( ! empty ( $smart [ 'discount_amt' ])) {
$rs = $db -> Execute ( sqlSelect ( 'invoice_item_discount' , 'amount,discount' , array ( 'where' => array ( 'invoice_id' => $smart [ 'id' ]))));
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( $rs && $rs -> RecordCount ()) {
$discounts = array ();
while ( ! $rs -> EOF ) {
@ $discounts [ $rs -> fields [ 'discount' ]] += $rs -> fields [ " amount " ];
$rs -> MoveNext ();
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$dhtml = '' ;
foreach ( $discounts as $dsds => $dsamt )
$dhtml .= sprintf ( '<a href=\'?_page=core:search&module=discount&discount_name=%s\'>%s</a> - <br/>' , $dsds , $dsds , number_format ( $dsamt , 2 ));
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$smart [ 'discount_popup' ] = $dhtml ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$dhtml = '' ;
foreach ( $discounts as $dsds => $dsamt )
$dhtml .= sprintf ( '%s - %s<br/>' , $dsds , number_format ( $dsamt , 2 ));
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$smart [ 'discount_popup_user' ] = $dhtml ;
}
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Get the checkout plugin details
if ( ! empty ( $smart [ 'checkout_plugin_data' ])) {
$plugin_data = unserialize ( $smart [ 'checkout_plugin_data' ]);
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( is_array ( $plugin_data ))
$smart [ 'checkout_plugin_data' ] = $plugin_data ;
else
$smart [ 'checkout_plugin_data' ] = array ( $smart [ 'checkout_plugin_data' ]);
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Get the term dates
include_once ( PATH_MODULES . 'net_term/net_term.inc.php' );
$net_term = new net_term ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$smart [ 'termdates' ] = $net_term -> getTermDates ( $smart [ 'net_term_id' ], $smart [ 'date_orig' ], $smart [ 'due_date' ]);
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Get the line items
$rs = $db -> Execute ( sqlSelect ( 'invoice_item' , '*' , array ( 'where' => array ( 'invoice_id' => $smart [ 'id' ]))));
if ( ! $rs ) {
global $C_debug ;
$C_debug -> error ( __FILE__ , __METHOD__ , $db -> ErrorMsg ());
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
return false ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$ii = 0 ;
while ( ! $rs -> EOF ) {
$smart_items [ $ii ] = $rs -> fields ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Get the product attribs
if ( ! empty ( $rs -> fields [ 'product_attr' ])) {
@ $attrib = explode ( " \r \n " , $rs -> fields [ 'product_attr' ]);
$js = '' ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
for ( $attr_i = 0 ; $attr_i < count ( $attrib ); $attr_i ++ ) {
$attributei = explode ( '==' , $attrib [ $attr_i ]);
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( ! empty ( $attributei [ 0 ]) && ! empty ( $attributei [ 1 ]))
$js .= sprintf ( '<div style="text-decoration: underline;">%s</div> : %s <br/>' , $attributei [ 0 ], $attributei [ 1 ]);
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$smart_items [ $ii ][ 'attribute_popup' ] = $js ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Get the date range if set
if ( ! empty ( $rs -> fields [ 'date_start' ]) && ! empty ( $rs -> fields [ 'date_stop' ])) {
$C_translate -> value ( 'invoice' , 'start' , date ( UNIX_DATE_FORMAT , $rs -> fields [ 'date_start' ]));
$C_translate -> value ( 'invoice' , 'stop' , date ( UNIX_DATE_FORMAT , $rs -> fields [ 'date_stop' ]));
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$smart_items [ $ii ][ 'range' ] = $C_translate -> translate ( 'recur_date_range' , 'invoice' , '' );
2009-08-03 04:10:16 +00:00
}
2010-11-29 22:41:08 +00:00
# Set charge type for payment option list
$any_new = true ;
if ( $rs -> fields [ 'price_type' ] == '1' && ! empty ( $smart [ 'recurr_arr' ]) && is_array ( unserialize ( $smart [ 'recurr_arr' ])))
$any_recurring = true ;
2009-08-03 04:10:16 +00:00
$rs -> MoveNext ();
2010-11-29 22:41:08 +00:00
$ii ++ ;
2009-08-03 04:10:16 +00:00
}
2010-11-29 22:41:08 +00:00
# Create a summary (for duplicate skus w/identical price,and attributes, roll into a single value
if ( $this -> summarizeInvoice )
$smart_items = $this -> sInvoiceItemsSummary ();
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Get the checkout (payment) options
if ( $VAR [ '_page' ] != 'invoice:view' ) {
# Get the converted amount due:
if ( $smart [ 'billed_currency_id' ] != $smart [ 'actual_billed_currency_id' ]) {
global $C_list ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$CURRENCY = $smart [ 'actual_billed_currency_id' ];
if ( $smart [ 'billed_amt' ] <= 0 )
$total = $C_list -> format_currency_decimal ( $smart [ 'total_amt' ], $CURRENCY );
else
$total = $C_list -> format_currency_decimal ( $smart [ 'total_amt' ], $CURRENCY ) - $smart [ 'actual_billed_amt' ];
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
} else {
$CURRENCY = $smart [ 'billed_currency_id' ];
$total = $smart [ 'total_amt' ] - $smart [ 'billed_amt' ];
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$q = sqlSelect ( 'checkout' , '*' , array ( 'where' => array ( 'active' => '1' )));
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( $any_trial )
$q .= ' AND allow_trial=1' ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( $any_recurring )
$q .= ' AND allow_recurring=1' ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( $any_new )
$q .= ' AND allow_new=1' ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$rs = $db -> Execute ( $q );
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( ! $rs ) {
global $C_debug ;
$C_debug -> error ( __FILE__ , __METHOD__ , $db -> ErrorMsg ());
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
return false ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( $rs -> RecordCount ()) {
while ( ! $rs -> EOF ) {
$show = true ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Check that the cart total is not to high:
if ( $rs -> fields [ 'total_maximum' ] != '' && $smart [ 'total_amt' ] >= $rs -> fields [ 'total_maximum' ])
$show = false ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Check that the cart total is not to low:
if ( $rs -> fields [ 'total_miniumum' ] != '' && $smart [ 'total_amt' ] <= $rs -> fields [ 'total_miniumum' ])
$show = false ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Check that the group requirement is met:
if ( $show && ! empty ( $rs -> fields [ 'required_groups' ])) {
global $C_auth ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$arr = unserialize ( $rs -> fields [ 'required_groups' ]);
if ( count ( $arr ) > 0 && ! empty ( $arr [ 0 ]))
$show = false ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
for ( $i = 0 ; $i < count ( $arr ); $i ++ ) {
if ( $C_auth -> auth_group_by_id ( $arr )) {
$show = true ;
$i = count ( $arr );
}
}
2008-11-26 22:50:40 +00:00
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Check that the customer is not ordering a blocked SKU
if ( $show && ! empty ( $rs -> fields [ 'excluded_products' ])) {
$arr = unserialize ( $rs -> 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 [ 'product_id' ] == $arr [ $isk ] && ! empty ( $arr [ $isk ]) && ! empty ( $smart_items [ 'product_id' ])) {
$show = false ;
$i = count ( $smart );
$isk = count ( $arr );
}
}
}
}
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$list_ord = 100 ;
if ( $show ) {
# Check if this method should be the default method
# By Amount
if ( ! empty ( $rs -> fields [ 'default_when_amount' ])) {
$arr = unserialize ( $rs -> fields [ 'default_when_amount' ]);
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
for ( $idx = 0 ; $idx < count ( $arr ); $idx ++ ) {
if ( $total >= $arr [ $idx ])
$list_ord -- ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$idx = count ( $arr );
}
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# By Currency
if ( ! empty ( $rs -> fields [ 'default_when_currency' ])) {
$arr = unserialize ( $rs -> fields [ 'default_when_currency' ]);
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
for ( $idx = 0 ; $idx < count ( $arr ); $idx ++ ) {
if ( $CURRENCY == $arr [ $idx ])
$list_ord -- ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$idx = count ( $arr );
}
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# By Group
if ( ! empty ( $rs -> fields [ 'default_when_group' ])) {
$arr = unserialize ( $rs -> fields [ 'default_when_group' ]);
global $C_auth ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
for ( $idx = 0 ; $idx < count ( $arr ); $idx ++ ) {
if ( $C_auth -> auth_group_by_id ( $arr [ $idx ]))
$list_ord -- ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$idx = count ( $arr );
}
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# By Country
if ( ! empty ( $rs -> fields [ 'default_when_country' ])) {
$arr = unserialize ( $rs -> fields [ 'default_when_country' ]);
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
for ( $idx = 0 ; $idx < count ( $arr ); $idx ++ ) {
if ( $account -> fields [ 'country_id' ] == $arr [ $idx ])
$list_ord -- ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$idx = count ( $arr );
}
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Add to the array
$checkout_optionsx [] = array ( 'sort' => $list_ord , 'fields' => $rs -> fields );
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$rs -> MoveNext ();
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Sort the checkout_options array by the [fields] element
if ( count ( $checkout_optionsx ) > 0 ) {
foreach ( $checkout_optionsx as $key => $row )
$sort [ $key ] = $row [ 'sort' ];
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
array_multisort ( $sort , SORT_ASC , $checkout_optionsx );
2009-08-03 04:10:16 +00:00
}
}
2010-11-29 22:41:08 +00:00
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Get the payment details
if ( $C_list -> is_installed ( 'payment' )) {
require_once ( PATH_MODULES . 'payment/payment.inc.php' );
require_once ( PATH_MODULES . 'payment_item/payment_item.inc.php' );
$pii = new payment_item ();
$i = 0 ;
foreach ( $pii -> sql_GetRecords ( array ( 'where' => array ( 'invoice_id' => $VAR [ 'id' ]), 'orderby' => 'date_last,invoice_id' )) as $payment ) {
if ( $payment [ 'alloc_amt' ]) {
$pi = new payment ( $payment [ 'payment_id' ]);
$smart [ 'payment_data' ][ $i ][ 'payment_id' ] = $payment [ 'payment_id' ];
$smart [ 'payment_data' ][ $i ][ 'date_payment' ] = $pi -> getRecordAttr ( 'date_payment' );
$smart [ 'payment_data' ][ $i ][ 'total' ] = $pi -> getRecordAttr ( 'total_amt' );
$smart [ 'payment_data' ][ $i ][ 'alloc' ] = $payment [ 'alloc_amt' ];
$i ++ ;
2009-08-03 04:10:16 +00:00
}
}
2010-11-29 22:41:08 +00:00
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# No results
if ( count ( $smart ) == 0 ) {
global $C_debug ;
$C_debug -> error ( __FILE__ , __METHOD__ , 'The selected record does not exist any longer, or your account is not authorized to view it' );
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
return ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Define the DB vars as a Smarty accessible block
global $smarty ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Define the results
$smarty -> assign ( 'cart' , $smart_items );
$smarty -> assign ( 'record' , $smart );
$smarty -> assign ( 'checkoutoptions' , $checkout_optionsx );
}
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
public function user_search_show ( $VAR ) {
global $smarty ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$smart = parent :: user_search_show ( $VAR );
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Add the balance to the array
foreach ( $smart as $index => $details )
$smart [ $index ][ 'balance' ] = $details [ 'total_amt' ] - $details [ 'billed_amt' ] - $details [ 'credit_amt' ];
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$smarty -> assign ( 'search_show' , $smart );
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
/**
* User view an invoice
*/
public function user_view ( $VAR ) {
global $C_auth ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( ! SESS_LOGGED )
return false ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Verify the account_id for this order is the SESS_ACCOUNT
if ( $C_auth -> auth_method_by_name ( 'invoice' , 'view' ) == false ) {
$invoices = $this -> sql_GetRecords ( array ( 'where' => array ( 'id' => $VAR [ 'id' ])));
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( ! count ( $invoices ) || $invoices [ 0 ][ 'account_id' ] != SESS_ACCOUNT )
return false ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$this -> view ( $VAR );
2008-11-26 22:50:40 +00:00
}
2009-08-03 04:10:16 +00:00
2008-11-26 22:50:40 +00:00
/**
2010-11-29 22:41:08 +00:00
* Get the balance of the account
2008-11-26 22:50:40 +00:00
*/
2010-11-29 22:41:08 +00:00
public function sPreviousBalance () {
static $CACHE = array ();
$id = $this -> getRecordAttr ( 'id' );
if ( ! isset ( $CACHE [ $id ])) {
$CACHE [ $id ] = 0 ;
foreach ( $this -> sPreviousInvoices () as $item )
$CACHE [ $id ] += round ( $item [ 'total_amt' ] - $item [ 'billed_amt' ] - $item [ 'credit_amt' ], 2 );
2009-08-03 04:10:16 +00:00
}
2010-11-29 22:41:08 +00:00
return $CACHE [ $id ];
2008-11-26 22:50:40 +00:00
}
2009-08-03 04:10:16 +00:00
2008-11-26 22:50:40 +00:00
/**
2010-11-29 22:41:08 +00:00
* Get all the previous invoices still unpaid
2008-11-26 22:50:40 +00:00
*/
2010-11-29 22:41:08 +00:00
private function sPreviousInvoices () {
static $CACHE = array ();
$id = $this -> getRecordAttr ( 'id' );
if ( ! isset ( $CACHE [ $id ])) {
$CACHE [ $id ] = $this -> sql_GetRecords (
array ( 'where' => sprintf ( 'account_id=%s AND status=1 AND (billed_amt+IFNULL(credit_amt,0)<total_amt OR billed_amt IS NULL) AND date_orig<%s AND id!=%s' ,
$this -> getRecordAttr ( 'account_id' ), $this -> getRecordAttr ( 'due_date' ), $id )));
2009-08-03 04:10:16 +00:00
}
2010-11-29 22:41:08 +00:00
return $CACHE [ $id ];
2009-08-03 04:10:16 +00:00
}
2008-11-26 22:50:40 +00:00
/**
2010-11-29 22:41:08 +00:00
* Get the items on an invoice
2008-11-26 22:50:40 +00:00
*
2010-11-29 22:41:08 +00:00
* @ uses invoice_item
2008-11-26 22:50:40 +00:00
*/
2010-11-29 22:41:08 +00:00
private function sInvoiceItems () {
static $CACHE = array ();
$id = $this -> getRecordAttr ( 'id' );
if ( ! isset ( $CACHE [ $id ])) {
include_once ( PATH_MODULES . 'invoice_item/invoice_item.inc.php' );
$ito = new invoice_item ();
$CACHE [ $id ] = $ito -> sInvoiceItems ( $this -> getRecordAttr ( 'id' ));
2008-11-26 22:50:40 +00:00
}
2010-11-29 22:41:08 +00:00
return $CACHE [ $id ];
2008-11-26 22:50:40 +00:00
}
2009-08-03 04:10:16 +00:00
/**
2010-11-29 22:41:08 +00:00
* Create modified array for invoice summarization
*
* This function will summarise the invoice items based on the same
* SKU , BASE_PRICE , SETUP_PRICE & PRODUCT_ATTR
*/
public function sInvoiceItemsSummary () {
$sum = array ();
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
foreach ( $this -> sInvoiceItems () as $index => $item ) {
$unique = true ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Unique line item
if ( isset ( $sum [ $item [ 'sku' ]])) {
# Is unique price/attributes?
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
foreach ( $sum [ $item [ 'sku' ]] as $sid => $flds ) {
if ( $flds [ 'price_base' ] == $item [ 'price_base' ] &&
$flds [ 'price_setup' ] == $item [ 'price_setup' ]) {
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$sum [ $item [ 'sku' ]][ $sid ][ 'quantity' ] += $item [ 'quantity' ];
$unique = false ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
break ;
}
}
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Unique line item
if ( $unique ) {
$a = count ( $sum [ $item [ 'sku' ]]);
$sum [ $item [ 'sku' ]][ $a ] = $item ;
$sum [ $item [ 'sku' ]][ $a ][ 'product_name' ] = $this -> sLineItemDesc ( $index , true );
}
2008-11-26 22:50:40 +00:00
}
2010-11-29 22:41:08 +00:00
if ( count ( $sum )) {
$items = array ();
foreach ( $sum as $sku => $item )
foreach ( $item as $sitem )
array_push ( $items , $sitem );
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
return $items ;
2008-11-26 22:50:40 +00:00
}
}
2010-11-29 22:41:08 +00:00
/**
* Return a line description , suitable for printing on invoices
*
* @ uses product_translate
*/
private function sLineItemDesc ( $id , $summary = false ) {
$li = $this -> sInvoiceItems ();
if ( ! isset ( $li [ $id ]))
return 'Other Item' ;
require_once ( PATH_MODULES . 'product_translate/product_translate.inc.php' );
$pdo = new product_translate ( $li [ $id ][ 'product_id' ]);
if ( $summary ) {
if ( is_null ( $li [ $id ][ 'sku' ]) && is_null ( $li [ $id ][ 'product_id' ]))
return _ ( 'Other Item' );
elseif ( is_null ( $li [ $id ][ 'product_id' ])) {
switch ( $li [ $id ][ 'sku' ]) {
case 'DOMAIN-REGISTER' : $name = _ ( 'Register Domain' ); break ;
case 'DOMAIN-TRANSFER' : $name = _ ( 'Transfer Domain' ); break ;
case 'DOMAIN-PARK' : $name = _ ( 'Park Domain' ); break ;
case 'DOMAIN-RENEW' : $name = _ ( 'Renew Domain' ); break ;
default : $name = $sku ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
return $name ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
} elseif ( $li [ $id ][ 'product_id' ])
return $pdo -> getRecordAttr ( 'name' );
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
} else {
switch ( $li [ $id ][ 'sku' ]) {
case 'DOMAIN-REGISTER' : $name = _ ( 'Register Domain' ); break ;
case 'DOMAIN-TRANSFER' : $name = _ ( 'Transfer Domain' ); break ;
case 'DOMAIN-PARK' : $name = _ ( 'Park Domain' ); break ;
case 'DOMAIN-RENEW' : $name = _ ( 'Renew Domain' ); break ;
default : return $li [ $id ][ 'product_name' ] ? $li [ $id ][ 'product_name' ] :
( $pdo -> getRecordAttr ( 'description_short' ) ? $pdo -> getRecordAttr ( 'description_short' ) : $pdo -> getRecordAttr ( 'name' ));
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
return $li [ $id ][ 'product_name' ] ? $li [ $id ][ 'product_name' ] : sprintf ( '%s (%s.%s)' , $name , $li [ $id ][ 'domain_name' ], $li [ $id ][ 'domain_tld' ]);
2008-11-26 22:50:40 +00:00
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
return 'Other Item' ;
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
public function sql_invoice_soon ( $fields = null , $adddays = 0 , $account = null , $orderby = null ) {
return $this -> sql_InvoiceSoon ( $fields , $adddays , $account , $orderby );
}
/**
* Return the SQL that determines which invoices need to be generated
*
* Invoices are generated when the greater of :
* + system default ( setup : max_inv_gen_period ), ( to be deprecated )
* + system default ( setup_invoice : invoice_advance_gen ),
* + the account setting ( account : invoice_advance_gen )
* + the net_terms setting ( net_term : invoice_advance_gen ) ( linked from the account : net_term_id ))
*
* This function can be called to display the SQL that is need to generate upcoming invoices .
*
* @ param string The SQL to use in the SELECT portion of the query , to return the fields
* @ param int Days in advance of the normal invoice generation date to obtain
* @ param int | array Limit the query to just a ( n ) ( set of ) Account ID ( s )
* @ param string The SQL to use in the ORDER BY portion of the query .
*/
public function sql_InvoiceSoon ( $fields = null , $adddays = 0 , $account = null , $orderby = null ) {
global $C_list ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# Get the max invoice days from the system configuration tables.
$days = $this -> sInvoiceDays ();
# Pre-notification date for service
$max_date = date ( 'Y-m-d' , time () + (( $adddays + $days ) * 86400 ));
if ( $account ) {
if ( is_array ( $account ))
$account_where = sprintf ( 'AND account.id IN (%s)' , implode ( ',' , $account ));
else
$account_where = sprintf ( 'AND account.id=%s' , $account );
} else
$account_where = '' ;
if ( is_null ( $fields ))
2011-07-22 01:04:20 +00:00
$fields = 'DISTINCT service.id AS sid,account.id AS account_id,FROM_UNIXTIME(service.date_next_invoice,\'%Y-%m-%d\') AS invoice_date,service.sku AS sku,service.price AS price,account.first_name AS first_name,account.last_name AS last_name,account.currency_id AS billed_currency_id,service.date_orig AS date_orig' ;
2010-11-29 22:41:08 +00:00
if ( is_null ( $orderby ))
$orderby = 'ORDER BY account_id,invoice_date,sid' ;
else
$orderby = sprintf ( 'ORDER BY %s' , $orderby );
// @todo NET_TERM is not tested.
if ( $C_list -> is_installed ( 'net_term' )) {
$net_term = 'LEFT JOIN {p}net_term AS net_term ON (account.net_term_id=net_term.id AND net_term.site_id={s})' ;
$net_term_where = sprintf ( 'OR ((net_term.invoice_advance_gen!="" OR net_term.invoice_advance_gen IS NOT NULL) AND service.date_next_invoice<=((86400*(net_term.invoice_advance_gen+%s+%s))+(UNIX_TIMESTAMP(CURDATE()))))' , $adddays , $days );
} else {
$net_term = '' ;
$net_term_where = '' ;
2008-11-26 22:50:40 +00:00
}
2010-11-29 22:41:08 +00:00
$sql = sprintf ( '
SELECT % s
FROM { p } service AS service
JOIN { p } account AS account ON ( service . account_id = account . id AND account . site_id = { s })
% s
WHERE service . site_id = { s }
AND service . active = 1
AND price > 0
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 <= (( 86400 * ( account . invoice_advance_gen +% s +% s )) + ( UNIX_TIMESTAMP ( CURDATE ()))))
% s
OR service . date_next_invoice <= UNIX_TIMESTAMP ( " %s " )
) % s % s ' ,
$fields , $net_term , $adddays , $days , $net_term_where , $max_date , $account_where , $orderby );
$sql = str_replace ( '{p}' , AGILE_DB_PREFIX , $sql );
$sql = str_replace ( '{s}' , DEFAULT_SITE , $sql );
return $sql ;
}
/**
* Template method to list all invoices that will be generated soon
*/
public function tmInvoiceSoon ( $VAR ) {
global $smarty , $C_list ;
$db = & DB ();
$order_by = isset ( $VAR [ 'order_by' ]) ? $VAR [ 'order_by' ] : 'account_id,invoice_date,sid' ;
# Then from the setup_invoice table.
$setup = $db -> Execute ( sqlSelect ( 'setup_invoice' , 'advance_notice' ));
# Run the database query
$result = $db -> Execute ( $this -> sql_InvoiceSoon ( null , $setup -> fields [ 'advance_notice' ], null , $order_by ));
# Error reporting
if ( ! $result ) {
global $C_debug ;
$C_debug -> error ( __FILE__ , __METHOD__ , $db -> ErrorMsg ());
return false ;
} elseif ( ! $result -> RecordCount ()) {
return false ;
2008-11-26 22:50:40 +00:00
}
2010-11-29 22:41:08 +00:00
$invoice = array ();
$i = 0 ;
while ( ! $result -> EOF ) {
$result -> fields [ '_C' ] = ++ $i % 2 ? 'row1' : 'row2' ;
$result -> fields [ 'id' ] = $result -> fields [ 'sid' ];
array_push ( $invoice , $result -> fields );
$result -> MoveNext ();
2008-11-26 22:50:40 +00:00
}
2010-11-29 22:41:08 +00:00
# Create the search record:
if ( count ( $invoice ) > 0 ) {
# create the search record
#include_once(PATH_CORE.'search.inc.php');
#$search = new CORE_search;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
#$arr['module'] = $this->module;
#$arr['sql'] = $this->sql_InvoiceSoon();
#$arr['limit'] = $limit;
#$arr['order_by']= $order_by;
#$arr['results'] = $results;
#$search->add($arr);
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# Define the search id and other parameters for Smarty
$smarty -> assign ( 'search_id' , $search -> id );
$smarty -> assign ( 'page' , '1' );
$smarty -> assign ( 'order_by' , $order_by );
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# Define the result count
$smarty -> assign ( 'results' , count ( $invoice ));
$smarty -> assign ( 'search_show' , $invoice );
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
public function performance ( $VAR ) { return $this -> tmPerformance ( $VAR ); }
/**
* Site Performance ( for the admin dashboard )
*/
public function tmPerformance ( $VAR ) {
global $smarty , $C_list , $C_translate ;
$db = & DB ();
$period = array ();
# Get the period type, default to month
$period [ 'period' ] = empty ( $VAR [ 'period' ]) ? 'y' : $VAR [ 'period' ];
switch ( $period [ 'period' ]) {
2008-11-26 22:50:40 +00:00
case 'w' :
2010-11-29 22:41:08 +00:00
$smarty -> assign ( 'period_compare' , sprintf ( '%s %s %s' , _ ( 'This Week' ), _ ( 'vs' ),( 'Last Week' )));
$smarty -> assign ( 'period_forcast' , _ ( 'This Week' ));
$period [ 'this_start' ] = mktime ( 0 , 0 , 0 , date ( 'm' ), date ( 'd' ) - date ( 'w' ), date ( 'y' ));
$period [ 'this_end' ] = mktime ( 23 , 59 , 59 , date ( 'm' ), date ( 'd' ), date ( 'y' ));
$period [ 'last_start' ] = mktime ( 0 , 0 , 0 , date ( 'm' ), date ( 'd' , $period [ 'this_start' ]) - 7 , date ( 'y' ));
$period [ 'last_end' ] = mktime ( 23 , 59 , 59 , date ( 'm' ), date ( 'd' ) - 7 , date ( 'y' ));
break ;
2008-11-26 22:50:40 +00:00
case 'm' :
2010-11-29 22:41:08 +00:00
$smarty -> assign ( 'period_compare' , sprintf ( '%s %s %s' , _ ( 'This Month' ), _ ( 'vs' ),( 'Last Month' )));
$smarty -> assign ( 'period_forcast' , _ ( 'This Month' ));
$period [ 'this_start' ] = mktime ( 0 , 0 , 0 , date ( 'm' ), 1 , date ( 'y' ));
$period [ 'this_end' ] = mktime ( 23 , 59 , 59 , date ( 'm' ), date ( 'd' ), date ( 'y' ));
$period [ 'last_start' ] = mktime ( 0 , 0 , 0 , date ( 'm' , $period [ 'this_start' ]) - 1 , 1 , date ( 'y' ));
$period [ 'last_end' ] = mktime ( 23 , 59 , 59 , date ( 'm' ) - 1 , date ( 'd' ), date ( 'y' ));
break ;
2008-11-26 22:50:40 +00:00
case 'y' :
2010-11-29 22:41:08 +00:00
default :
$smarty -> assign ( 'period_compare' , sprintf ( '%s %s %s' , _ ( 'This Year' ), _ ( 'vs' ),( 'Last Year' )));
$smarty -> assign ( 'period_forcast' , _ ( 'This Year' ));
$period [ 'this_start' ] = mktime ( 0 , 0 , 0 , 1 , 1 , date ( 'y' , time ()));
$period [ 'this_end' ] = mktime ( 23 , 59 , 59 , date ( 'm' ), date ( 'd' ), date ( 'y' ));
$period [ 'last_start' ] = mktime ( 0 , 0 , 0 , 1 , 1 , date ( 'y' , $period [ 'this_start' ]) - 1 );
$period [ 'last_end' ] = mktime ( 23 , 59 , 59 , date ( 'm' ), date ( 'd' ), date ( 'y' ) - 1 );
break ;
2008-11-26 22:50:40 +00:00
}
2010-11-29 22:41:08 +00:00
# Get sales for this period
$rs = $db -> Execute ( sqlSelect ( 'invoice' , 'SUM(total_amt) as total_amt' ,
array ( 'where' => sprintf ( 'date_orig>=%s AND date_orig<=%s' , $period [ 'this_start' ], $period [ 'this_end' ]))));
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
if ( $rs && $rs -> RecordCount ())
$this_amt = $rs -> fields [ 'total_amt' ];
2008-11-26 22:50:40 +00:00
else
2010-11-29 22:41:08 +00:00
$this_amt = 0 ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# Get sales for last period
$rs = $db -> Execute ( sqlSelect ( 'invoice' , 'SUM(total_amt) as total_amt' ,
array ( 'where' => sprintf ( 'date_orig>=%s AND date_orig<=%s' , $period [ 'last_start' ], $period [ 'last_end' ]))));
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
if ( $rs && $rs -> RecordCount ())
$last_amt = $rs -> fields [ 'total_amt' ];
2008-11-26 22:50:40 +00:00
else
2010-11-29 22:41:08 +00:00
$last_amt = 0 ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
$smarty -> assign ( 'sales_current' , $this_amt );
$smarty -> assign ( 'sales_previous' , $last_amt );
$smarty -> assign ( 'sales_change' ,( $last_amt > 0 ) ? $this_amt / $last_amt * 100 - 100 : 0 );
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# Get forcast for current period
switch ( $period [ 'period' ]) {
case 'w' :
$dow = date ( 'w' ) + 1 ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
$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 ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
break ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
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' );
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
break ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
case 'y' :
default :
$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 ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
break ;
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
$smarty -> assign ( 'forcast_current' , $forcast_current );
$smarty -> assign ( 'quota_current' , $forcast_daily );
$smarty -> assign ( 'forcast_change' ,( $last_amt > 0 ) ? $forcast_daily / $forcast_1_daily * 100 : 0 );
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# Get AR credits for this period
$rs = $db -> Execute ( sqlSelect ( 'invoice' , 'SUM(billed_amt) as total_amt' ,
array ( 'where' => sprintf ( 'date_orig>=%s AND date_orig<=%s AND billed_amt>0' , $period [ 'this_start' ], $period [ 'this_end' ]))));
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
if ( $rs && $rs -> RecordCount ())
$this_billed_amt = $rs -> fields [ 'total_amt' ];
2008-11-26 22:50:40 +00:00
else
2010-11-29 22:41:08 +00:00
$this_billed_amt = 0 ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# Get AR credits for last period
$rs = $db -> Execute ( sqlSelect ( 'invoice' , 'SUM(billed_amt) as total_amt' ,
array ( 'where' => sprintf ( 'date_orig>=%s AND date_orig<=%s AND billed_amt>0' , $period [ 'last_start' ], $period [ 'last_end' ]))));
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
if ( $rs && $rs -> RecordCount ())
$last_billed_amt = $rs -> fields [ 'total_amt' ];
else
$last_billed_amt = 0 ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
$smarty -> assign ( 'ar_credits_current' , $this_billed_amt );
$smarty -> assign ( 'ar_credits_previous' , $last_billed_amt );
$smarty -> assign ( 'ar_credit_change' ,( $last_billed_amt > 0 ) ? $this_billed_amt / $last_billed_amt * 100 - 100 : 0 );
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# Get AR Balance
$smarty -> assign ( 'ar_balance_current' , $this_billed_amt - $this_amt );
$smarty -> assign ( 'ar_balance_last' , $last_billed_amt - $last_amt );
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# Get Users (current)
$rs = $db -> Execute ( sqlSelect ( 'account' , 'COUNT(*) as count' ,
array ( 'where' => sprintf ( 'date_orig>=%s AND date_orig<=%s' , $period [ 'this_start' ], $period [ 'this_end' ]))));
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
if ( $rs && $rs -> RecordCount ())
$users_current = $rs -> fields [ 'count' ];
else
$users_current = 0 ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# Get Users (previous)
$rs = $db -> Execute ( sqlSelect ( 'account' , 'COUNT(*) as count' ,
array ( 'where' => sprintf ( 'date_orig>=%s AND date_orig<=%s' , $period [ 'last_start' ], $period [ 'last_end' ]))));
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( $rs && $rs -> RecordCount ())
$users_previous = $rs -> fields [ 'count' ];
else
$user_previous = 0 ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$smarty -> assign ( 'users_current' , $users_current );
$smarty -> assign ( 'users_previous' , $users_previous );
$smarty -> assign ( 'users_change' ,( $users_previous > 0 ) ? $users_current / $users_current * 100 - 100 : 0 );
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Get Affiliate stats
if ( $C_list -> is_installed ( 'affiliate' )) {
$smarty -> assign ( 'show_affiliates' , true );
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Get affiliate sales for this period
$rs = $db -> Execute ( sqlSelect ( 'invoice' , 'SUM(total_amt) as total_amt' ,
array ( 'where' => sprintf ( 'date_orig>=%s AND date_orig<=%s AND affiliate_id NOT IN (0,"")' , $period [ 'this_start' ], $period [ 'this_end' ]))));
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( $rs && $rs -> RecordCount ())
$this_amt = $rs -> fields [ 'total_amt' ];
2008-11-26 22:50:40 +00:00
else
2010-11-29 22:41:08 +00:00
$this_amt = 0 ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Get affiliate sales for last period
$rs = $db -> Execute ( sqlSelect ( 'invoice' , 'SUM(total_amt) as total_amt' ,
array ( 'where' => sprintf ( 'date_orig>=%s AND date_orig<=%s AND affiliate_id NOT IN (0,"")' , $period [ 'last_start' ], $period [ 'last_end' ]))));
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( $rs && $rs -> RecordCount ())
$last_amt = $rs -> fields [ 'total_amt' ];
2009-08-03 04:10:16 +00:00
else
2010-11-29 22:41:08 +00:00
$last_amt = 0 ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$smarty -> assign ( 'affiliate_sales_current' , $this_amt );
$smarty -> assign ( 'affiliate_sales_previous' , $last_amt );
$smarty -> assign ( 'affiliate_sales_change' ,( $last_amt > 0 ) ? $this_amt / $last_amt * 100 - 100 : 0 );
}
2009-08-03 04:10:16 +00:00
2008-11-26 22:50:40 +00:00
# Generate the Calendar Overview
include_once ( PATH_MODULES . 'core/calendar.inc.php' );
2009-08-03 04:10:16 +00:00
$calendar = new calendar ;
2008-11-26 22:50:40 +00:00
$C_list -> currency ( DEFAULT_CURRENCY );
2010-11-29 22:41:08 +00:00
$currency_symbol = $C_list -> format_currency [ DEFAULT_CURRENCY ][ 'symbol' ];
2009-08-03 04:10:16 +00:00
2008-11-26 22:50:40 +00:00
# Get the paid/due invoice statistics
2010-11-29 22:41:08 +00:00
$records = $this -> sql_GetRecords ( array ( 'where' => sprintf ( 'date_orig>=%s AND date_orig<=%s' , $calendar -> start , $calendar -> end )));
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$paid = array ();
$due = array ();
if ( count ( $records )) {
foreach ( $records as $rs ) {
$day = date ( 'j' , $rs [ 'date_orig' ]);
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( $rs [ 'billed_amt' ] > 0 && ( $rs [ 'billing_status' ] == 1 || $rs [ 'refund_status' ] != 1 ))
@ $paid [ $day ] += $rs [ 'billed_amt' ];
if ( $rs [ 'billing_status' ] != 1 && $rs [ 'refund_status' ] != 1 )
@ $due [ $day ] += $rs [ 'total_amt' ] - $rs [ 'billed_amt' ];
2009-08-03 04:10:16 +00:00
}
2010-11-29 22:41:08 +00:00
foreach ( $paid as $day => $item )
$calendar -> add ( sprintf ( '<b>%s</b> - %s%s' , _ ( 'Paid' ), $currency_symbol , number_format ( $item , 2 )), $day , 'green' , 'green' );
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
foreach ( $due as $day => $item )
$calendar -> add ( sprintf ( '<b>%s</b> - %s%s' , _ ( 'Due' ), $currency_symbol , number_format ( $item , 2 )), $day , 'red' , 'red' );
2008-11-26 22:50:40 +00:00
}
2009-08-03 04:10:16 +00:00
# Get the upcoming due services
2010-11-29 22:41:08 +00:00
$rs = $db -> Execute ( sqlSelect ( 'service' , 'date_next_invoice,price' ,
array ( 'where' => sprintf ( 'price>0 AND date_next_invoice>=%s AND date_next_invoice<=%s AND suspend_billing<>1' ,
$calendar -> start , $calendar -> end ))));
if ( $rs && $rs -> RecordCount ()) {
$due = array ();
while ( ! $rs -> EOF ) {
$day = date ( 'j' , $rs -> fields [ 'date_next_invoice' ]);
@ $due [ $day ] += $rs -> fields [ 'price' ];
2008-11-26 22:50:40 +00:00
$rs -> MoveNext ();
2009-08-03 04:10:16 +00:00
}
2010-11-29 22:41:08 +00:00
foreach ( $due as $day => $item )
$calendar -> add ( sprintf ( '<b>%s</b> - %s%s' , _ ( 'Recurring' ), $currency_symbol , number_format ( $item , 2 )), $day , 'grey' , 'grey' );
2009-08-03 04:10:16 +00:00
}
2010-11-29 22:41:08 +00:00
$smarty -> assign ( 'calendar' , $calendar -> generate ());
2009-08-03 04:10:16 +00:00
2008-11-26 22:50:40 +00:00
return ;
}
2010-11-29 22:41:08 +00:00
/**
* Task based function to e - mail or store printable PDF of all unprinted invoices
*
* @ todo This seems to be hard limited to do 100 invoices in a run - why ? ( make it configurable , or remove the limit ? )
*/
public function task_DeliverInvoices () {
# Get all unprinted invoices
2008-11-26 22:50:40 +00:00
$db = & DB ();
2010-11-29 22:41:08 +00:00
$rs = $db -> SelectLimit ( 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.status=1) AND A.account_id=B.id AND (B.invoice_delivery IS NOT NULL AND B.invoice_delivery>0)' ), 100 );
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
if ( $rs && $rs -> RecordCount ()) {
# Send the e-mail....
require_once ( PATH_INCLUDES . 'phpmailer/class.phpmailer.php' );
$mail = new PHPMailer ();
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
$mail -> From = SITE_EMAIL ;
$mail -> FromName = SITE_NAME ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
/*
$mail -> SMTPAuth = true ;
$mail -> Host = " smtp.domain.com " ;
$mail -> Username = " user " ;
$mail -> Password = " pass " ;
$mail -> Mailer = " smtp " ;
$mail -> Debug = true ;
*/
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
while ( ! $rs -> EOF ) {
$this -> sql_LoadRecord ( $rs -> fields [ 'id' ]);
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
switch ( $rs -> fields [ 'invoice_delivery' ]) {
# Email Invoice
case 1 :
if ( $file = $this -> pdf ( null , null , array ( 'dest' => 'S' ))) {
$mail -> AddAddress ( $rs -> fields [ 'email' ], sprintf ( '%s %s' , $rs -> fields [ 'first_name' ], $rs -> fields [ 'last_name' ]));
$mail -> AddBcc ( 'deon@leenooks.vpn' );
$mail -> AddBcc ( 'chris@graytech.com.au' );
$mail -> Subject = sprintf ( '%s %s: %s' , SITE_NAME , _ ( 'Invoice' ), $this -> getRecordAttr ( 'id' ));
$mail -> AltBody = sprintf ( " Please find the printable version of invoice number %s attached. \r \n \r \n Thank you, \r \n %s " , $this -> getRecordAttr ( 'id' ), SITE_NAME );
$mail -> IsHTML ( true );
$mail -> AddEmbeddedImage ( sprintf ( '%s/%s' , PATH_THEMES . DEFAULT_THEME , 'invoice/invoice-logo.png' ), 'logoimg' , '' , 'base64' , 'image/png' );
$mail -> Body = sprintf ( '<p>Please find attached invoice <b>%s</b> from %s</p>' , $this -> getRecordAttr ( 'id' ), SITE_NAME );
$mail -> Body .= sprintf ( '<p>A PDF version is also attached with more detail and payment options. Alternatively, you can visit our website and <a href="%s?_page=invoice:user_view&id=%s">pay online</a>.</p>' ,
URL , $this -> getRecordAttr ( 'id' ));
$mail -> Body .= " <hr/> \n " ;
$mail -> Body .= wordwrap ( $this -> html ( array ( 'id' => $this -> getRecordAttr ( 'id' ))));
$mail -> AddStringAttachment ( $file , sprintf ( '%s.pdf' , $this -> getPrintInvoiceID ()), 'base64' , 'application/pdf' );
if ( $mail -> Send ())
$db -> Execute ( sqlUpdate ( $db , 'invoice' , array ( 'print_status' => 1 ), array ( 'id' => $this -> getRecordAttr ( 'id' ))));
else
printf ( 'Unable to email invoice # %s to %s<br/>' , $this -> getRecordAttr ( 'id' ), $rs -> fields [ 'email' ]);
$mail -> ClearAddresses ();
$mail -> ClearAttachments ();
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
break ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# Print Invoice
case 2 :
$file = tempnam ( PATH_FILES , sprintf ( 'pdf_inv_%s.pdf' , $this -> getPrintInvoiceID ()));
$this -> pdf ( null , null , array ( 'dest' => 'F' , 'file' => $file ));
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
if ( copy ( $file , sprintf ( '%sinvoice_%s.pdf' , AGILE_PDF_INVOICE_PATH , $this -> getPrintInvoiceID ())))
$db -> Execute ( sqlUpdate ( $db , 'invoice' , array ( 'print_status' => 1 ), array ( 'id' => $this -> getRecordAttr ( 'id' ))));
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
unlink ( $file );
break ;
default :
printf ( 'Unknown invoice_delivery: %s for %s<br/>' , $rs -> fields [ 'invoice_delivery' ], $this -> getRecordAttr ( 'id' ));
2008-11-26 22:50:40 +00:00
}
2010-11-29 22:41:08 +00:00
$rs -> MoveNext ();
}
2008-11-26 22:50:40 +00:00
}
}
2010-11-29 22:41:08 +00:00
/**
* Email a list of overdue invoices .
*
* @ uses PHPMailer
* @ uses staff
*/
public function task_OverdueListEmail () {
# @todo Make this configurable somewhere.
$receipient_dep = 'Accounts' ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
require_once ( PATH_MODULES . 'staff/staff.inc.php' );
$so = new staff ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
if ( ! $staff = $so -> sDepartmentMemberEmail ( $receipient_dep ))
2008-11-26 22:50:40 +00:00
return false ;
2010-11-29 22:41:08 +00:00
$db = & DB ();
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
$rs = $db -> Execute ( sqlSelect ( $db , array ( 'invoice' , 'account' ), 'A.id,A.account_id,ROUND(SUM(A.total_amt-A.billed_amt-IFNULL(A.credit_amt,0)),2) as total,B.first_name,B.last_name,A.due_date' , sprintf ( 'A.status=1 AND ROUND(A.total_amt-A.billed_amt-IFNULL(A.credit_amt,0),2)>0 AND A.account_id=B.id AND A.due_date<%s' , time ()), false , false , false , 'account_id,id' ));
if ( $rs && $rs -> RecordCount ()) {
$body = '' ;
$account_total = 0 ;
$account_id = '' ;
$i = 0 ;
$count = 0 ;
$grand_total = 0 ;
while ( ! $rs -> EOF ) {
if ( $account_id != $rs -> fields [ 'account_id' ] && $i ) {
$body .= sprintf ( " Total: %3.2f \n \n " , $account_total );
$account_total = 0 ;
$i = 0 ;
2008-11-26 22:50:40 +00:00
}
2010-11-29 22:41:08 +00:00
if ( ! $i )
$body .= sprintf ( " %s %s (%s) \n " , $rs -> fields [ 'last_name' ], $rs -> fields [ 'first_name' ], $rs -> fields [ 'account_id' ]);
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
$body .= sprintf ( " Invoice: %s, Due Date: %s, Amount: %3.2f \n " , $rs -> fields [ 'id' ], date ( 'Y-m-d' , $rs -> fields [ 'due_date' ]), $rs -> fields [ 'total' ]);
$account_total += $rs -> fields [ 'total' ];
$grand_total += $rs -> fields [ 'total' ];
$account_id = $rs -> fields [ 'account_id' ];
$count ++ ;
$i ++ ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
$rs -> MoveNext ();
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
if ( $account_total )
$body .= sprintf ( " Total: %3.2f \n " , $account_total );
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
$body .= " \n " ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
if ( $count || $ground_total )
$body .= sprintf ( " %3.2f outstanding in %s invoices \n " , $grand_total , $count );
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# Send the e-mail....
require_once ( PATH_INCLUDES . 'phpmailer/class.phpmailer.php' );
$mail = new PHPMailer ();
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
foreach ( $staff as $email => $name )
$mail -> AddAddress ( $email , $name );
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
$mail -> From = SITE_EMAIL ;
$mail -> FromName = SITE_NAME ;
$mail -> Subject = _ ( 'List of Invoices Overdue' );
$mail -> Body = $body ;
$mail -> Send ();
2008-11-26 22:50:40 +00:00
}
}
2010-11-29 22:41:08 +00:00
/**
* Return the invoice ID
*/
public function getPrintInvoiceID () {
return sprintf ( '%02s-%04s-%06s' , DEFAULT_SITE , $this -> getRecordAttr ( 'account_id' ), $this -> getRecordAttr ( 'id' ));
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
public function getPrintInvoiceNum () {
return $this -> getRecordAttr ( 'id' );
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
/**
* Add an item to the invoice
*
* @ uses host_tld
* @ uses invoice_item
* @ uses product
*/
public function aaddItem ( $item ) {
include_once ( PATH_MODULES . 'invoice_item/invoice_item.inc.php' );
$ito = new invoice_item ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
foreach ( $item as $i => $v )
if ( isset ( $ito -> field [ $i ]))
$ito -> setRecordAttr ( $i , $v );
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
$ito -> setRecordAttr ( 'invoice_id' , $this -> getRecordAttr ( 'id' ));
if ( ! is_null ( $this -> getRecordAttr ( 'account_id' )))
$ito -> setRecordAttr ( 'account_id' , $this -> getRecordAttr ( 'account_id' ));
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
if ( ! empty ( $item [ 'product_id' ])) {
include_once ( PATH_MODULES . 'product/product.inc.php' );
$po = new product ( $item [ 'product_id' ]);
$ito -> setRecordAttr ( 'product_name' , $po -> getTranslateField ( 'name' ));
$ito -> setRecordAttr ( 'product_id' , $po -> getRecordAttr ( 'id' ));
// $ito->setRecordAttr('sku',$po->getRecordAttr('sku'));
$ito -> setRecordAttr ( 'quantity' , isset ( $item [ 'quantity' ]) ? $item [ 'quantity' ] : 1 );
$ito -> setRecordAttr ( 'price_type' , $po -> getRecordAttr ( 'price_type' ));
$ito -> setRecordAttr ( 'recurring_schedule' , isset ( $item [ 'recurring_schedule' ]) ? $item [ 'recurring_schedule' ] : $po -> getRecordAttr ( 'price_recurr_default' ));
if ( isset ( $item [ 'price_base' ]))
$ito -> setBaseRate ( $item [ 'price_base' ]);
else {
$price = $po -> price_prod (
array (
'price_type' => $po -> getRecordAttr ( 'price_type' ),
'price_recurr_type' => $po -> getRecordAttr ( 'price_recurr_type' ),
'price_recurr_weekday' => $po -> getRecordAttr ( 'price_recurr_weekday' ),
'price_recurr_week' => $po -> getRecordAttr ( 'price_recurr_week' ),
'price_group' => $po -> getRecordAttr ( 'price_group' ),
'price_base' => $po -> getRecordAttr ( 'price_base' ),
'price_setup' => $po -> getRecordAttr ( 'price_setup' )),
$ito -> getRecordAttr ( 'recurring_schedule' ), $this -> getRecordAttr ( 'account_id' ), false );
$ito -> setRecordAttr ( 'price_setup' , isset ( $item [ 'price_setup' ]) ? $item [ 'price_setup' ] : $price [ 'setup' ]);
$ito -> setBaseRate ( $price [ 'base' ]);
}
$billdates = $po -> recurrDates ( $ito -> getRecordAttr ( 'recurring_schedule' ), $po -> getRecordAttr ( 'recur_weekday' ), null ,
is_null ( $ito -> getRecordAttr ( 'date_start' )) ? time () : $ito -> getRecordAttr ( 'date_start' ));
$ito -> setRecordAttr ( 'date_start' , $billdates [ 'date' ]);
$ito -> setRecordAttr ( 'date_stop' , $billdates [ 'end' ]);
$ito -> setProRata ( $billdates [ 'prorata' ]);
} elseif ( ! empty ( $item [ 'charge_id' ])) {
} elseif ( $item [ 'type' ] == 'domain' ) {
include_once ( PATH_MODULES . 'host_tld/host_tld.inc.php' );
$hto = new host_tld ();
#@todo - TEMP until we have another recurrDates() function that we can use.
include_once ( PATH_MODULES . 'product/product.inc.php' );
$po = new product ();
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
$tld = $hto -> sql_GetRecords ( array ( 'where' => array ( 'name' => $item [ 'domain_tld' ])));
if ( ! count ( $tld )) { printf ( 'NO TLD FOR %s??' , $item [ 'domain_tld' ]); die ();};
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
$tld = array_pop ( $tld );
$pg = unserialize ( $tld [ 'price_group' ]);
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# @todo - need to improve this code after reworking host_tld
switch ( @ $item [ 'host_type' ]) {
case 'register' :
$ito -> setRecordAttr ( 'product_name' , 'Domain Name Register' );
break ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
default :
$ito -> setRecordAttr ( 'product_name' , 'Domain Name Renewal' );
}
$ito -> setRecordAttr ( 'recurring_schedule' , isset ( $item [ 'recurring_schedule' ]) ? $item [ 'recurring_schedule' ] : 5 ); // get this from host_tld
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$billdates = $po -> recurrDates ( $ito -> getRecordAttr ( 'recurring_schedule' ), null , null ,
is_null ( $ito -> getRecordAttr ( 'date_start' )) ? time () : $ito -> getRecordAttr ( 'date_start' ), true );
$ito -> setRecordAttr ( 'date_start' , $billdates [ 'date' ]);
$ito -> setRecordAttr ( 'date_stop' , $billdates [ 'end' ]);
$ito -> setProRata ( $billdates [ 'prorata' ]);
$ito -> setRecordAttr ( 'price_type' , 1 );
$ito -> setRecordAttr ( 'price_setup' , 0 );
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( is_null ( $ito -> getRecordAttr ( 'price' ))) {
include_once ( PATH_MODULES . 'host_tld/host_tld.inc.php' );
$tldObj = new host_tld ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
$tldprice = $tldObj -> price_tld_arr ( $ito -> getRecordAttr ( 'domain_tld' ), $item [ 'host_type' ],
false , false , false , $ito -> getRecordAttr ( 'account_id' ));
$ito -> setBaseRate ( $tldprice [ $ito -> getRecordAttr ( 'domain_term' )]);
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
} else {
echo '<PRE>' ; print_r ( array ( 'i' => $item , 'ii' => $ito ));
echo '<B>NEED TO FIGURE OUT THE PRICE IF WE ARE NOT A PRODUCT</B>' ; die ();
$ito -> setRecordAttr ( 'price_setup' , 0 );
$ito -> setRecordAttr ( 'recurring_schedule' , isset ( $item [ 'recurr_schedule' ]) ? $item [ 'recurr_schedule' ] : 0 );
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# If we are a cart, we'll set a cart ID, so the item can be deleted.
if ( isset ( $item [ 'cart_id' ]))
$ito -> setRecordAttr ( 'cart_id' , $item [ 'cart_id' ]);
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
array_push ( $this -> items , $ito );
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# Return the item id.
return count ( $this -> items ) - 1 ;
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
public function sCountItems () {
return count ( $this -> items );
2008-11-26 22:50:40 +00:00
}
2010-11-29 22:41:08 +00:00
public function getItems () {
$items = array ();
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
foreach ( $this -> items as $item )
array_push ( $items , $item -> getRecord ());
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
return $items ;
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
public function getProductItems () {
$items = array ();
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
foreach ( $this -> items as $item )
if ( ! is_null ( $item -> getRecordAttr ( 'product_id' )))
array_push ( $items , $item -> getRecordAttr ( 'product_id' ));
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
return $items ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
public function getProductItemTypes () {
$items = array ();
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
foreach ( $this -> items as $item )
if ( ! is_null ( $item -> getRecordAttr ( 'price_type' )))
array_push ( $items , $item -> getRecordAttr ( 'price_type' ));
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
return array_unique ( $items , SORT_NUMERIC );
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
/**
* This function will get all the discount codes used in the invoice
* it will also cause all the discounts to be re - calcated
*/
public function getDiscountDetails () {
$discounts = array ();
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
foreach ( $this -> items as $item )
foreach ( $item -> getDiscountArr ( $this -> sSubTotal ()) as $discount )
@ $discounts [ $discount [ 'discount' ]] += $discount [ 'amount' ];
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$d = array ();
foreach ( $discounts as $k => $v )
array_push ( $d , array ( 'name' => $k , 'total' => $v ));
return $d ;
2008-11-26 22:50:40 +00:00
}
2010-11-29 22:41:08 +00:00
public function sTotalDiscount ( $recalc = false ) {
$total = 0 ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( $recalc )
$this -> getDiscountDetails ();
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
foreach ( $this -> items as $item )
$total += $item -> getRecordAttr ( 'discount_amt' );
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
return $total ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# @todo change this to work the same way as getDiscountDetails()
public function getTaxDetails () {
$taxes = array ();
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
foreach ( $this -> items as $item )
foreach ( $item -> getTaxArr () as $tax )
@ $taxes [ $tax [ 'name' ]] += $tax [ 'rate' ];
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
return $taxes ;
2009-08-03 04:10:16 +00:00
}
2010-11-29 22:41:08 +00:00
public function sTotalTax ( $recalc ) {
$total = 0 ;
if ( $recalc )
$this -> getTaxDetails ();
foreach ( $this -> items as $item )
$total += $item -> getRecordAttr ( 'tax_amt' );
return $total ;
2008-11-26 22:50:40 +00:00
}
/**
2010-11-29 22:41:08 +00:00
* This function will calculate the pre - tax / pre - discounted totals for this invoice
*/
public function sSubTotal ( $calc = false ) {
static $total ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
if ( $total && ! $calc )
return $total ;
else
$total = 0 ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
foreach ( $this -> items as $item )
$total += $item -> sGetSubTotalAmt ();
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
return $total ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
public function sTotal ( $calc = false ) {
static $total ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( $total && ! $calc )
return $total ;
else
$total = 0 ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
foreach ( $this -> items as $item )
$total += $item -> sGetTotalAmt ( $calc );
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
return $total ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
/**
* Calculate the recurring amount for this invoice
*
* The recurring amount is only applicable if all items have the same recur_schedule
*/
public function sRecurAmt ( $calc = false ) {
static $total ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( ! is_null ( $total ) && ! $calc )
return $total ;
else
$total = null ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$sched = null ;
foreach ( $this -> items as $item ) {
if ( is_null ( $sched ))
$sched = $item -> getRecordAttr ( 'recurring_schedule' );
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( $sched != $item -> getRecordAttr ( 'recurring_schedule' ))
return null ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$total += $item -> sGetRecurAmt ();
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
return $total ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
public function sql_SaveRecord ( $noconvert = false ) {
global $VAR ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# (Re)Calculate our discounts and taxes
$this -> setRecordAttr ( 'discount_amt' , $this -> sTotalDiscount ( true ));
$this -> setRecordAttr ( 'tax_amt' , $this -> sTotalTax ( true ));
$this -> setRecordAttr ( 'total_amt' , $this -> sTotal ( true ));
# Save the invoice and items
# @todo make this into a transaction, so if the item records fail, we dont have a partial save
if ( $id = parent :: sql_SaveRecord ( $noconvert )) {
foreach ( $this -> items as $item ) {
$item -> setRecordAttr ( 'invoice_id' , $id );
# Remove the cart id
$item -> delRecordAttr ( 'cart_id' );
if ( ! $item -> sql_SaveRecord ( $noconvert , false )) {
echo '<PRE>' ; print_r ( $item ); die ();
}
2009-08-03 04:10:16 +00:00
}
}
2010-11-29 22:41:08 +00:00
return $id ;
2008-11-26 22:50:40 +00:00
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
public function custom_tracking ( $VAR ) { return $this -> drCustomTracking ( $VAR ); }
2009-08-03 04:10:16 +00:00
/**
2010-11-29 22:41:08 +00:00
* Custom Tracking
2009-08-03 04:10:16 +00:00
*/
2010-11-29 22:41:08 +00:00
public function drCustomTracking ( $VAR ) {
# If we dont have a tracking file, or we are not logged in, no point continuing.
if ( ! is_file ( PATH_FILES . 'tracking.txt' ) || ! SESS_LOGGED )
2008-11-26 22:50:40 +00:00
return false ;
2010-11-29 22:41:08 +00:00
# Check if we are in the iframe, otherwise render the iframe.
if ( empty ( $VAR [ '_escape' ]) || empty ( $VAR [ 'confirm' ])) {
printf ( '<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:drCustomTracking&rand=%s"></iframe>' ,
md5 ( microtime ()));
return ;
2008-11-26 22:50:40 +00:00
}
2010-11-29 22:41:08 +00:00
# Get the un-tracked invoice details
2009-08-03 04:10:16 +00:00
$db = & DB ();
2010-11-29 22:41:08 +00:00
$result = $this -> sql_GetRecords ( array ( 'where' => sprintf ( '(custom_affiliate_status IS NULL OR custom_affiliate_status=0) AND billing_status=1 AND account_id=%s' , SESS_ACCOUNT )));
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
if ( ! count ( $result ))
return false ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Get the totals
$invoice = '' ;
$total_amount = 0 ;
foreach ( $result as $record ) {
if ( ! empty ( $invoice ))
$invoice .= '-' ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$invoice .= $record [ 'id' ];
$total_amount += $record [ 'total_amt' ];
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Echo the custom tracking code to the screen:
$tracking = file_get_contents ( PATH_FILES . 'tracking.txt' );
$tracking = str_replace ( '%%amount%%' , $total_amount , $tracking );
$tracking = str_replace ( '%%invoice%%' , $invoice , $tracking );
$tracking = str_replace ( '%%affiliate%%' , SESS_AFFILIATE , $tracking );
$tracking = str_replace ( '%%campaign%%' , SESS_CAMPAIGN , $tracking );
$tracking = str_replace ( '%%account%%' , SESS_ACCOUNT , $tracking );
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
echo $tracking ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Update the record so it is not tracked again
$rs = $db -> Execute (
sqlUpdate ( 'invoice' , array ( 'custom_affiliate_status' => 1 ), array ( 'where' => sprintf ( 'account_id=%s AND billing_status=1' , SESS_ACCOUNT ))));
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( $rs === false ) {
global $C_debug ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$C_debug -> error ( __FILE__ , __METHOD__ , sprintf ( '%s (%s)' , $db -> ErrorMsg (), $sql ));
2009-08-03 04:10:16 +00:00
}
2010-11-29 22:41:08 +00:00
return true ;
2009-08-03 04:10:16 +00:00
}
2010-11-29 22:41:08 +00:00
public function autoApproveInvoice ( $id ) { return $this -> pAutoApprove ( $id ); }
2009-08-03 04:10:16 +00:00
/**
2010-11-29 22:41:08 +00:00
* Auto approve Invoice
2009-08-03 04:10:16 +00:00
*/
2010-11-29 22:41:08 +00:00
public function pAutoApprove ( $id ) {
$db = & DB ();
$do = false ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Get the invoice details
$invoices = $this -> sql_GetRecords ( array ( 'where' => array ( 'id' => $id , 'process_status' => 0 )));
if ( ! count ( $invoices ))
return false ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$invoice = array_pop ( $invoices );
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Get the checkout details
$checkout = $db -> Execute ( sqlSelect ( 'checkout' , '*' , array ( 'where' => array ( 'id' => $invoice [ 'checkout_plugin_id' ]))));
if ( ! $checkout ) {
global $C_debug ;
$C_debug -> error ( __FILE__ , __METHOD__ , $db -> ErrorMsg ());
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
return false ;
2009-08-03 04:10:16 +00:00
}
2010-11-29 22:41:08 +00:00
# Get the account details
$account = $db -> Execute ( sqlSelect ( 'account' , '*' , array ( 'where' => array ( 'id' => $invoice [ 'account_id' ]))));
if ( $account ) {
global $C_debug ;
$C_debug -> error ( __FILE__ , __METHOD__ , $db -> ErrorMsg ());
2009-08-03 04:10:16 +00:00
return false ;
2010-11-29 22:41:08 +00:00
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Is this a recurring invoices, and is manual approvale req?
if ( $invoice [ 'type' ] == 1 && $checkout -> fields [ 'manual_approval_recur' ] != 1 )
$do = true ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Manual approval required for all?
if ( $invoice [ 'type' ] != 1 && $checkout -> fields [ 'manual_approval_all' ] != 1 )
$do = true ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
if ( ! $do ) {
# Manual approval required for invoice amount?
if ( ! empty ( $checkout -> fields [ 'manual_approval_amount' ]) && $do == true )
if ( $checkout -> fields [ 'manual_approval_amount' ] <= $invoice [ 'total_amt' ])
$do = false ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Manual approval required for user's country?
if ( ! empty ( $checkout -> fields [ 'manual_approval_country' ]) && $do == true ) {
$arr = unserialize ( $checkout -> fields [ 'manual_approval_country' ]);
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
for ( $i = 0 ; $i < count ( $arr ); $i ++ )
if ( $account -> fields [ 'country_id' ] == $arr [ $i ])
$do = false ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Manual approval req. for user's currency?
if ( ! empty ( $checkout -> fields [ 'manual_approval_currency' ]) && $do == true ) {
$arr = unserialize ( $checkout -> fields [ 'manual_approval_currency' ]);
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
for ( $i = 0 ; $i < count ( $arr ); $i ++ )
if ( $invoice [ 'actual_billed_currency_id' ] == $arr [ $i ])
$do = false ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Manual approval required for user's group(s)?
if ( ! empty ( $checkout -> fields [ 'manual_approval_group' ]) && $do == true ) {
# Get the group details
$groups = $db -> Execute ( sqlSelect ( 'account_group' , 'group_id' , array ( 'where' => array ( 'account_id' => $invoice [ 'account_id' ], 'active' => 1 ))));
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( ! $groups ) {
global $C_debug ;
$C_debug -> error ( __FILE__ , __METHOD__ , $db -> ErrorMsg ());
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
return false ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$arr = unserialize ( $checkout -> fields [ 'manual_approval_group' ]);
while ( ! $groups -> EOF ) {
for ( $i = 0 ; $i < count ( $arr ); $i ++ ) {
$idx = $groups -> fields [ 'group_id' ];
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( $idx == $arr [ $i ])
$do = false ;
2008-11-26 22:50:40 +00:00
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$groups -> MoveNext ();
2008-11-26 22:50:40 +00:00
}
2009-08-03 04:10:16 +00:00
}
2010-11-29 22:41:08 +00:00
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Approve the invoice
if ( $do )
$this -> pApprove ( $id );
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
else {
# Admin manual approval notice
include_once ( PATH_MODULES . 'email_template/email_template.inc.php' );
$mail = new email_template ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$mail -> send ( 'invoice_manual_auth_admin' , $invoice [ 'account_id' ], $invoice [ 'id' ], $invoice [ 'checkout_plugin_id' ], '' );
}
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
public function approveInvoice ( $id ) { return $this -> pApprove ( $id ); }
/**
* Approve an invoice , which will enable services to be provisioned .
*
* @ param int $id Invoice ID to approve
* @ uses service
*/
public function pApprove ( $id ) {
$db = & DB ();
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Get the invoice details
$invoices = $this -> sql_GetRecords ( array ( 'where' => array ( 'id' => $id , 'process_status' => 0 )));
if ( ! count ( $invoices ))
return false ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$invoice = array_pop ( $invoices );
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Update the invoice approval status:
$rs = $db -> Execute ( sqlUpdate ( 'invoice' , array ( 'date_last' => time (), 'process_status' => 1 ), array ( 'where' => array ( 'id' => $id ))));
if ( ! $rs ) {
global $C_debug ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
$C_debug -> error ( __FILE__ , __METHOD__ , $db -> ErrorMsg ());
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
return false ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Send approval notice to user:
2008-11-26 22:50:40 +00:00
include_once ( PATH_MODULES . 'email_template/email_template.inc.php' );
$mail = new email_template ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$mail -> send ( 'invoice_approved_user' , $invoice [ 'account_id' ], $id , '' , '' );
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Include the service class
include_once ( PATH_MODULES . 'service/service.inc.php' );
$so = new service ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# Determine if services have already been created for this invoice
switch ( $invoice [ 'type' ]) {
# Recurring invoice, just update assoc services
case 1 :
# Loop through invoice items & approve assoc services
$rs = $db -> Execute ( sqlSelect ( 'invoice_item' , 'service_id' , array ( 'where' => array ( 'invoice_id' => $id ))));
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( ! $rs ) {
global $C_debug ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$C_debug -> error ( __FILE__ , __METHOD__ , $db -> ErrorMsg ());
return false ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Update services status
if ( $rs -> RecordCount ())
while ( ! $rs -> EOF ) {
$so -> approveService ( $rs -> fields [ 'service_id' ]);
$rs -> MoveNext ();
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
break ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
default :
$rs = $db -> Execute ( sqlSelect ( 'service' , 'id' , array ( 'where' => array ( 'invoice_id' => $id ))));
if ( ! $rs ) {
global $C_debug ;
$C_debug -> error ( __FILE__ , __METHOD__ , $db -> ErrorMsg ());
return false ;
2008-11-26 22:50:40 +00:00
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# If there are already existing services, just update their status
if ( $rs -> RecordCount ()) {
while ( ! $rs -> EOF ) {
$so -> approveService ( $rs -> fields [ 'id' ]);
$rs -> MoveNext ();
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# No services exist, they can be provisioned
} else {
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Get the invoice items in this invoice
$ii = $db -> Execute ( sqlSelect ( 'invoice_item' , '*' , array ( 'where' => sprintf ( '(parent_id IN (0,"") OR parent_id IS NULL)' ))));
if ( ! $ii ) {
global $C_debug ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$C_debug -> error ( __FILE__ , __METHOD__ , $db -> ErrorMsg ());
return false ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
while ( ! $ii -> EOF ) {
if ( ! $ii -> fields [ 'service_id' ]) {
# Add the service
$so -> invoiceItemToService ( $ii -> fields [ 'id' ], $invoice );
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Check for any children items in this invoice
$iii = $db -> Execute ( sqlSelect ( 'invoice_item' , '*' , array ( 'where' => array ( 'parent_id' => $ii -> fields [ 'id' ], 'invoice_id' => $id ))));
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( ! $iii ) {
global $C_debug ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$C_debug -> error ( __FILE__ , __METHOD__ , $db -> ErrorMsg ());
return false ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
while ( ! $iii -> EOF ) {
# Add the service
$so -> invoiceItemToService ( $iii -> fields [ 'id' ], $invoice );
$iii -> MoveNext ();
}
} else {
# This is a domain renewal
if ( $ii -> fields [ 'item_type' ] == 2 && $ii -> fields [ 'domain_type' ] == 'renew' )
$so -> renewDomain ( $ii , $invoice -> fields [ 'account_billing_id' ]);
# This is an upgrade for an existing service
else
$so -> modifyService ( $ii , $invoice -> fields [ 'account_billing_id' ]);
}
$ii -> MoveNext ();
}
}
}
# Create a memo
$rs = $db -> Execute ( sqlInsert ( $db , 'invoice_memo' , array (
'date_orig' => time (),
'invoice_id' => $id ,
'account_id' => ( defined ( 'SESS_ACCOUNT' )) ? SESS_ACCOUNT : 0 ,
'type' => 'approval' ,
'memo' => _ ( 'Invoice Approved' )
)));
2009-08-03 04:10:16 +00:00
if ( ! $rs ) {
global $C_debug ;
2010-11-29 22:41:08 +00:00
$C_debug -> error ( __FILE__ , __METHOD__ , $db -> ErrorMsg ());
return false ;
2009-08-03 04:10:16 +00:00
}
2010-11-29 22:41:08 +00:00
return true ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
public function voidInvoice ( $id ) { return $this -> pVoid ( $id ); }
/**
* Void an invoice , which will suspend services .
*/
public function pVoid ( $id ) {
$db = & DB ();
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Get the invoice details
$invoices = $this -> sql_GetRecords ( array ( 'where' => array ( 'id' => $id , 'process_status' => 1 )));
if ( ! count ( $invoices ))
return false ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Update the invoice approval status:
$rs = $db -> Execute ( sqlUpdate ( 'invoice' , array ( 'date_last' => time (), 'process_status' => 0 ), array ( 'where' => array ( 'id' => $id ))));
if ( ! $rs ) {
global $C_debug ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$C_debug -> error ( __FILE__ , __METHOD__ , $db -> ErrorMsg ());
return false ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Determine if services have already been created for this invoice and deactivate
$rs = $db -> Execute ( sqlSelect ( 'service' , 'id' , array ( 'where' => array ( 'invoice_id' => $id ))));
if ( ! $rs ) {
global $C_debug ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$C_debug -> error ( __FILE__ , __METHOD__ , $db -> ErrorMsg ());
2009-08-03 04:10:16 +00:00
return false ;
2010-11-29 22:41:08 +00:00
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Include the service class
2009-08-03 04:10:16 +00:00
include_once ( PATH_MODULES . 'service/service.inc.php' );
2010-11-29 22:41:08 +00:00
$so = new service ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( $rs -> RecordCount ()) {
# Update services to inactive status:
while ( ! $rs -> EOF ) {
$so -> voidService ( $rs -> fields [ 'id' ]);
$rs -> MoveNext ();
}
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Loop through invoice items & delete assoc services
$rs = $db -> Execute ( sqlSelect ( 'invoice_item' , 'service_id' , array ( 'where' => array ( 'invoice_id' => $id ))));
if ( ! $rs ) {
global $C_debug ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$C_debug -> error ( __FILE__ , __METHOD__ , $db -> ErrorMsg ());
return false ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Update services to inactive status
if ( $rs -> RecordCount ()) {
while ( ! $rs -> EOF ) {
$so -> voidService ( $rs -> fields [ 'service_id' ]);
$rs -> MoveNext ();
2008-11-26 22:50:40 +00:00
}
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# If voided, create a memo
$rs = $db -> Execute ( sqlInsert ( $db , 'invoice_memo' , array (
'date_orig' => time (),
'invoice_id' => $id ,
'account_id' => ( defined ( 'SESS_ACCOUNT' )) ? SESS_ACCOUNT : 0 ,
'type' => 'void' ,
'memo' => _ ( 'Invoice Voided' )
)));
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( ! $rs ) {
2009-08-03 04:10:16 +00:00
global $C_debug ;
$C_debug -> error ( __FILE__ , __METHOD__ , $db -> ErrorMsg ());
return false ;
}
2010-11-29 22:41:08 +00:00
return true ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
/**
* Reconcile Invoice
*/
public function reconcile ( $VAR ) {
global $C_translate , $C_debug , $C_list ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$db = & DB ();
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Reconcile is disabled when payment is installed
# @todo Think of a better way (dynamic) to handle this
if ( ! $C_list -> is_installed ( 'payment' )) {
$C_debug -> alert ( 'Reconcile is disabled, please use the payment option!' );
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
return false ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Validate amt
if ( $VAR [ 'amount' ] <= 0 ) {
$C_debug -> alert ( _ ( 'Payment amount to low!' ));
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
return false ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Get the invoice details
$invoices = $this -> sql_GetRecords ( array ( 'where' => array ( 'id' => $VAR [ 'id' ])));
if ( ! count ( $invoices ))
return false ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$invoice = array_pop ( $invoices );
$billing_status = 1 ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( $VAR [ 'amount' ] > $invoice [ 'total_amt' ] - $invoice [ 'billed_amt' ]) {
$update = $invoice [ 'total_amt' ];
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$C_translate -> value [ 'invoice' ][ 'amt' ] = number_format ( $VAR [ 'amount' ] - $invoice [ 'total_amt' ] - $invoice [ 'billed_amt' ], 2 );
$alert = $C_translate -> translate ( 'rec_over' , 'invoice' , '' );
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
} elseif ( $VAR [ 'amount' ] == $invoice [ 'total_amt' ] - $invoice [ 'billed_amt' ]) {
$update = $invoice [ 'total_amt' ];
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
} else {
$update = $VAR [ 'amount' ] + $invoice [ 'billed_amt' ];
$billing_status = 0 ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Update the invoice record
$rs = $db -> Execute (
sqlUpdate ( 'invoice' , array ( 'date_last' => time (), 'billed_amt' => $update , 'billing_status' => $billing_status ),
array ( 'where' => array ( 'id' => $VAR [ 'id' ]))));
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Create a memo
$rs = $db -> Execute ( sqlInsert ( $db , 'invoice_memo' , array (
'date_orig' => time (),
'invoice_id' => $VAR [ 'id' ],
'account_id' => ( defined ( 'SESS_ACCOUNT' )) ? SESS_ACCOUNT : 0 ,
'type' => 'reconcile' ,
'memo' => sprintf ( '%s: %s (%s)' , _ ( 'Payment Added to Invoice' ), number_format ( $VAR [ 'amount' ], 2 ), isset ( $VAR [ 'memo' ]) ? $VAR [ 'memo' ] : '' )
)));
# Receipt printing
# @todo Move this to be consistent with invoice printing.
include_once PATH_MODULES . 'invoice/receipt_print.php' ;
$receipt = new receipt_print ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$receipt -> add ( $invoice , number_format ( $VAR [ 'amount' ], 2 ), number_format ( $update , 2 ));
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Auto update if billed complete
if ( $billing_status ) {
$this -> autoApproveInvoice ( $VAR [ 'id' ]);
# User invoice creation confirmation
include_once ( PATH_MODULES . 'email_template/email_template.inc.php' );
$email = new email_template ;
$email -> send ( 'invoice_paid_user' , $invoice [ 'account_id' ], $VAR [ 'id' ], $invoice [ 'billed_currency_id' ], '' );
# Admin alert of payment processed
$email = new email_template ;
$email -> send ( 'admin->invoice_paid_admin' , $invoice [ 'account_id' ], $VAR [ 'id' ], $invoice [ 'billed_currency_id' ], '' );
2009-08-03 04:10:16 +00:00
}
2010-11-29 22:41:08 +00:00
# Redirect
if ( ! empty ( $VAR [ 'redirect' ])) {
printf ( '<script type="text/javascript">window.parent.location="%s";' , $VAR [ 'redirect' ]);
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( ! empty ( $alert ))
printf ( 'alert("%s");' , $alert );
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
echo '</script>' ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
exit ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$C_debug -> alert ( $C_translate -> translate ( 'ref_comp' , 'invoice' , '' ));
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
return ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
/**
* Refund Invoice
*/
public function refund ( $VAR ) {
global $C_translate , $C_debug ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Validate amt
if ( $VAR [ 'amount' ] <= 0 ) {
$C_debug -> alert ( _ ( 'Refund amount to low!' ));
2009-08-03 04:10:16 +00:00
2008-11-26 22:50:40 +00:00
return false ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$update = $this -> getRecordAttr ( 'billed_amt' ) - $VAR [ 'amount' ];
$billing_status = ( $update > 0 ) ? 1 : 0 ;
# Update the invoice record
$rs = $db -> Execute (
sqlUpdate ( 'invoice' ,
array ( 'date_last' => time (), 'billed_amt' => $update , 'billing_status' => $billing_status , 'suspend_billing' => 1 , 'refund_status' => 1 ),
array ( 'where' => array ( 'id' => $VAR [ 'id' ]))));
if ( ! $rs ) {
$C_debug -> error ( __FILE__ , __METHOD__ , $db -> ErrorMsg ());
return false ;
2008-11-26 22:50:40 +00:00
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Create a memo
$rs = $db -> Execute ( sqlInsert ( $db , 'invoice_memo' , array (
'date_orig' => time (),
'invoice_id' => $VAR [ 'id' ],
'account_id' => ( defined ( 'SESS_ACCOUNT' )) ? SESS_ACCOUNT : 0 ,
'type' => 'refund' ,
'memo' => sprintf ( '%s: %s (%s)' , _ ( 'Refunded Invoice' ), number_format ( $VAR [ 'amount' ], 2 ), isset ( $VAR [ 'memo' ]) ? $VAR [ 'memo' ] : '' )
)));
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( ! $rs ) {
$C_debug -> error ( __FILE__ , __METHOD__ , $db -> ErrorMsg ());
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
return false ;
2008-11-26 22:50:40 +00:00
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Void
$this -> pVoid ( $VAR [ 'id' ]);
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Call into the checkout plugin and attempt realtime refund
$C_debug -> alert ( 'Realtime refund processing not enabled.' );
if ( ! true ) {
$billing = $db -> Execute (
sqlSelect ( $db ,
array ( 'account_billing' , 'checkout' ),
'A.*,B.checkout_plugin' , sprintf ( 'A.id=%s AND A.checkout_plugin_id=B.id' , $this -> getRecordAttr ( 'account_billing_id' ))));
if ( $billing && $billing -> RecordCount () && ! empty ( $billing -> fields [ 'checkout_plugin' ])) {
$plugin_file = sprintf ( '%scheckout/%s.php' , PATH_PLUGINS , $billing -> fields [ 'checkout_plugin' ]);
if ( is_file ( $plugin_file )) {
include_once ( $plugin_file );
eval ( sprintf ( '$PLG = new plg_chout_%s("%s");' , $billing -> fields [ 'checkout_plugin' ], $billing -> fields [ 'checkout_plugin_id' ]));
if ( is_callable ( array ( $PLG , 'refund' )))
$PLG -> refund ( $this -> getRecord (), $billing -> fields , $VAR [ 'amount' ]);
}
2008-11-26 22:50:40 +00:00
}
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Redirect
if ( ! empty ( $VAR [ 'redirect' ])) {
printf ( '<script type="text/javascript">window.parent.location="%s";' , $VAR [ 'redirect' ]);
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
return ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$C_debug -> alert ( $C_translate -> translate ( 'ref_comp' , 'invoice' , '' ));
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
return ;
2008-11-26 22:50:40 +00:00
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
/**
* Resend due notice
*
* @ uses email_template
*/
public function resend ( $VAR ) {
global $C_debug ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$db = & DB ();
2008-11-26 22:50:40 +00:00
# User invoice creation confirmation
include_once ( PATH_MODULES . 'email_template/email_template.inc.php' );
$mail = new email_template ;
2010-11-29 22:41:08 +00:00
$mail -> send ( 'invoice_resend' , $this -> getRecordAttr ( 'account_id' ), $this -> getRecordAttr ( 'id' ), '' , '' );
# Alert
$C_debug -> alert ( 'Sent payment due notice to user' );
# Update invoice
$db -> Execute ( sqlUpdate ( 'invoice' , array ( 'notice_count' => $this -> getRecordAttr ( 'notice_count' ) + 1 ), array ( 'id' => $this -> getRecordAttr ( 'id' ))));
}
/**
* Initialise an invoice
*
* This function is responsible for getting all the information required to render an invoice .
*/
private function initInvoicePrint () {
# Check admin authentication:
global $C_auth ;
2009-08-03 04:10:16 +00:00
$db = & DB ();
2010-11-29 22:41:08 +00:00
if ( $C_auth -> auth_method_by_name ( 'invoice' , 'pdf' ) == false ) {
if ( $this -> getRecordAttr ( 'account_id' ) != SESS_ACCOUNT )
2008-11-26 22:50:40 +00:00
return false ;
}
2010-11-29 22:41:08 +00:00
$invoice = array ();
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
#@todo this should be in setup_invoice
$invoice [ 'site' ][ 'TAXID' ] = SITE_TAXID ;
$invoice [ 'site' ][ 'NAME' ] = SITE_NAME ;
$invoice [ 'site' ][ 'ADDRESS' ] = SITE_ADDRESS ;
$invoice [ 'site' ][ 'CITY' ] = SITE_CITY ;
$invoice [ 'site' ][ 'STATE' ] = SITE_STATE ;
$invoice [ 'site' ][ 'ZIP' ] = SITE_ZIP ;
$invoice [ 'site' ][ 'FAX' ] = SITE_FAX ;
$invoice [ 'site' ][ 'PHONE' ] = SITE_PHONE ;
$invoice [ 'site' ][ 'EMAIL' ] = SITE_EMAIL ;
$invoice [ 'site' ][ 'URL' ] = URL ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Invoice Configuration
$rs = $db -> Execute ( sqlSelect ( $db , 'setup_invoice' , '*' , '' ));
$invoice [ 'invcfg' ] = $rs -> fields ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# Invoice details
$rs = $db -> Execute ( sqlSelect ( $db , array ( 'invoice' , 'currency' ), 'A.*,B.symbol' , sprintf ( 'A.id=%s AND B.id=A.billed_currency_id' , $this -> getRecordAttr ( 'id' ))));
$invoice [ 'invoice' ] = $rs -> fields ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# Account detail:
$rs = $db -> Execute ( sqlSelect ( $db , 'account' , '*' , array ( 'id' => $this -> getRecordAttr ( 'account_id' ))));
$invoice [ 'account' ] = $rs -> fields ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# If we get here, all is OK.
return $invoice ;
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
/**
* Display a HTML invoice in the browser or email
*/
public function html ( $VAR ) {
global $C_list ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
if ( ! isset ( $this -> record ) && isset ( $VAR [ 'id' ]))
$this -> sql_LoadRecord ( $VAR [ 'id' ]);
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# Get our invoice details
if ( ! $this -> print = $this -> initInvoicePrint ())
return false ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$return = '' ;
$return .= '<style type="text/css">' ;
$return .= 'table.data {width: 100%;vertical-align: top;empty-cells: show;border: 1px solid #AAAACC;border-spacing: 0px;background-color: #FEFEFE;}' ;
$return .= '</style>' ;
$return .= '<table border="0" style="width: 100%;">' ;
$return .= '<tr>' ;
#$return .= sprintf('<td style="width: 15%%;"><img src="cid:logoimg" alt="logo"/></td>',sprintf('%s/%s','/ab/themes/'.DEFAULT_THEME,'invoice/invoice-logo.png'));
$return .= '<td style="width: 5%;"><img src="cid:logoimg" alt="logo"/></td>' ;
$return .= '<td colspan="3" style="vertical-align: top;">' ;
$return .= '<table border="0" width="100%" style="blank">' ;
$return .= sprintf ( '<tr><td>%s</td></tr>' , $this -> print [ 'site' ][ 'NAME' ]);
$return .= sprintf ( '<tr><td style="font-size: 80%%;">%s %s %s</td></tr>' ,
$this -> print [ 'site' ][ 'ADDRESS' ], $this -> print [ 'site' ][ 'STATE' ], $this -> print [ 'site' ][ 'ZIP' ]);
$return .= '<tr><td> </td></tr>' ;
$return .= sprintf ( '<tr><td style="font-size: 80%%;">%s</td></tr>' , $this -> print [ 'site' ][ 'TAXID' ]);
$return .= '</table>' ;
$return .= '</td>' ;
$return .= '</tr>' ;
$return .= '<tr><td> </td></tr>' ;
$return .= sprintf ( '<tr><td colspan="2" style="width: 50%%";> </td><td>%s</td><td style="text-align: right;"><b>%s</b></td></tr>' ,
_ ( 'Tax Invoice' ), $this -> getPrintInvoiceNum ());
$return .= sprintf ( '<tr><td colspan="2"> </td><td>%s</td><td style="text-align: right;"><b>%s</b></td></tr>' ,
_ ( 'Issue Date' ), date ( UNIX_DATE_FORMAT , $this -> print [ 'invoice' ][ 'date_orig' ]));
$return .= sprintf ( '<tr><td colspan="2"> </td><td>%s</td><td style="text-align: right;"><b>%s</b></td></tr>' ,
_ ( 'Amount Due' ), date ( UNIX_DATE_FORMAT , $this -> print [ 'invoice' ][ 'due_date' ]));
$return .= sprintf ( '<tr><td colspan="2"> </td><td>%s</td><td style="text-align: right;"><b>%s</b></td></tr>' ,
_ ( 'Current Charges' ), $C_list -> format_currency_num ( $this -> print [ 'invoice' ][ 'total_amt' ], $this -> getRecordAttr ( 'currency_id' )));
$return .= '<tr><td> </td></tr>' ;
$return .= '<td colspan="4" style="vertical-align: top;">' ;
$return .= '<table border="0" width="100%" class="data">' ;
foreach ( $this -> sInvoiceItems () as $index => $items ) {
# Get the date range if set
if ( ! empty ( $items [ 'date_start' ]) && ! empty ( $items [ 'date_stop' ])) {
global $C_translate ;
$C_translate -> value ( 'invoice' , 'start' , date ( UNIX_DATE_FORMAT , $items [ 'date_start' ]));
$C_translate -> value ( 'invoice' , 'stop' , date ( UNIX_DATE_FORMAT , $items [ 'date_stop' ]));
}
$return .= sprintf ( '<tr><td>%s</td><td>%s</td><td style="text-align: right;">%s</td></tr>' ,
$items [ 'quantity' ], $this -> sLineItemDesc ( $index ), $C_list -> format_currency_num ( $items [ 'price_base' ], $this -> getRecordAttr ( 'currency_id' )));
if ( $items [ 'price_setup' ])
$return .= sprintf ( '<tr><td> </td><td>%s %s</td><td style="text-align: right;">%s</td></tr>' ,
$this -> sLineItemDesc ( $index ), _ ( 'Setup' ), $C_list -> format_currency_num ( $items [ 'price_base' ], $this -> getRecordAttr ( 'currency_id' )));
}
$return .= '<tr><td> </td></tr>' ;
if ( $this -> print [ 'invoice' ][ 'discount_amt' ])
$return .= sprintf ( '<tr style="font-size: 80%%;"><td> </td><td>%s</td><td style="text-align: right;">%s</td></tr>' ,
_ ( 'Discount' ), $C_list -> format_currency_num ( $this -> print [ 'invoice' ][ 'discount_amt' ], $this -> getRecordAttr ( 'currency_id' )));
if ( $this -> print [ 'invoice' ][ 'tax_amt' ])
$return .= sprintf ( '<tr style="font-size: 80%%;"><td> </td><td>%s</td><td style="text-align: right;">%s</td></tr>' ,
_ ( 'Taxes' ), $C_list -> format_currency_num ( $this -> print [ 'invoice' ][ 'tax_amt' ], $this -> getRecordAttr ( 'currency_id' )));
$return .= '<tr><td> </td></tr>' ;
$return .= sprintf ( '<tr><td> </td><td><b>%s</b></td><td style="text-align: right;"><b>%s</b></td></tr>' ,
_ ( 'Total Due' ), $C_list -> format_currency_num ( $this -> print [ 'invoice' ][ 'total_amt' ], $this -> getRecordAttr ( 'currency_id' )));
$return .= '</table>' ;
$return .= '</td>' ;
$return .= '</tr>' ;
$return .= '</table>' ;
return $return ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
/**
* Display a PDF invoice in the browser for download .
*
* This method can be called directly via do [] .
*
* @ return string PDF Output ( only if dest => S ), otherwise PDF returns an empty string .
*/
public function pdf ( $VAR , $object , $args = array ( 'dest' => 'I' )) {
if ( ! isset ( $this -> record ) && isset ( $VAR [ 'id' ]))
$this -> sql_LoadRecord ( $VAR [ 'id' ]);
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( ! $pdf = $this -> initInvoicePDF ())
return false ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# If we called as a do[] method, we need to set the output correctly
if ( isset ( $VAR [ '_page' ]))
$args = array ( 'dest' => 'I' );
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
$this -> pdfInvoiceSummary ( $pdf );
return $pdf -> Output ( $args [ 'file' ] ? $args [ 'file' ] : sprintf ( '%s.pdf' , $this -> getPrintInvoiceID ()), $args [ 'dest' ]);
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
/**
* Initialise a PDF invoice
*
* This function is resonsible for setting up a PDF invoice
*/
private function initInvoicePDF () {
# Get our invoice details
if ( ! $this -> print = $this -> initInvoicePrint ())
return false ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
#@todo since the view template dynamic finds available plugins, this should also find the plugin (incase the prefix/dir is moved).
require_once ( sprintf ( '%sinvoice/PDF/pdf_invoice_%s.inc.php' , PATH_MODULES , $this -> print [ 'invcfg' ][ 'invoice_pdf_plugin' ]));
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
$pdf = new pdf_invoice_overview ( $this );
$pdf -> load_setup ();
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( $pdf -> getTemplate ()) {
$pagecount = $pdf -> setSourceFile ( $pdf -> getTemplate ());
$tplidx = $pdf -> ImportPage ( 1 );
2008-11-26 22:50:40 +00:00
}
2010-11-29 22:41:08 +00:00
$pdf -> addPage ();
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# If we are using FPDI
if ( isset ( $tplidx ))
$pdf -> useTemplate ( $tplidx );
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# If we get here, all is OK.
return $pdf ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
/** HERE **/
/** Export multiple invoices */
function pdfExport ( & $rs )
{
$db =& DB ();
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 ();
if ( $pdf -> getTemplate ())
$pagecount = $pdf -> setSourceFile ( $pdf -> getTemplate ());
$tplidx = $pdf -> ImportPage ( 1 );
while ( ! $rs -> EOF ) {
$pdf -> addPage ();
$pdf -> useTemplate ( $tplidx );
$this -> pdfInvoiceSummary ( $pdf );
$rs -> MoveNext ();
unset ( $pdf -> itemsSummary );
}
$pdf -> Output ();
ob_end_flush ();
2008-11-26 22:50:40 +00:00
}
/**
2010-11-29 22:41:08 +00:00
* Render an invoice with the summary page
2009-08-03 04:10:16 +00:00
*
2010-11-29 22:41:08 +00:00
* @ todo Draw discounts
* @ todo Draw tax details
2008-11-26 22:50:40 +00:00
*/
2010-11-29 22:41:08 +00:00
private function pdfInvoiceSummary ( $pdf ) {
# Invoice details:
2008-11-26 22:50:40 +00:00
$db = & DB ();
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Draw Invoice Basics
$pdf -> drawCompanyLogo ();
$pdf -> drawCompanyAddress ( $this );
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$pdf -> drawInvoiceHeader ( $this );
$pdf -> drawNews ( $this -> print [ 'invcfg' ][ 'news' ]);
$pdf -> drawRemittenceStub ( $this );
$pdf -> drawPaymentMethods ( $this );
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( $this -> print [ 'invoice' ][ 'billing_status' ] != 1 && $this -> print [ 'invoice' ][ 'suspend_billing' ] != 1 && $this -> print [ 'invoice' ][ 'due_date' ] <= time ())
$pdf -> drawInvoiceDueNotice ();
elseif ( $this -> print [ 'invoice' ][ 'billing_status' ] == 1 )
$pdf -> drawInvoicePaidNotice ();
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( $this -> sPreviousBalance ())
$pdf -> drawSummaryInvoicesDue ( $this -> sPreviousInvoices ());
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$pdf -> drawSummaryLineItems ( $this );
unset ( $pdf -> itemsSummary );
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# BEGIN loop for enumerating information in multiple ways on the invoice
$iteration = 0 ;
while ( $pdf -> drawLineItems_pre ( $iteration )) {
foreach ( $this -> sInvoiceItems () as $index => $items ) {
# Get the date range if set
if ( ! empty ( $items [ 'date_start' ]) && ! empty ( $items [ 'date_stop' ])) {
global $C_translate ;
$C_translate -> value ( 'invoice' , 'start' , date ( UNIX_DATE_FORMAT , $items [ 'date_start' ]));
$C_translate -> value ( 'invoice' , 'stop' , date ( UNIX_DATE_FORMAT , $items [ 'date_stop' ]));
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
$line = array (
'name' => $this -> sLineItemDesc ( $index ),
'domain' => $items [ 'domain_name' ],
'amount' => $items [ 'price_base' ],
'sku' => $items [ 'sku' ],
'qty' => $items [ 'quantity' ],
'cost' => $items [ 'price_base' ],
'attr' => $items [ 'product_attr' ],
'price_type' => $items [ 'price_type' ],
'price_base' => $items [ 'price_base' ],
'item_type' => $items [ 'item_type' ],
'total_amt' => $items [ 'total_amt' ]
);
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( $items [ 'date_start' ] && $items [ 'date_stop' ])
if ( $items [ 'date_start' ] == $items [ 'date_stop' ])
$line [ 'daterange' ] = sprintf ( '%s' , date ( UNIX_DATE_FORMAT , $items [ 'date_start' ]));
else
$line [ 'daterange' ] = sprintf ( '%s - %s' , date ( UNIX_DATE_FORMAT , $items [ 'date_start' ]), date ( UNIX_DATE_FORMAT , $items [ 'date_stop' ]));
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$pdf -> drawLineItems ( $db , $line , $this -> getRecordAttr ( 'id' ));
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( $items [ 'price_setup' ]) {
$line = array (
'name' => sprintf ( '%s - %s' , $this -> sLineItemDesc ( $index ), _ ( 'Setup Charge' )),
'amount' => $items [ 'price_setup' ],
'qty' => '1' ,
'sku' => $items [ 'sku' ],
'cost' => $items [ 'price_setup' ],
'price_base' => $items [ 'price_setup' ],
'price_type' => 999
);
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$pdf -> drawLineItems ( $db , $line , $this -> getRecordAttr ( 'id' ));
}
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( $this -> print [ 'invoice' ][ 'discount_amt' ]) {
$line = array (
'name' => _ ( 'Discount' ),
'amount' =>- ( $this -> print [ 'invoice' ][ 'discount_amt' ]),
'qty' => '1' ,
'cost' =>- ( $this -> print [ 'invoice' ][ 'discount_amt' ]),
'price_base' =>- ( $this -> print [ 'invoice' ][ 'discount_amt' ]),
'price_type' => 999 );
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$pdf -> drawLineItems ( $db , $line , $this -> getRecordAttr ( 'id' ));
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( $this -> print [ 'invoice' ][ 'tax_amt' ]) {
$rs = $db -> Execute ( sqlSelect ( $db , array ( 'invoice_item_tax' , 'tax' ), 'A.amount,B.description' , sprintf ( 'A.tax_id=B.id AND A.invoice_id=%s' , $this -> getRecordAttr ( 'id' ))));
if ( $rs && $rs -> RecordCount ()) {
$taxes = array ();
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
while ( ! $rs -> EOF ) {
if ( ! isset ( $taxes [ $rs -> fields [ 'description' ]]))
$taxes [ $rs -> fields [ 'description' ]] = $rs -> fields [ 'amount' ];
else
$taxes [ $rs -> fields [ 'description' ]] += $rs -> fields [ 'amount' ];
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$rs -> MoveNext ();
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
foreach ( $taxes as $txds => $txamt ) {
$line = array ( 'name' => $txds , 'amount' => $txamt , 'total_amt' => $txamt , 'price_type' => 999 );
$pdf -> drawLineItems ( $db , $line , $this -> getRecordAttr ( 'id' ));
}
}
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Increment the iteration
++ $iteration ;
2008-11-26 22:50:40 +00:00
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Custom functions:
$pdf -> drawCustom ();
}
2009-08-03 04:10:16 +00:00
/**
2010-11-29 22:41:08 +00:00
* Generate all invoices for recurring services / charges / domains
2009-08-03 04:10:16 +00:00
*/
2010-11-29 22:41:08 +00:00
public function task_GenerateRecurrInvoices () {
global $C_list ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$db = & DB ();
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$rs = $db -> Execute ( $this -> sql_InvoiceSoon ());
if ( ! $rs ) {
global $C_debug ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$C_debug -> error ( __FILE__ , __METHOD__ , $db -> ErrorMsg ());
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# There are invoices.
} elseif ( $rs -> RecordCount ()) {
$ids = '' ;
$account = '' ;
$date = '' ;
$invoice = '' ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Group all the service IDs and generate one invoice for all services.
while ( ! $rs -> EOF ) {
if ( $ids && (( $rs -> fields [ 'account_id' ] != $account ) || ( $rs -> fields [ 'invoice_date' ] != $date ))) {
$io = new invoice ;
$io -> generateInvoice ( $ids , $invoice );
$ids = '' ;
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Set the current account and date
$account = $rs -> fields [ 'account_id' ];
$invoice = $rs -> fields [ 'iid' ];
$date = $rs -> fields [ 'invoice_date' ];
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Add to id list
if ( $ids )
$ids .= ',' . $rs -> fields [ 'sid' ];
2008-11-26 22:50:40 +00:00
else
2010-11-29 22:41:08 +00:00
$ids = $rs -> fields [ 'sid' ];
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$rs -> MoveNext ();
2008-11-26 22:50:40 +00:00
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( $ids ) {
$io = new invoice ;
$io -> generateInvoice ( $ids , $invoice );
}
2008-11-26 22:50:40 +00:00
}
2010-11-29 22:41:08 +00:00
# Generate invoices for any domains expiring in X days.
if ( $C_list -> is_installed ( 'host_tld' ))
$this -> generateDomains ();
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
return true ;
}
public function generateinvoice_account ( $VAR ) {
# Check if charge module installed
global $C_list ;
$db = & DB ();
$rs = $db -> Execute ( $this -> sql_InvoiceSoon ( null , 0 , $VAR [ 'account_id' ]));
if ( ! $rs ) {
global $C_debug ;
$C_debug -> error ( __FILE__ , __METHOD__ , $db -> ErrorMsg ());
return ;
2008-11-26 22:50:40 +00:00
}
2010-11-29 22:41:08 +00:00
# Set the invoice and date
$invoice = $rs -> fields [ 'iid' ];
$date = $rs -> fields [ 'invoice_date' ];
$ids = '' ;
while ( ! $rs -> EOF ) {
if ( $ids && ( $rs -> fields [ 'invoice_date' ] != $date )) {
$io = new invoice ;
$io -> generateInvoice ( $ids , $invoice );
$ids = '' ;
}
# Add to id list
if ( $ids )
$ids .= ',' ;
$ids .= $rs -> fields [ 'sid' ];
$rs -> MoveNext ();
}
$io = new invoice ;
if ( $ids )
$io -> generateInvoice ( $ids , $invoice );
if ( isset ( $VAR [ '_page_next' ]))
define ( 'REDIRECT_PAGE' , '?_page=' . $VAR [ '_page_next' ]);
}
/**
* Generate an Invoice for the service Ids
*/
private function generateInvoice ( $sids , $piid ) {
global $C_list ;
# If there are no service ID's, we'll just return
if ( empty ( $sids ))
2008-11-26 22:50:40 +00:00
return false ;
2010-11-29 22:41:08 +00:00
# Load required elements
include_once ( PATH_MODULES . 'account/account.inc.php' );
include_once ( PATH_MODULES . 'service/service.inc.php' );
include_once ( PATH_MODULES . 'product/product.inc.php' );
$afo = false ;
if ( $C_list -> is_installed ( 'account_fee' )) {
include_once ( PATH_MODULES . 'account_fee/account_fee.inc.php' );
$afo = new account_fee ;
2009-08-03 04:10:16 +00:00
}
2010-11-29 22:41:08 +00:00
# Start a transaction
$db = & DB ();
if ( AGILE_DB_TYPE == 'mysqlt' ) {
$db -> StartTrans ();
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( ! $db -> hasTransactions ) {
2008-11-26 22:50:40 +00:00
global $C_debug ;
2010-11-29 22:41:08 +00:00
$msg = " Transactions not supported in 'mysql' driver. Use 'mysqlt' or 'mysqli' driver " ;
$C_debug -> alert ( $msg );
$C_debug -> error ( __FILE__ , __METHOD__ , $msg );
2008-11-26 22:50:40 +00:00
return false ;
}
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Start
$this -> clearRecord ();
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Generate an invoice id
$this -> setRecordAttr ( 'id' , sqlGenID ( $db , 'invoice' ));
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# Beginning totals
$invoice = array ();
$invoice [ 'recur_schedules' ] = array ();
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
foreach ( explode ( ',' , $sids ) as $sid ) {
$so = new service ( $sid );
$po = new product ( $so -> getRecordAttr ( 'product_id' ));
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( ! isset ( $ao )) {
$ao = new account ( $so -> getRecordAttr ( 'account_id' ));
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$this -> setRecordAttr ( 'account_id' , $so -> getRecordAttr ( 'account_id' ));
$this -> setRecordAttr ( 'account_billing_id' , $so -> getRecordAttr ( 'account_billing_id' ));
$this -> setRecordAttr ( 'billed_currency_id' , $ao -> getRecordAttr ( 'currency_id' ));
$this -> setRecordAttr ( 'actual_billed_currency_id' , DEFAULT_CURRENCY );
$this -> setRecordAttr ( 'reseller_id' , $ao -> getRecordAttr ( 'reseller_id' ));
$this -> setRecordAttr ( 'checkout_plugin_id' , $ao -> getRecordAttr ( 'checkout_plugin_id' ));
$this -> setRecordAttr ( 'checkout_plugin_data' , $ao -> getRecordAttr ( 'checkout_plugin_data' ));
$this -> setRecordAttr ( 'grace_period' , $ao -> getRecordAttr ( 'invoice_grace' ));
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# @todo this may unintentially allocate all service revenue to an affiliate, which should be configurable (not just the service that the account signed up for initially)
$this -> setRecordAttr ( 'affiliate_id' , $ao -> getRecordAttr ( 'affiliate_id' ));
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# @todo the parent invoice should bring this campaign id.
$this -> setRecordAttr ( 'campaign_id' , null );
2008-11-26 22:50:40 +00:00
}
2010-11-29 22:41:08 +00:00
$this -> setRecordAttr ( 'due_date' , $so -> getRecordAttr ( 'date_next_invoice' ));
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$last_invoice = $so -> getRecordAttr ( 'date_next_invoice' );
$next_invoice = $so -> getRecordAttr ( 'date_next_invoice' );
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
while ( $next_invoice < ( time () + ( $this -> sInvoiceDays () * 86400 ))) {
if ( $po -> getRecord ()) {
$billdates = $po -> recurrDates ( $so -> getRecordAttr ( 'recur_schedule' ), $so -> getRecordAttr ( 'recur_weekday' ), null , $next_invoice );
$next_invoice = $billdates [ 'end' ];
$x = $billdates [ 'end' ];
} else {
$x = $next_invoice ;
$next_invoice = $so -> calcNextInvoiceDate (
$last_invoice , $so -> getRecordAttr ( 'recur_schedule' ), $so -> getRecordAttr ( 'recur_type' ), $so -> getRecordAttr ( 'recur_weekday' ));
}
$iid = $this -> aaddItem ( array (
'charge_id' => null ,
'date_start' => $last_invoice ,
'date_stop' => $next_invoice ,
'domain_name' => $so -> getRecordAttr ( 'domain_name' ),
'domain_tld' => $so -> getRecordAttr ( 'domain_tld' ),
'domain_type' => $so -> getRecordAttr ( 'domain_type' ),
'domain_term' => $so -> getRecordAttr ( 'domain_term' ),
'item_type' => 0 ,
'price_setup' => 0 ,
'price_base' => $so -> getRecordAttr ( 'price' ),
'price_type' => $so -> getRecordAttr ( 'price_type' ),
'product_id' => $so -> getRecordAttr ( 'product_id' ),
'product_attr' => $so -> getRecordAttr ( 'prod_attr' ),
'product_attr_cart' => null ,
'quantity' => 1 ,
'recurring_schedule' => $so -> getRecordAttr ( 'recur_schedule' ),
'service_id' => $so -> getRecordAttr ( 'id' ),
'type' => $so -> getRecordAttr ( 'type' )
));
$last_invoice = $x ;
2008-11-26 22:50:40 +00:00
}
2010-11-29 22:41:08 +00:00
array_push ( $invoice [ 'recur_schedules' ], $so -> getRecordAttr ( 'recur_schedule' ));
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# Update the last & next invoice date for this service
$rs = $db -> Execute ( sqlUpdate ( $db , 'service' ,
array ( 'date_last_invoice' => $so -> getRecordAttr ( 'date_next_invoice' ), 'date_next_invoice' => $next_invoice ),
array ( 'id' => $so -> getRecordAttr ( 'id' ))));
if ( ! $rs ) {
2008-11-26 22:50:40 +00:00
global $C_debug ;
2010-11-29 22:41:08 +00:00
2009-08-03 04:10:16 +00:00
$C_debug -> error ( __FILE__ , __METHOD__ , $db -> ErrorMsg ());
2010-11-29 22:41:08 +00:00
$db -> FailTrans ();
2008-11-26 22:50:40 +00:00
return false ;
}
2010-11-29 22:41:08 +00:00
# Get any charges for this service and create them as invoice items
if ( $C_list -> is_installed ( 'charge' )) {
include_once ( PATH_MODULES . 'charge/charge.inc.php' );
$co = new charge ();
foreach ( $co -> sql_GetRecords (
array ( 'where' => sprintf ( '(status=0 OR status IS NULL) AND service_id=%s' ,
$so -> getRecordAttr ( 'id' ), $so -> getRecordAttr ( 'date_next_invoice' )))) as $record ) {
$iid = $this -> aaddItem ( array (
'charge_id' => $record [ 'id' ],
'date_start' => $record [ 'date_orig' ],
'date_stop' => $record [ 'date_orig' ],
'domain_name' => null ,
'domain_tld' => null ,
'domain_type' => null ,
'domain_term' => null ,
'item_type' => 5 ,
'price_setup' => 0 ,
'price_base' => $record [ 'amount' ],
'price_type' => 3 ,
'product_id' => $record [ 'product_id' ],
'product_name' => $record [ 'description' ],
'product_attr' => $record [ 'attributes' ],
'product_attr_cart' => null ,
'quantity' => $record [ 'quantity' ],
'recurring_schedule' => null ,
'service_id' => $so -> getRecordAttr ( 'id' ),
'sku' => $record [ 'sku' ]
));
# Update charge status
$rs = $db -> Execute ( sqlUpdate ( $db , 'charge' , array ( 'status' => 1 ), array ( 'id' => $record [ 'id' ])));
if ( false && ! $rs ) {
global $C_debug ;
$C_debug -> error ( __FILE__ , __METHOD__ , $db -> ErrorMsg ());
$db -> FailTrans ();
return false ;
}
2008-11-26 22:50:40 +00:00
}
2010-11-29 22:41:08 +00:00
}
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# See if there is an account fee for this invoice
if ( $afo && count ( $invoice [ 'recur_schedules' ])) {
foreach ( $invoice [ 'recur_schedules' ] as $recur_schedule ) {
include_once ( PATH_MODULES . 'invoice_item/invoice_item.inc.php' );
$ito = new invoice_item ();
if ( $fee = $afo -> sAccountFee ( $ao -> getRecordAttr ( 'id' ), $recur_schedule )) {
# Create the invoice item
$ito -> setRecordAttr ( 'charge_id' , null );
$ito -> setRecordAttr ( 'invoice_id' , $this -> getRecordAttr ( 'id' ));
$ito -> setRecordAttr ( 'account_id' , $ao -> getRecordAttr ( 'id' ));
$ito -> setRecordAttr ( 'service_id' , null );
$ito -> setRecordAttr ( 'product_id' , null );
$ito -> setRecordAttr ( 'product_attr' , null );
$ito -> setRecordAttr ( 'product_name' , _ ( 'Account Fee' ));
$ito -> setRecordAttr ( 'sku' , 'ACCOUNT_FEE' );
$ito -> setRecordAttr ( 'quantity' , 1 );
$ito -> setRecordAttr ( 'item_type' , 6 );
$ito -> setRecordAttr ( 'price_type' , 0 );
$ito -> setRecordAttr ( 'price_base' , $fee );
$ito -> setRecordAttr ( 'price_setup' , 0 );
$ito -> setRecordAttr ( 'discount_amt' , 0 );
$ito -> setRecordAttr ( 'recurring_schedule' , $recur_schedule );
}
2009-08-03 04:10:16 +00:00
}
2008-11-26 22:50:40 +00:00
}
2010-11-29 22:41:08 +00:00
# Add any taxes
# Get invoice grace period from global/account
if ( ! empty ( $this -> invoice_grace ))
$grace_period = $this -> invoice_grace ;
else
$grace_period = GRACE_PERIOD ;
$this -> setRecordAttr ( 'notice_next_date' , time ());
$this -> setRecordAttr ( 'billing_status' , 0 );
$this -> setRecordAttr ( 'print_status' , 0 );
$this -> setRecordAttr ( 'process_status' , 0 );
$this -> setRecordAttr ( 'status' , 1 );
// $this->setRecordAttr('suspend_billing',0);
$this -> setRecordAttr ( 'billed_amt' , 0 );
$this -> setRecordAttr ( 'actual_billed_amt' , 0 );
$this -> setRecordAttr ( 'notice_count' , 0 );
$this -> setRecordAttr ( 'type' , 1 );
$this -> setRecordAttr ( 'notice_max' , MAX_BILLING_NOTICE );
$rs = $this -> sql_SaveRecord ( true );
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( ! $rs ) {
global $C_debug ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
$C_debug -> error ( __FILE__ , __METHOD__ , $db -> ErrorMsg ());
$db -> FailTrans ();
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
return false ;
2008-11-26 22:50:40 +00:00
}
2010-11-29 22:41:08 +00:00
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 ();
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
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 ( __FILE__ , __METHOD__ , $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 ( __FILE__ , __METHOD__ , $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 -> pVoid ( $invoice -> fields [ 'id' ]);
# 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 ();
2008-11-26 22:50:40 +00:00
}
}
2009-08-03 04:10:16 +00:00
/**
2010-11-29 22:41:08 +00:00
* Find out if a user has unpaid invoices
2009-08-03 04:10:16 +00:00
*/
2010-11-29 22:41:08 +00:00
public function has_unpaid ( $VAR ) {
global $smarty , $C_list ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
if ( ! SESS_LOGGED )
return false ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
$total = 0 ;
foreach ( $this -> sInvoicesBal ( SESS_ACCOUNT ) as $details )
$total += $details [ 'balance' ];
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
if ( $total )
$smarty -> assign ( 'has_unpaid' , $C_list -> format_currency_num ( $total , SESS_CURRENCY ));
}
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
/**
* Get the totals for multiple invoices or for a group of invoices stored in temp
*
* The retrieved invoice numbers are stored in $this -> invoice ;
*
* @ param string If invoice is 'MULTI-*' , get unpaid invoices from the temporary_data table , otherwise
* get the unpaid invoices listed , or all invoices if blank .
*/
private function multiple_invoice_total ( $invoice , $account_id = SESS_ACCOUNT ) {
$this -> invoice = array ();
$db = & DB ();
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
if ( ! preg_match ( '/^MULTI-/' , $invoice )) {
$id_list = '' ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
if ( $invoice = preg_replace ( '/,$/' , '' , $invoice ))
$id_list = sprintf ( 'id in (%s) AND' , $invoice );
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Get invoice totals
$total = 0 ;
$rs = $db -> Execute ( sqlSelect ( $db , 'invoice' , 'id,total_amt,billed_amt,credit_amt' , sprintf ( '%s account_id=%s AND billing_status=0 AND (refund_status=0 OR refund_status IS NULL) AND status=1' , $id_list , SESS_ACCOUNT )));
if ( $rs && $rs -> RecordCount ()) {
while ( ! $rs -> EOF ) {
$this -> invoice [ $rs -> fields [ 'id' ]] = $rs -> fields [ 'total_amt' ] - $rs -> fields [ 'billed_amt' ] - $rs -> fields [ 'credit_amt' ];
$total += $this -> invoice [ $rs -> fields [ 'id' ]];
$rs -> MoveNext ();
2008-11-26 22:50:40 +00:00
}
2010-11-29 22:41:08 +00:00
return $total ;
2009-08-03 04:10:16 +00:00
}
2010-11-29 22:41:08 +00:00
} else {
# Get total from temp data
$rs = $db -> Execute ( sqlSelect ( $db , 'temporary_data' , 'data,field1' , array ( 'field2' => $invoice )));
if ( $rs && $rs -> RecordCount () && $rs -> fields [ 'field1' ] > 0 ) {
$this -> invoice = unserialize ( $rs -> fields [ 'data' ]);
return $rs -> fields [ 'field1' ];
2009-08-03 04:10:16 +00:00
}
2010-11-29 22:41:08 +00:00
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
return false ;
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
/**
* Preview checkout of multiple invoices
*/
public function tpl_checkout_multiple_preview ( $VAR ) {
global $smarty , $C_list ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
if ( ! SESS_LOGGED )
return false ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# If the ID is blank, this will get all unpaid invoices.
if ( ! isset ( $VAR [ 'id' ]))
$VAR [ 'id' ] = '' ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
$total = $this -> multiple_invoice_total ( $VAR [ 'id' ], SESS_ACCOUNT );
$db = & DB ();
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
if ( $total > 0 && count ( $this -> invoice ) > 1 ) {
# Get country id for checkout options
$account = $db -> Execute ( sqlSelect ( $db , 'account' , 'country_id' , array ( 'id' => SESS_ACCOUNT )));
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# Get payment options
include_once ( PATH_MODULES . 'checkout/checkout.inc.php' );
$checkout = new checkout ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
$checkoutoptions = $checkout -> get_checkout_options ( SESS_ACCOUNT , $total , false , true );
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# Get a temporary id (48 hours)
$id = sqlGenID ( $db , 'temporary_data' );
$invoice [ 'id' ] = sprintf ( 'MULTI-%s' , $id );
$invoice [ 'total' ] = $total ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
$fields = array ( 'date_orig' => time (), 'date_expire' => time () + 86400 * 3 , 'field2' => $invoice [ 'id' ], 'field1' => $total , 'data' => serialize ( $this -> invoice ));
$rs = $db -> Execute ( $q = sqlInsert ( $db , 'temporary_data' , $fields , $id ));
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
$smarty -> assign ( 'record' , $invoice );
$smarty -> assign ( 'total' , $C_list -> format_currency_num ( $total , SESS_CURRENCY ));
$smarty -> assign ( 'checkoutoptions' , $checkoutoptions );
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
} elseif ( count ( $this -> invoice ) == 1 ) {
printf ( " <script language=javascript>document.location.href='?_page=invoice:user_view&id=%s';</script> " , key ( $this -> invoice ));
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
} else {
echo _ ( 'No due invoices selected for payment.' );
}
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
/**
* Make a payment now
*/
public function checkoutnow ( $VAR ) {
global $C_translate , $smarty , $C_list , $VAR ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# Validate user logged in:
if ( SESS_LOGGED != '1' ) {
echo '<script type="text/javascript">alert("You must be logged in to complete this purchase! Please refresh this page in your browser to login now...");</script>' ;
return false ;
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# If the ID is blank, this will get all unpaid invoices.
if ( ! isset ( $VAR [ 'invoice_id' ]))
return false ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# Some defaults
$recur_amt = 0 ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
$db = & DB ();
if ( preg_match ( '/^MULTI-/' , @ $VAR [ 'invoice_id' ])) {
# Get multi-invoice details
$total = $this -> multiple_invoice_total ( $VAR [ 'invoice_id' ], SESS_ACCOUNT );
if ( ! $total )
return false ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
$recur_arr = false ;
$account_id = SESS_ACCOUNT ;
$this -> invoice_id = $VAR [ 'invoice_id' ];
$CURRENCY = DEFAULT_CURRENCY ;
$multi = true ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
} else {
# Validate the invoice selected, & get the totals:
$result = $db -> Execute ( $q = sqlSelect ( $db , 'invoice' , '*' , array ( 'id' => $VAR [ 'invoice_id' ])));
if ( ! $result || $result -> RecordCount () == 0 )
return false ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# Determine the price & currency
if ( $result -> fields [ 'billed_currency_id' ] != $result -> fields [ 'actual_billed_currency_id' ]) {
global $C_list ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
$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' ];
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
} else {
$CURRENCY = $result -> fields [ 'billed_currency_id' ];
$total = $result -> fields [ 'total_amt' ] - $result -> fields [ 'billed_amt' ];
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
if ( $result -> fields [ 'recur_amt' ] > 0 )
$recur_amt = $C_list -> format_currency_decimal ( $result -> fields [ 'recur_amt' ], $CURRENCY );
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
@ $recur_arr = unserialize ( $result -> fields [ 'recur_arr' ]);
$account_id = $result -> fields [ 'account_id' ];
$this -> invoice_id = $result -> fields [ 'id' ];
$this -> invoice [ $result -> fields [ 'id' ]] = $total ;
$multi = false ;
}
$amount = round ( $total , 2 );
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# 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 ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# 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 ;
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# 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 " ] . '",$multi);' );
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 );
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# 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 " ];
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# 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 , $this -> invoice );
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# redirect
if ( ! empty ( $this -> checkout_plugin_data [ 'redirect' ])) echo $this -> checkout_plugin_data [ 'redirect' ];
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# 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 " ) {
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
echo " <html><head></head><body><center>
Please wait while we redirect you to the secure payment site ....
{ $PLG -> redirect } </ center ></ body ></ html > " ;
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# Call the Plugin method for storing the checkout data, if new data entered:
$this -> account_billing_id = $PLG -> store_billing ( $VAR , $PLG );
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# Load the email template module
include_once ( PATH_MODULES . 'email_template/email_template.inc.php' );
$mail = new email_template ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# 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 ( __FILE__ , __METHOD__ , $db -> ErrorMsg ());
return false ;
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
// 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 , '' );
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# 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 , '' );
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# Submit the invoice for approval
$arr [ 'id' ] = $this -> invoice_id ;
$this -> pApprove ( $this -> invoice_id );
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
} else {
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# 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 ( __FILE__ , __METHOD__ , $db -> ErrorMsg ());
return false ;
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# Admin e-mail alert of manual payment processing
if ( $PLG -> getName () == '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 );
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
global $C_debug ;
$C_debug -> alert ( $C_translate -> translate ( 'manual_alert' , 'checkout' ));
}
}
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
/** GENERIC INVOICE METHODS **/
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
/**
* Return a list of accounts with their current outsanding invoices balance
*
* @ return array List of Accounts and their current balance
*/
public function sAccountsBal () {
static $sAccountBal = array ();
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
if ( ! count ( $sAccountBal )) {
$db = & DB ();
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
$rs = $db -> Execute ( sqlSelect ( $db , 'invoice' , 'account_id,ROUND(SUM(total_amt-billed_amt-IFNULL(credit_amt,0)),2) AS balance' , false , 'account_id' , '' , '' , 'account_id' ));
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
if ( $rs && $rs -> RecordCount ()) {
while ( ! $rs -> EOF ) {
$sAccountBal [ $rs -> fields [ 'account_id' ]] = $rs -> fields [ 'balance' ];
$rs -> MoveNext ();
2008-11-26 22:50:40 +00:00
}
}
2010-11-29 22:41:08 +00:00
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
return $sAccountBal ;
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
/**
* Get a list of invoices with a non - zero balance
*
* @ param $account_id Get the invoices for this account , otherwise all invoices are returned .
* @ param $refresh If true , force re - reading database to get the list of invoices .
* @ return array List of invoices with balance
*/
public function sInvoicesBal ( $account_id = null , $refresh = false ) {
static $sInvoicesBal = array ();
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
if ( $refresh || ! count ( $sInvoicesBal )) {
$sInvoicesBal = array ();
$db = & DB ();
$rs = $db -> Execute ( sqlSelect ( 'invoice' , 'date_orig,account_id,id,total_amt,billed_amt,IFNULL(credit_amt,0) as credit_amt,ROUND(total_amt-billed_amt-IFNULL(credit_amt,0),2) as balance' ,
array ( 'where' => '(refund_status=0 OR refund_status IS NULL) AND status=1 AND total_amt-billed_amt-IFNULL(credit_amt,0)!=0' , 'orderby' => 'account_id,date_orig,id' )));
if ( $rs && $rs -> RecordCount ()) {
while ( ! $rs -> EOF ) {
$invoice = array ();
$invoice [ 'invoice_id' ] = $rs -> fields [ 'id' ];
$invoice [ 'balance' ] = $rs -> fields [ 'balance' ];
$invoice [ 'total_amt' ] = $rs -> fields [ 'total_amt' ];
$invoice [ 'billed_amt' ] = $rs -> fields [ 'billed_amt' ];
$invoice [ 'credit_amt' ] = $rs -> fields [ 'credit_amt' ];
$invoice [ 'date_orig' ] = $rs -> fields [ 'date_orig' ];
$sInvoicesBal [ $rs -> fields [ 'account_id' ]][ $rs -> fields [ 'id' ]] = $invoice ;
$rs -> MoveNext ();
}
}
2008-11-26 22:50:40 +00:00
}
2010-11-29 22:41:08 +00:00
return ( is_null ( $account_id ) ? $sInvoicesBal : isset ( $sInvoicesBal [ $account_id ]) ? $sInvoicesBal [ $account_id ] : array ());
2008-11-26 22:50:40 +00:00
}
2009-08-03 04:10:16 +00:00
/**
2010-11-29 22:41:08 +00:00
* Get a list of invoices for an account .
*
* @ param $account_id
* @ param $invoices Optional array of invoices to retrieve , otherwise all invoices are return .
* @ return array Requested invoices
2009-08-03 04:10:16 +00:00
*/
2010-11-29 22:41:08 +00:00
public function sInvoicesAcc ( $account_id , $invoices = array ()) {
static $sInvoicesAccount = array ();
$return = array ();
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
if ( count ( $invoices )) {
foreach ( $invoices as $invoice )
if ( isset ( $sInvoicesAccount [ $account_id ][ $invoice_id ]))
$return [ $invoice_id ] = $sInvoicesAccount [ $account_id ][ $invoice_id ];
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
} else {
if ( isset ( $sInvoicesAccount [ $account_id ]))
$return = $sInvoicesAccount [ $account_id ];
}
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# Do we need to get the invoices from the DB?
if (( ! count ( $invoices ) && ! count ( $return )) || count ( $invoices ) != count ( $return )) {
$db = & DB ();
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
if ( count ( $invoices ))
$where = sprintf ( 'AND id IN (%s)' , join ( ',' , $invoices ));
else
$where = '' ;
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
$rs = $db -> Execute ( sqlSelect ( 'invoice' , 'id,date_orig,total_amt,billed_amt,IFNULL(credit_amt,0) as credit_amt,ROUND(total_amt-billed_amt-IFNULL(credit_amt,0),2) AS balance' , array ( 'where' => sprintf ( 'account_id=%s %s' , $account_id , $where ), 'orderby' => 'id' )));
if ( $rs && $rs -> RecordCount ()) {
2009-08-03 04:10:16 +00:00
while ( ! $rs -> EOF ) {
2010-11-29 22:41:08 +00:00
$sInvoicesAccount [ $account_id ][ $rs -> fields [ 'id' ]] = $rs -> fields ;
$return [ $rs -> fields [ 'id' ]] = $rs -> fields ;
2009-08-03 04:10:16 +00:00
$rs -> MoveNext ();
}
}
2008-11-26 22:50:40 +00:00
}
2010-11-29 22:41:08 +00:00
return $return ;
2008-11-26 22:50:40 +00:00
}
2010-11-29 22:41:08 +00:00
public function invoice_days () { return $this -> sInvoiceDays (); }
2009-08-03 04:10:16 +00:00
/**
2010-11-29 22:41:08 +00:00
* Determine the number of days in advance an invoice should be generated .
* Invoices are generated when the greater of :
* + system default ( setup : max_inv_gen_period ), ( to be deprecated )
* + system default ( setup_invoice : invoice_advance_gen ),
*
* @ return int Days in Advance to Issue Invoices .
2009-08-03 04:10:16 +00:00
*/
2010-11-29 22:41:08 +00:00
public function sInvoiceDays () {
$db = & DB ();
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
# Get the max invoice days from the setup_invoice table
$days = 0 ;
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# First from the setup table.
$setup = $db -> Execute ( sqlSelect ( $db , 'setup' , 'max_inv_gen_period' , '' ));
if ( isset ( $setup -> fields [ 'max_inv_gen_period' ]))
$days = $setup -> fields [ 'max_inv_gen_period' ];
2009-08-03 04:10:16 +00:00
2010-11-29 22:41:08 +00:00
# Then from the setup_invoice table.
$setup = $db -> Execute ( sqlSelect ( $db , 'setup_invoice' , 'invoice_advance_gen,advance_notice' , '' ));
if ( isset ( $setup -> fields [ 'invoice_advance_gen' ]) && $setup -> fields [ 'invoice_advance_gen' ] > $days )
$days = $setup -> fields [ 'invoice_advance_gen' ];
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
if ( isset ( $setup -> fields [ 'advance_notice' ]) && $setup -> fields [ 'advance_notice' ] > $days )
$days = $setup -> fields [ 'advance_notice' ];
2008-11-26 22:50:40 +00:00
2010-11-29 22:41:08 +00:00
return $days ;
2008-11-26 22:50:40 +00:00
}
2009-08-03 04:10:16 +00:00
}
2009-01-05 00:22:54 +00:00
?>