Thanks for your quick reply I think the issue maybe that I have a mod called vmemails which does make a backup of the checkout file when added so it may of made changes to it
the function you mention I have found but found 3 instances of it here is the code
if( !defined( '_VALID_MOS' ) && !defined( '_JEXEC' ) ) die( 'Direct Access to '.basename(__FILE__).' is not allowed.' );
/**
*
* @version $Id: ps_checkout.php 1830 2009-06-26 20:52:15Z Aravot $
* @package VirtueMart
* @subpackage classes
* @copyright Copyright (C) 2004-2009 soeren - All rights reserved.
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php
* VirtueMart is free software. This version may have been modified pursuant
* to the GNU General Public License, and as distributed it includes or
* is derivative of works licensed under the GNU General Public License or
* other free or open source software licenses.
* See /administrator/components/com_virtuemart/COPYRIGHT.php for copyright notices and details.
*
* http://virtuemart.net
*/
define("CHECK_OUT_GET_FINAL_BASKET", 1);
define("CHECK_OUT_GET_SHIPPING_ADDR", 2);
define("CHECK_OUT_GET_SHIPPING_METHOD", 3);
define("CHECK_OUT_GET_PAYMENT_METHOD", 4);
define("CHECK_OUT_GET_FINAL_CONFIRMATION", 99);
/**
* The class contains the shop checkout code. It is used to checkout
* and order and collect payment information.
*
*/
class vm_ps_checkout {
var $_SHIPPING = null;
var $_subtotal = null;
var $_shipping = null;
var $_shipping_tax = null;
var $_payment_discount = null;
var $_coupon_discount = null;
var $_order_total = null;
/** @var string An md5 hash of print_r( $cart, true ) to check wether the checkout values have to be renewed */
var $_cartHash;
/**
* Initiate Shipping Modules
*/
function vm_ps_checkout() {
global $vendor_freeshipping, $vars, $PSHOP_SHIPPING_MODULES;
// Make a snapshot of the current checkout configuration
$this->generate_cart_hash();
/* Ok, need to decide if we have a free Shipping amount > 0,
* and IF the cart total is more than that Free Shipping amount,
* let's set Order Shipping = 0
*/
$this->_subtotal = $this->get_order_subtotal($vars);
if( $vendor_freeshipping > 0 && $vars['order_subtotal_withtax'] >= $vendor_freeshipping) {
$PSHOP_SHIPPING_MODULES = Array( "free_shipping" );
include_once( CLASSPATH. "shipping/free_shipping.php" );
$this->_SHIPPING = new free_shipping();
}
elseif( !empty( $_REQUEST['shipping_rate_id'] )) {
// Create a Shipping Object and assign it to the _SHIPPING attribute
// We take the first Part of the Shipping Rate Id String
// which holds the Class Name of the Shipping Module
$rate_array = explode( "|", urldecode(vmGet($_REQUEST,"shipping_rate_id")) );
$filename = basename( $rate_array[0] );
if( $filename != '' && file_exists(CLASSPATH. "shipping/".$filename.".php")) {
include_once( CLASSPATH. "shipping/".$filename.".php" );
if( class_exists($filename) ) {
$this->_SHIPPING = new $filename();
}
}
}
//$steps = ps_checkout::get_checkout_steps();
if(empty($_REQUEST['ship_to_info_id']) && ps_checkout::noShipToNecessary()) {
$db = new ps_DB();
/* Select all the ship to information for this user id and
* order by modification date; most recently changed to oldest
*/
$q = "SELECT user_info_id from `#__{vm}_user_info` WHERE ";
$q .= "user_id='" . $_SESSION['auth']["user_id"] . "' ";
$q .= "AND address_type='BT'";
$db->query($q);
$db->next_record();
$_REQUEST['ship_to_info_id'] = $db->f("user_info_id");
}
}
/**
* Checks if Ship To can be skipped
*
* @return boolean
*/
function noShipToNecessary() {
global $cart, $only_downloadable_products;
if( NO_SHIPTO == '1') {
return true;
}
if( !isset( $cart)) $cart = ps_cart::initCart();
if( ENABLE_DOWNLOADS == '1') {
$not_downloadable = false;
require_once( CLASSPATH .'ps_product.php');
for($i = 0; $i < $cart["idx"]; $i++) {
if( !ps_product::is_downloadable($cart[$i]['product_id']) ) {
$not_downloadable = true;
break;
}
}
return !$not_downloadable;
}
return false;
}
function noShippingMethodNecessary() {
global $cart, $only_downloadable_products;
if( NO_SHIPPING == '1') {
return true;
}
if( !isset( $cart)) $cart = ps_cart::initCart();
if( ENABLE_DOWNLOADS == '1') {
$not_downloadable = false;
require_once( CLASSPATH .'ps_product.php');
for($i = 0; $i < $cart["idx"]; $i++) {
if( !ps_product::is_downloadable($cart[$i]['product_id']) ) {
$not_downloadable = true;
break;
}
}
return !$not_downloadable;
}
return false;
}
function noShippingNecessary() {
return $this->noShipToNecessary() && $this->noShippingMethodNecessary();
}
/**
* Retrieve an array with all order steps and their details
*
* @return array
*/
function get_checkout_steps() {
global $VM_CHECKOUT_MODULES;
$stepnames = array_keys( $VM_CHECKOUT_MODULES );
$steps = array();
$i = 0;
$last_order = 0;
foreach( $VM_CHECKOUT_MODULES as $step ) {
// Get the stepname from the array key
$stepname = current($stepnames);
next($stepnames);
switch( $stepname ) {
case 'CHECK_OUT_GET_SHIPPING_ADDR':
if( ps_checkout::noShipToNecessary() ) $step['enabled'] = 0;
break;
case 'CHECK_OUT_GET_SHIPPING_METHOD':
if( ps_checkout::noShippingMethodNecessary() ) $step['enabled'] = 0;
break;
}
if( $step['enabled'] == 1 ) {
$steps[$step['order']][] = $stepname;
}
}
ksort( $steps );
return $steps;
}
/**
* Retrieve the key name of the current checkout step
*
* @return string
*/
function get_current_stage() {
$steps = ps_checkout::get_checkout_steps();
$stage = key( $steps ); // $steps is sorted by key, so the first key is the first stage
// First check the REQUEST parameters for other steps
if( !empty( $_REQUEST['checkout_last_step'] ) && empty( $_POST['checkout_this_step'] )) {
// Make sure we have an integer (max 4)
$checkout_step = abs( min( $_REQUEST['checkout_last_step'], 4 ) );
if( isset( $steps[$checkout_step] )) {
return $checkout_step; // it's a valid step
}
}
$checkout_step = (int)vmGet( $_REQUEST, 'checkout_stage' );
if( isset( $steps[$checkout_step] )) {
return $checkout_step; // it's a valid step
}
// Else: we have no alternative steps given by REQUEST
while ($step = current($steps)) {
if( !empty($_POST['checkout_this_step']) ) {
foreach( $step as $stepname ) {
if( in_array( $stepname, $_POST['checkout_this_step'])) {
next($steps);
$key = key( $steps );
if( empty( $key )) {
// We are beyond the last index of the array and need to go "back" to the last index
end( $steps );
}
//echo "Stage: ".key( $steps );
return key($steps);
}
}
}
next($steps);
}
return $stage;
}
/**
* Displays the "checkout bar" using the checkout bar template
*
* @param array $steps_to_do Array holding all steps the customer has to make
* @param array $step_msg Array containing the step messages
* @param int $step_count Number of steps to make
* @param int $highlighted_step The index of the recent step
*/
function show_checkout_bar() {
global $sess, $ship_to_info_id, $shipping_rate_id, $VM_LANG;
if (SHOW_CHECKOUT_BAR != '1' || defined('VM_CHECKOUT_BAR_LOADED')) {
return;
}
// Let's assemble the steps
$steps = ps_checkout::get_checkout_steps();
$step_count = sizeof( $steps );
$steps_tmp = $steps;
$i = 0;
foreach( $steps as $step ) {
foreach( $step as $step_name ) {
switch ( $step_name ) {
case 'CHECK_OUT_GET_SHIPPING_ADDR':
$step_msg = $VM_LANG->_('PHPSHOP_ADD_SHIPTO_2');
break;
case 'CHECK_OUT_GET_SHIPPING_METHOD':
$step_msg = $VM_LANG->_('PHPSHOP_ISSHIP_LIST_CARRIER_LBL');
break;
case 'CHECK_OUT_GET_PAYMENT_METHOD':
$step_msg = $VM_LANG->_('PHPSHOP_ORDER_PRINT_PAYMENT_LBL');
break;
case 'CHECK_OUT_GET_FINAL_CONFIRMATION':
$step_msg = $VM_LANG->_('PHPSHOP_CHECKOUT_CONF_PAYINFO_COMPORDER');
break;
}
$steps_to_do[$i][] = array('step_name' => $step_name,
'step_msg' => $step_msg,
'step_order' => key($steps_tmp) );
}
next( $steps_tmp );
$i++;
}
$highlighted_step = ps_checkout::get_current_stage();
$theme = new $GLOBALS['VM_THEMECLASS']();
$theme->set_vars( array( 'step_count' => $step_count,
'steps_to_do' => $steps_to_do,
'steps' => $steps,
'highlighted_step' => $highlighted_step,
'ship_to_info_id' => vmGet($_REQUEST, 'ship_to_info_id'),
'shipping_rate_id' => vmGet( $_REQUEST, 'shipping_rate_id')
) );
echo $theme->fetch( 'checkout/checkout_bar.tpl.php');
define('VM_CHECKOUT_BAR_LOADED', 1 );
}
/**
* Called to validate the form values before the order is stored
*
* @author gday
* @author soeren
*
* @param array $d
* @return boolean
*/
function validate_form(&$d) {
global $VM_LANG, $PSHOP_SHIPPING_MODULES, $vmLogger;
$db = new ps_DB;
$auth = $_SESSION['auth'];
$cart = $_SESSION['cart'];
if (!$cart["idx"]) {
$q = "SELECT order_id FROM #__{vm}_orders WHERE user_id='" . $auth["user_id"] . "' ";
$q .= "ORDER BY cdate DESC";
$db->query($q);
$db->next_record();
$d["order_id"] = $db->f("order_id");
return False;
}
if( PSHOP_AGREE_TO_TOS_ONORDER == '1' ) {
if( empty( $d["agreed"] )) {
$vmLogger->warning( $VM_LANG->_('PHPSHOP_AGREE_TO_TOS',false) );
return false;
}
}
if ( !ps_checkout::noShippingMethodNecessary() ) {
if ( !$this->validate_shipping_method($d) ) {
return False;
}
}
if ( !$this->validate_payment_method( $d, false )) {
return false;
}
if( CHECK_STOCK == '1' ) {
for($i = 0; $i < $cart["idx"]; $i++) {
$quantity_in_stock = ps_product::get_field($cart[$i]["product_id"], 'product_in_stock');
$product_name = ps_product::get_field($cart[$i]["product_id"], 'product_name');
if( $cart[$i]["quantity"] > $quantity_in_stock ) {
$vmLogger->err( 'The Quantity for the Product "'.$product_name.'" in your Cart ('.$cart[$i]["quantity"].') exceeds the Quantity in Stock ('.$quantity_in_stock.').
We are very sorry for this Inconvenience, but you you need to lower the Quantity in Cart for this Product.');
return false;
}
}
}
// calculate the unix timestamp for the specified expiration date
// default the day to the 1st
$expire_timestamp = @mktime(0,0,0,$_SESSION["ccdata"]["order_payment_expire_month"], 15,$_SESSION["ccdata"]["order_payment_expire_year"]);
$_SESSION["ccdata"]["order_payment_expire"] = $expire_timestamp;
return True;
}
/**
* Validates the variables prior to adding an order
*
* @param array $d
* @return boolean
*/
function validate_add(&$d) {
global $auth, $VM_LANG, $vmLogger;
require_once(CLASSPATH.'ps_payment_method.php');
$ps_payment_method = new ps_payment_method;
if( empty( $auth['user_id'] ) ) {
$vmLogger->err('Sorry, but it is not possible to order without a User ID.
Please contact the Store Administrator if this Error occurs again.');
return false;
}
if (!ps_checkout::noShipToNecessary()) {
if (empty($d["ship_to_info_id"])) {
$vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_SHIPTO',false) );
return False;
}
}
/*
if (!$d["payment_method_id"]) {
$vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_MSG_4',false) );
return False;
}*/
if ($ps_payment_method->is_creditcard(@$d["payment_method_id"])) {
if (empty($_SESSION["ccdata"]["order_payment_number"])) {
$vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_CCNR',false) );
return False;
}
if(!$ps_payment_method->validate_payment($d["payment_method_id"],
$_SESSION["ccdata"]["order_payment_number"])) {
$vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_CCNUM_INV',false) );
return False;
}
if(empty( $_SESSION["ccdata"]["order_payment_expire"])) {
$vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_CCDATE_INV',false) );
return False;
}
}
return True;
}
function validate_shipto(&$d) {
//TODO to be implemented
}
/**
* Called to validate the shipping_method
*
* @param array $d
* @return boolean
*/
function validate_shipping_method(&$d) {
global $VM_LANG, $PSHOP_SHIPPING_MODULES, $vmLogger;
if( empty($d['shipping_rate_id']) ) {
$vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_SHIP',false) );
return false;
}
if( is_callable( array($this->_SHIPPING, 'validate') )) {
if(!$this->_SHIPPING->validate( $d )) {
$vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_OTHER_SHIP',false) );
return false;
}
}
return true;
}
/**
* Called to validate the payment_method
* If payment with CreditCard is used, than the Data must be in stored in the session
* This has be done to prevent sending the CreditCard Number back in hidden fields
* If the parameter $is_test is true the Number Visa Creditcard number 4111 1111 1111 1111
*
* @param array $d
* @param boolean $is_test
* @return boolean
*/
function validate_payment_method(&$d, $is_test) {
global $VM_LANG, $vmLogger, $order_total;
$auth = $_SESSION['auth'];
$cart = $_SESSION['cart'];
// We don't need to validate a payment method when
// the user has no order total he should pay
if( empty( $_REQUEST['order_total'])) {
if( isset( $d['order_total'])) {
if( round( $d['order_total'], 2 ) <= 0.00 ) {
return true;
}
}
if( isset($order_total) && $order_total <= 0.00 ) {
return true;
}
}
if (!isset($d["payment_method_id"]) || $d["payment_method_id"]==0 ) {
$vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_PAYM',false) );
return false;
}
require_once(CLASSPATH.'ps_payment_method.php');
$ps_payment_method = new ps_payment_method;
$dbp = new ps_DB; //DB Payment_method
// Now Check if all needed Payment Information are entered
// Bank Information is found in the User_Info
$w = "SELECT `enable_processor` FROM `#__{vm}_payment_method` WHERE ";
$w .= "payment_method_id=" . (int)$d["payment_method_id"];
$dbp->query($w);
$dbp->next_record();
if (($dbp->f("enable_processor") == "Y")
|| ($dbp->f("enable_processor") == "")) {
// Creditcard
if (empty( $_SESSION['ccdata']['creditcard_code']) ) {
$vmLogger->err( $VM_LANG->_('VM_CHECKOUT_ERR_CCTYPE') );
return false;
}
// $_SESSION['ccdata'] = $ccdata;
// The Data should be in the session
if (!isset($_SESSION['ccdata'])) { //Not? Then Error
$vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_CCDATA',false) );
return False;
}
if (!$_SESSION['ccdata']['order_payment_number']) {
$vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_CCNR_FOUND',false) );
return False;
}
// CREDIT CARD NUMBER CHECK
// USING THE CREDIT CARD CLASS in ps_payment
if(!$ps_payment_method->validate_payment( $_SESSION['ccdata']['creditcard_code'], $_SESSION['ccdata']['order_payment_number'])) {
$vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_CCDATE',false) );
return False;
}
if (!$is_test) {
$payment_number = ereg_replace(" |-", "", $_SESSION['ccdata']['order_payment_number']);
if ($payment_number == "4111111111111111") {
$vmLogger->warning( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_TEST',false) );
return False;
}
}
if(!empty($_SESSION['ccdata']['need_card_code']) && empty($_SESSION['ccdata']['credit_card_code'])) {
$vmLogger->err( $VM_LANG->_('PHPSHOP_CUSTOMER_CVV2_ERROR',false) );
return False;
}
if(!$_SESSION['ccdata']['order_payment_expire_month']) {
$vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_CCMON',false) );
return False;
}
if(!$_SESSION['ccdata']['order_payment_expire_year']) {
$vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_CCYEAR',false) );
return False;
}
$date = getdate( time() );
if ($_SESSION['ccdata']['order_payment_expire_year'] < $date["year"] or
($_SESSION['ccdata']['order_payment_expire_year'] == $date["year"] and
$_SESSION['ccdata']['order_payment_expire_month'] < $date["mon"])) {
$vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_CCDATE_INV',false) );
return False;
}
return True;
}
elseif ($dbp->f("enable_processor") == "B") {
$_SESSION['ccdata']['creditcard_code'] = "";
$_SESSION['ccdata']['order_payment_name'] = "";
$_SESSION['ccdata']['order_payment_number'] = "";
$_SESSION['ccdata']['order_payment_expire_month'] = "";
$_SESSION['ccdata']['order_payment_expire_year'] = "";
// Bank Account
require_once( CLASSPATH . 'ps_user.php' );
$dbu =& ps_user::getUserInfo( $auth["user_id"], array( 'bank_account_holder','bank_iban','bank_account_nr','bank_sort_code','bank_name' ) );
if ( $dbu->f("bank_account_holder") == "" || $dbu->f("bank_account_nr") =="" ) {
if( !empty($d['bank_account_holder']) && !empty($d['bank_account_nr'])) {
// Insert the given data
$fields = array( 'bank_account_holder' => $d['bank_account_holder'],
'bank_account_nr' => $d['bank_account_nr'],
'bank_sort_code' => $d['bank_sort_code'],
'bank_name' => $d['bank_name'],
'bank_iban' => $d['bank_iban']
);
ps_user::setUserInfo( $fields, $auth["user_id"] );
$dbu =& ps_user::getUserInfo( $auth["user_id"], array( 'bank_account_holder','bank_iban','bank_account_nr','bank_sort_code','bank_name' ) );
}
else {
$vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_USER_DATA',false) );
return False;
}
}
if ($dbu->f("bank_account_holder") == ""){
$vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_BA_HOLDER_NAME',false) );
return False;
}
if (($dbu->f("bank_iban") == "") and
($dbu->f("bank_account_nr") =="")) {
$vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_IBAN',false) );
return False;
}
if ($dbu->f("bank_iban") == "") {
if ($dbu->f("bank_account_nr") == ""){
$vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_BA_NUM',false) );
return False;
}
if ($dbu->f("bank_sort_code") == ""){
$vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_BANK_SORT',false) );
return False;
}
if ($dbu->f("bank_name") == ""){
$vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_BANK_NAME',false) );
return False;
}
}
}
else {
$_SESSION['ccdata']['creditcard_code'] = '';
$_SESSION['ccdata']['order_payment_name'] = "";
$_SESSION['ccdata']['order_payment_number'] = "";
$_SESSION['ccdata']['order_payment_expire_month'] = "";
$_SESSION['ccdata']['order_payment_expire_year'] = "";
}
// Enter additional Payment check procedures here if neccessary
return True;
}
/**
* Update order details
* CURRENTLY UNUSED
*
* @param array $d
* @return boolean
*/
function update(&$d) {
global $vmLogger;
$db = new ps_DB;
$timestamp = time();
if ($this->validate_update($d)) {
return True;
}
else {
$vmLogger->err( $this->error );
return False;
}
}
/**
* Control Function for the Checkout Process
* @author Ekkhard Domning
* @author soeren
* @param array $d
* @return boolean
*/
function process(&$d) {
global $checkout_this_step, $sess,$VM_LANG, $vmLogger;
$ccdata = array();
if( empty($d["checkout_this_step"]) || !is_array(@$d["checkout_this_step"])) {
$vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_VALID_STEP',false) );
return false;
}
foreach($d["checkout_this_step"] as $checkout_this_step) {
switch($checkout_this_step) {
case 'CHECK_OUT_GET_FINAL_BASKET' :
break;
case 'CHECK_OUT_GET_SHIPPING_ADDR' :
// The User has choosen a Shipping address
if (empty($d["ship_to_info_id"])) {
$vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_SHIPTO',false) );
unset( $_POST['checkout_this_step']);
return False;
}
break;
case 'CHECK_OUT_GET_SHIPPING_METHOD':
// The User has choosen a Shipping method
if (!$this->validate_shipping_method($d)) {
unset( $_POST['checkout_this_step']);
return false;
}
# awocoupon_code START ===============================================================
//needed to check coupon code against shipping method
//if coupon code is enter before shipping is selected
if( !empty( $_SESSION['coupon_code'] )) {
// Update the Coupon Discount !!
require_once(CLASSPATH.'ps_coupon.php');
ps_coupon::process_coupon_code($d);
}
# awocoupon_code END =================================================================
break;
case 'CHECK_OUT_GET_PAYMENT_METHOD':
// The User has choosen a payment method
$_SESSION['ccdata']['order_payment_name'] = @$d['order_payment_name'];
// VISA, AMEX, DISCOVER....
$_SESSION['ccdata']['creditcard_code'] = @$d['creditcard_code'];
$_SESSION['ccdata']['order_payment_number'] = @$d['order_payment_number'];
$_SESSION['ccdata']['order_payment_expire_month'] = @$d['order_payment_expire_month'];
$_SESSION['ccdata']['order_payment_expire_year'] = @$d['order_payment_expire_year'];
// 3-digit Security Code (CVV)
$_SESSION['ccdata']['credit_card_code'] = @$d['credit_card_code'];
if (!$this->validate_payment_method($d, false)) { //Change false to true to Let the user play with the VISA Testnumber
unset( $_POST['checkout_this_step']);
return false;
}
break;
case 'CHECK_OUT_GET_FINAL_CONFIRMATION':
// The User wants to order now, validate everything, if OK than Add immeditialtly
return( $this->add( $d ) );
default:
$vmLogger->crit( "CheckOut step ($checkout_this_step) is undefined!" );
return false;
} // end switch
}
return true;
} // end function process
/**
* Prints the List of all shipping addresses of a user
*
* @param unknown_type $user_id
* @param unknown_type $name
* @param unknown_type $value
*/
function ship_to_addresses_radio($user_id, $name, $value) {
echo ps_checkout::list_addresses( $user_id, $name, $value );
}
/**
* Creates a Radio List of all shipping addresses of a user
*
* @param int $user_id
* @param string $name
* @param string $value
*/
function list_addresses( $user_id, $name, $value ) {
global $sess,$VM_LANG;
$db = new ps_DB;
/* Select all the ship to information for this user id and
* order by modification date; most recently changed to oldest
*/
$q = "SELECT * from #__{vm}_user_info WHERE ";
$q .= "user_id=" . (int)$user_id . ' ';
$q .= "AND address_type='BT'";
$db->query($q);
$db->next_record();
$bt_user_info_id = $db->f("user_info_id");
$q = "SELECT * FROM #__{vm}_user_info i ";
$q .= "INNER JOIN #__{vm}_country c ON (i.country=c.country_3_code) ";
$q .= "LEFT JOIN #__{vm}_state s ON (i.state=s.state_2_code AND s.country_id=c.country_id) ";
$q .= "WHERE user_id =" . (int)$user_id . ' ';
$q .= "AND address_type = 'ST' ";
$q .= "ORDER by address_type_name, mdate DESC";
$db->query($q);
$theme = vmTemplate::getInstance();
$theme->set_vars(array('db' => $db,
'user_id' => $user_id,
'name' => $name,
'value' => $value,
'bt_user_info_id' => $bt_user_info_id,
)
);
echo $theme->fetch( 'checkout/list_shipto_addresses.tpl.php');
}
/**
* Fetches the address information for the currently logged in user
*
* @param string $address_type Can be BT (Bill To) or ST (Shipto address)
*/
function display_address($address_type='BT') {
$auth = $_SESSION['auth'];
$address_type = $address_type == 'BT' ? $address_type : 'ST';
$db = new ps_DB;
$q = "SELECT * FROM #__{vm}_user_info i ";
$q .= "INNER JOIN #__{vm}_country c ON (i.country=c.country_3_code OR i.country=c.country_2_code) ";
$q .= "LEFT JOIN #__{vm}_state s ON (i.state=s.state_2_code AND s.country_id=c.country_id) ";
$q .= "WHERE user_id='" . $auth["user_id"] . "' ";
$q .= "AND address_type='BT'";
$db->query($q);
$db->next_record();
$theme = new $GLOBALS['VM_THEMECLASS']();
$theme->set('db', $db );
return $theme->fetch('checkout/customer_info.tpl.php');
}
/**
* Lists Shipping Methods of all published Shipping Modules
*
* @param string $ship_to_info_id
* @param string $shipping_method_id
*/
function list_shipping_methods( $ship_to_info_id=null, $shipping_method_id=null ) {
global $PSHOP_SHIPPING_MODULES, $vmLogger, $auth, $weight_total;
if( empty( $ship_to_info_id )) {
// Get the Bill to user_info_id
$database = new ps_DB();
$database->setQuery( "SELECT user_info_id FROM #__{vm}_user_info WHERE user_id=".$auth['user_id']." AND address_type='BT'" );
$vars["ship_to_info_id"] = $_REQUEST['ship_to_info_id'] = $database->loadResult();
} else {
$vars['ship_to_info_id'] = $ship_to_info_id;
}
$vars['shipping_rate_id'] = $shipping_method_id;
$vars["weight"] = $weight_total;
$vars['zone_qty'] = vmRequest::getInt( 'zone_qty', 0 );
$i = 0;
$theme = new $GLOBALS['VM_THEMECLASS']();
$theme->set_vars(array('vars' => $vars,
'PSHOP_SHIPPING_MODULES' => $PSHOP_SHIPPING_MODULES
)
);
echo $theme->fetch( 'checkout/list_shipping_methods.tpl.php');
}
/**
* Lists the payment methods of all available payment modules
* @static
* @param int $payment_method_id
*/
function list_payment_methods( $payment_method_id=0 ) {
global $order_total, $sess, $VM_CHECKOUT_MODULES;
$ps_vendor_id = $_SESSION['ps_vendor_id'];
$auth = $_SESSION['auth'];
$ship_to_info_id = vmGet( $_REQUEST, 'ship_to_info_id' );
$shipping_rate_id = vmGet( $_REQUEST, 'shipping_rate_id' );
require_once(CLASSPATH . 'ps_payment_method.php');
$ps_payment_method = new ps_payment_method;
require_once( CLASSPATH. 'ps_creditcard.php' );
$ps_creditcard = new ps_creditcard();
$count = 0;
// Do we have Credit Card Payments?
$db_cc = new ps_DB;
$q = "SELECT * from #__{vm}_payment_method,#__{vm}_shopper_group WHERE ";
$q .= "#__{vm}_payment_method.shopper_group_id=#__{vm}_shopper_group.shopper_group_id ";
$q .= "AND (#__{vm}_payment_method.shopper_group_id='".$auth['shopper_group_id']."' ";
$q .= "OR #__{vm}_shopper_group.default='1') ";
$q .= "AND (enable_processor='' OR enable_processor='Y') ";
$q .= "AND payment_enabled='Y' ";
$q .= "AND #__{vm}_payment_method.vendor_id='$ps_vendor_id' ";
$q .= " ORDER BY list_order";
$db_cc->query($q);
if ($db_cc->num_rows()) {
$first_payment_method_id = $db_cc->f("payment_method_id");
$count += $db_cc->num_rows();
$cc_payments=true;
}
else {
$cc_payments=false;
}
$db_nocc = new ps_DB;
$q = "SELECT * from #__{vm}_payment_method,#__{vm}_shopper_group WHERE ";
$q .= "#__{vm}_payment_method.shopper_group_id=#__{vm}_shopper_group.shopper_group_id ";
$q .= "AND (#__{vm}_payment_method.shopper_group_id='".$auth['shopper_group_id']."' ";
$q .= "OR #__{vm}_shopper_group.default='1') ";
$q .= "AND (enable_processor='B' OR enable_processor='N' OR enable_processor='P') ";
$q .= "AND payment_enabled='Y' ";
$q .= "AND #__{vm}_payment_method.vendor_id='$ps_vendor_id' ";
$q .= " ORDER BY list_order";
$db_nocc->query($q);
if ($db_nocc->next_record()) {
$nocc_payments=true;
$first_payment_method_id = $db_nocc->f("payment_method_id");
$count += $db_nocc->num_rows();
$db_nocc->reset();
}
else {
$nocc_payments=false;
}
// Redirect to the last step when there's only one payment method
if( $VM_CHECKOUT_MODULES['CHECK_OUT_GET_PAYMENT_METHOD']['order'] != $VM_CHECKOUT_MODULES['CHECK_OUT_GET_FINAL_CONFIRMATION']['order'] ) {
if ($count <= 1 && $cc_payments==false) {
vmRedirect($sess->url(SECUREURL.basename($_SERVER['PHP_SELF'])."?page=checkout.index&payment_method_id=$first_payment_method_id&ship_to_info_id=$ship_to_info_id&shipping_rate_id=".urlencode($shipping_rate_id)."&checkout_stage=".$VM_CHECKOUT_MODULES['CHECK_OUT_GET_FINAL_CONFIRMATION']['order'], false, false ),"");
}
elseif( isset($order_total) && $order_total <= 0.00 ) {
// In case the order total is less than or equal zero, we don't need a payment method
vmRedirect($sess->url(SECUREURL.basename($_SERVER['PHP_SELF'])."?page=checkout.index&ship_to_info_id=$ship_to_info_id&shipping_rate_id=".urlencode($shipping_rate_id)."&checkout_stage=".$VM_CHECKOUT_MODULES['CHECK_OUT_GET_FINAL_CONFIRMATION']['order'], false, false),"");
}
}
$theme = new $GLOBALS['VM_THEMECLASS']();
$theme->set_vars(array('db_nocc' => $db_nocc,
'db_cc' => $db_cc,
'nocc_payments' => $nocc_payments,
'payment_method_id' => $payment_method_id,
'first_payment_method_id' => $first_payment_method_id,
'count' => $count,
'cc_payments' => $cc_payments,
'ps_creditcard' => $ps_creditcard,
'ps_payment_method' => $ps_payment_method
)
);
echo $theme->fetch( 'checkout/list_payment_methods.tpl.php');
}
/**
* This is the main function which stores the order information in the database
*
* @author gday, soeren, many others!
* @param array $d The REQUEST/$vars array
* @return boolean
*/
function add( &$d ) {
global $order_tax_details, $afid, $VM_LANG, $auth, $my, $mosConfig_offset,
$vmLogger, $vmInputFilter, $discount_factor;
$ps_vendor_id = $_SESSION["ps_vendor_id"];
$cart = $_SESSION['cart'];
require_once(CLASSPATH. 'ps_payment_method.php' );
$ps_payment_method = new ps_payment_method;
require_once(CLASSPATH. 'ps_product.php' );
$ps_product= new ps_product;
require_once(CLASSPATH.'ps_cart.php');
$ps_cart = new ps_cart;
$db = new ps_DB;
/* Set the order number */
$order_number = $this->get_order_number();
$d['order_number'] = $order_number; # awocoupon_code
$totals = $this->calc_order_totals( $d );
extract( $totals );
//$timestamp = time() + ($mosConfig_offset*60*60); //Original
$timestamp = time(); //Custom
if (!$this->validate_form($d)) {
return false;
}
if (!$this->validate_add($d)) {
return false;
}
// make sure Total doesn't become negative
if( $order_total < 0 ) $order_total = 0;
$order_total = round( $order_total, 2);
$vmLogger->debug( '-- Checkout Debug--
Subtotal: '.$order_subtotal.'
Taxable: '.$order_taxable.'
Payment Discount: '.$payment_discount.'
Coupon Discount: '.$coupon_discount.'
Shipping: '.$order_shipping.'
Shipping Tax : '.$order_shipping_tax.'
Tax : '.$order_tax.'
------------------------
Order Total: '.$order_total.'
----------------------------'
);
// Check to see if Payment Class File exists
$payment_class = $ps_payment_method->get_field($d["payment_method_id"], "payment_class");
$enable_processor = $ps_payment_method->get_field($d["payment_method_id"], "enable_processor");
if (file_exists(CLASSPATH . "payment/$payment_class.php") ) {
if( !class_exists( $payment_class )) {
include( CLASSPATH. "payment/$payment_class.php" );
}
$_PAYMENT = new $payment_class();
if (!$_PAYMENT->process_payment($order_number,$order_total, $d)) {
$vmLogger->err( $VM_LANG->_('PHPSHOP_PAYMENT_ERROR',false)." ($payment_class)" );
$_SESSION['last_page'] = "checkout.index";
$_REQUEST["checkout_next_step"] = CHECK_OUT_GET_PAYMENT_METHOD;
return False;
}
}
else {
$d["order_payment_log"] = $VM_LANG->_('PHPSHOP_CHECKOUT_MSG_LOG');
}
// Remove the Coupon, because it is a Gift Coupon and now is used!!
if( @$_SESSION['coupon_type'] == "gift" ) {
$d['coupon_id'] = $_SESSION['coupon_id'];
include_once( CLASSPATH.'ps_coupon.php' );
ps_coupon::remove_coupon_code( $d );
}
// Get the IP Address
if (!empty($_SERVER['REMOTE_ADDR'])) {
$ip = $_SERVER['REMOTE_ADDR'];
}
else {
$ip = 'unknown';
}
// Collect all fields and values to store them!
$fields = array(
'user_id' => $auth["user_id"],
'vendor_id' => $ps_vendor_id,
'order_number' => $order_number,
'user_info_id' => $d["ship_to_info_id"],
'ship_method_id' => @urldecode($d["shipping_rate_id"]),
'order_total' => $order_total,
'order_subtotal' => $order_subtotal,
'order_tax' => $order_tax,
'order_tax_details' => serialize($order_tax_details),
'order_shipping' => $order_shipping,
'order_shipping_tax' => $order_shipping_tax,
'order_discount' => $payment_discount,
'coupon_discount' => $coupon_discount,
'coupon_code' => @$_SESSION['coupon_code'],
'order_currency' => $GLOBALS['product_currency'],
'order_status' => 'P',
'cdate' => $timestamp,
'mdate' => $timestamp,
'customer_note' => htmlspecialchars(vmRequest::getString('customer_note','', 'POST', 'none' ), ENT_QUOTES ),
'ip_address' => $ip
);
// Insert the main order information
$db->buildQuery( 'INSERT', '#__{vm}_orders', $fields );
$result = $db->query();
$d["order_id"] = $order_id = $db->last_insert_id();
if( $result === false || empty( $order_id )) {
$vmLogger->crit( 'Adding the Order into the Database failed! User ID: '.$auth["user_id"] );
return false;
}
// Insert the initial Order History.
$mysqlDatetime = date("Y-m-d G:i:s", $timestamp);
$fields = array(
'order_id' => $order_id,
'order_status_code' => 'P',
'date_added' => $mysqlDatetime,
'customer_notified' => 1,
'comments' => ''
);
$db->buildQuery( 'INSERT', '#__{vm}_order_history', $fields );
$db->query();
/**
* Insert the Order payment info
*/
$payment_number = ereg_replace(" |-", "", @$_SESSION['ccdata']['order_payment_number']);
$d["order_payment_code"] = @$_SESSION['ccdata']['credit_card_code'];
// Payment number is encrypted using mySQL encryption functions.
$fields = array(
'order_id' => $order_id,
'payment_method_id' => $d["payment_method_id"],
'order_payment_log' => @$d["order_payment_log"],
'order_payment_trans_id' => $vmInputFilter->safeSQL( @$d["order_payment_trans_id"] )
);
if( !empty( $payment_number ) && VM_STORE_CREDITCARD_DATA == '1' ) {
// Store Credit Card Information only if the Store Owner has decided to do so
$fields['order_payment_code'] = $d["order_payment_code"];
$fields['order_payment_expire'] = @$_SESSION["ccdata"]["order_payment_expire"];
$fields['order_payment_name'] = @$_SESSION["ccdata"]["order_payment_name"];
$fields['order_payment_number'] = VM_ENCRYPT_FUNCTION."( '$payment_number','" . ENCODE_KEY . "')";
$specialfield = array('order_payment_number');
} else {
$specialfield = array();
}
$db->buildQuery( 'INSERT', '#__{vm}_order_payment', $fields, '', $specialfield );
$db->query();
/**
* Insert the User Billto & Shipto Info
*/
// First: get all the fields from the user field list to copy them from user_info into the order_user_info
$fields = array();
require_once( CLASSPATH . 'ps_userfield.php' );
$userfields = ps_userfield::getUserFields('', false, '', true, true );
foreach ( $userfields as $field ) {
if ($field->name=='email') $fields[] = 'user_email';
else $fields[] = $field->name;
}
$fieldstr = implode( ',', $fields );
// Save current Bill To Address
$q = "INSERT INTO `#__{vm}_order_user_info`
(`order_info_id`,`order_id`,`user_id`,address_type, ".$fieldstr.") ";
$q .= "SELECT NULL, '$order_id', '".$auth['user_id']."', address_type, ".$fieldstr." FROM #__{vm}_user_info WHERE user_id='".$auth['user_id']."' AND address_type='BT'";
$db->query( $q );
// Save current Ship to Address if applicable
$q = "INSERT INTO `#__{vm}_order_user_info`
(`order_info_id`,`order_id`,`user_id`,address_type, ".$fieldstr.") ";
$q .= "SELECT NULL, '$order_id', '".$auth['user_id']."', address_type, ".$fieldstr." FROM #__{vm}_user_info WHERE user_id='".$auth['user_id']."' AND user_info_id='".$d['ship_to_info_id']."' AND address_type='ST'";
$db->query( $q );
/**
* Insert all Products from the Cart into order line items;
* one row per product in the cart
*/
$dboi = new ps_DB;
for($i = 0; $i < $cart["idx"]; $i++) {
$r = "SELECT product_id,product_in_stock,product_sales,product_parent_id,product_sku,product_name ";
$r .= "FROM #__{vm}_product WHERE product_id='".$cart[$i]["product_id"]."'";
$dboi->query($r);
$dboi->next_record();
$product_price_arr = $ps_product->get_adjusted_attribute_price($cart[$i]["product_id"], $cart[$i]["description"]);
$product_price = $GLOBALS['CURRENCY']->convert( $product_price_arr["product_price"], $product_price_arr["product_currency"] );
if( empty( $_SESSION['product_sess'][$cart[$i]["product_id"]]['tax_rate'] )) {
$my_taxrate = $ps_product->get_product_taxrate($cart[$i]["product_id"] );
}
else {
$my_taxrate = $_SESSION['product_sess'][$cart[$i]["product_id"]]['tax_rate'];
}
// Attribute handling
$product_parent_id = $dboi->f('product_parent_id');
$description = '';
if( $product_parent_id > 0 ) {
$db_atts = $ps_product->attribute_sql( $dboi->f('product_id'), $product_parent_id );
while( $db_atts->next_record()) {
$description .= $db_atts->f('attribute_name').': '.$db_atts->f('attribute_value').'; ';
}
}
$description .= $ps_product->getDescriptionWithTax($_SESSION['cart'][$i]["description"], $dboi->f('product_id'));
$product_final_price = round( ($product_price *($my_taxrate+1)), 2 );
$vendor_id = $ps_vendor_id;
$fields = array('order_id' => $order_id,
'user_info_id' => $d["ship_to_info_id"],
'vendor_id' => $vendor_id,
'product_id' => $cart[$i]["product_id"],
'order_item_sku' => $dboi->f("product_sku"),
'order_item_name' => $dboi->f("product_name"),
'product_quantity' => $cart[$i]["quantity"],
'product_item_price' => $product_price,
'product_final_price' => $product_final_price,
'order_item_currency' => $GLOBALS['product_currency'],
'order_status' => 'P',
'product_attribute' => $description,
'cdate' => $timestamp,
'mdate' => $timestamp
);
$db->buildQuery( 'INSERT', '#__{vm}_order_item', $fields );
$db->query();
// Update Stock Level and Product Sales, decrease - no matter if in stock or not!
$q = "UPDATE #__{vm}_product ";
$q .= "SET product_in_stock = product_in_stock - ".(int)$cart[$i]["quantity"];
$q .= " WHERE product_id = '" . $cart[$i]["product_id"]. "'";
$db->query($q);
$q = "UPDATE #__{vm}_product ";
$q .= "SET product_sales= product_sales + ".(int)$cart[$i]["quantity"];
$q .= " WHERE product_id='".$cart[$i]["product_id"]."'";
$db->query($q);
}
######## BEGIN DOWNLOAD MOD ###############
if( ENABLE_DOWNLOADS == "1" ) {
require_once( CLASSPATH.'ps_order.php');
for($i = 0; $i < $cart["idx"]; $i++) {
// only handle downloadable products here
if( ps_product::is_downloadable($cart[$i]["product_id"])) {
$params = array('product_id' => $cart[$i]["product_id"], 'order_id' => $order_id, 'user_id' => $auth["user_id"] );
ps_order::insert_downloads_for_product( $params );
if( @VM_DOWNLOADABLE_PRODUCTS_KEEP_STOCKLEVEL == '1' ) {
// Update the product stock level back to where it was.
$q = "UPDATE #__{vm}_product ";
$q .= "SET product_in_stock = product_in_stock + ".(int)$cart[$i]["quantity"];
$q .= " WHERE product_id = '" .(int)$cart[$i]["product_id"]. "'";
$db->query($q);
}
}
}
}
################## END DOWNLOAD MOD ###########
// Export the order_id so the checkout complete page can get it
$d["order_id"] = $order_id;
/*
* Let the shipping module know which shipping method
* was selected. This way it can save any information
* it might need later to print a shipping label.
*/
if( is_callable( array($this->_SHIPPING, 'save_rate_info') )) {
$this->_SHIPPING->save_rate_info($d);
}
// Now as everything else has been done, we can update
// the Order Status if the Payment Method is
// "Use Payment Processor", because:
// Payment Processors return false on any error
// Only completed payments return true!
$update_order = false;
if( $enable_processor == "Y" ) {
if( defined($_PAYMENT->payment_code.'_VERIFIED_STATUS')) {
$d['order_status'] = constant($_PAYMENT->payment_code.'_VERIFIED_STATUS');
$update_order = true;
}
} elseif( $order_total == 0.00 ) {
// If the Order Total is zero, we can confirm the order to automatically enable the download
$d['order_status'] = ENABLE_DOWNLOAD_STATUS;
$update_order = true;
}
if ( $update_order ) {
require_once(CLASSPATH."ps_order.php");
$ps_order = new ps_order();
$ps_order->order_status_update($d);
}
// Send the e-mail confirmation messages
$this->email_receipt($order_id);
// Reset the cart (=empty it)
$ps_cart->reset();
$_SESSION['savedcart']['idx']=0;
$ps_cart->saveCart();
// Unset the payment_method variables
$d["payment_method_id"] = "";
$d["order_payment_number"] = "";
$d["order_payment_expire"] = "";
$d["order_payment_name"] = "";
$d["credit_card_code"] = "";
// Clear the sensitive Session data
$_SESSION['ccdata']['order_payment_name'] = "";
$_SESSION['ccdata']['order_payment_number'] = "";
$_SESSION['ccdata']['order_payment_expire_month'] = "";
$_SESSION['ccdata']['order_payment_expire_year'] = "";
$_SESSION['ccdata']['credit_card_code'] = "";
$_SESSION['coupon_discount'] = "";
$_SESSION['coupon_id'] = "";
$_SESSION['coupon_redeemed'] = false;
$_POST["payment_method_id"] = "";
$_POST["order_payment_number"] = "";
$_POST["order_payment_expire"] = "";
$_POST["order_payment_name"] = "";
/*
if( empty($my->id) && !empty( $auth['user_id'])) {
require_once(CLASSPATH.'ps_user.php');
ps_user::logout();
}
*/
return True;
}
/**
* Create an order number using the session id, session
* name, and the current unix timestamp.
*
* @return string
*/
function get_order_number() {
global $auth;
/* Generated a unique order number */
$str = session_id();
$str .= (string)time();
$order_number = $auth['user_id'] .'_'. md5($str);
return substr($order_number, 0, 32);
}
/**
* Stores the md5 hash of the recent cart in the var _cartHash
*
*/
function generate_cart_hash() {
$this->_cartHash = $this->get_new_cart_hash();
}
function get_order_total( &$d ) {
global $discount_factor;
$totals = $this->calc_order_totals($d);
return $totals['order_total'];
}
/**
* Calculates the current order totals and fills an array with all the values
*
* @param array $d
* @return array
*/
function calc_order_totals( &$d ) {
global $discount_factor, $mosConfig_offset;
$totals = array();
/* sets _subtotal */
$totals['order_subtotal'] = $tmp_subtotal = $this->calc_order_subtotal($d);
$totals['order_taxable'] = $this->calc_order_taxable($d);
if( !empty($d['payment_method_id'])) {
$totals['payment_discount'] = $d['payment_discount'] = $this->get_payment_discount($d['payment_method_id'], $totals['order_subtotal']);
} else {
$totals['payment_discount'] = $d['payment_discount'] = 0.00;
}
/* DISCOUNT HANDLING */
if( !empty($_SESSION['coupon_discount']) ) {
$totals['coupon_discount'] = floatval($_SESSION['coupon_discount']);
}
else {
$totals['coupon_discount'] = 0.00;
}
// make sure Total doesn't become negative
if( $tmp_subtotal < 0 ) $totals['order_subtotal'] = $tmp_subtotal = 0;
if( $totals['order_taxable'] < 0 ) $totals['order_taxable'] = 0;
// from now on we have $order_tax_details
$d['order_tax'] = $totals['order_tax'] = round( $this->calc_order_tax($totals['order_taxable'], $d), 2 );
if( is_object($this->_SHIPPING) ) {
/* sets _shipping */
$d['order_shipping'] = $totals['order_shipping'] = round( $this->calc_order_shipping( $d ), 2 );
/* sets _shipping_tax
* btw: This is WEIRD! To get an exactly rounded value we have to convert
* the amount to a String and call "round" with the string. */
$d['order_shipping_tax'] = $totals['order_shipping_tax'] = round( strval($this->calc_order_shipping_tax($d)), 2 );
}
else {
$d['order_shipping'] = $totals['order_shipping'] = $totals['order_shipping_tax'] = $d['order_shipping_tax'] = 0.00;
}
$d['order_total'] = $totals['order_total'] = $tmp_subtotal
+ $totals['order_tax']
+ $totals['order_shipping']
+ $totals['order_shipping_tax']
- $totals['coupon_discount']
- $totals['payment_discount'];
$totals['order_tax'] *= $discount_factor;
return $totals;
}
/**
* Generates the md5 hash of the recent cart / checkout constellation
*
* @return unknown
*/
function get_new_cart_hash() {
return md5( print_r( $_SESSION['cart'], true)
. vmGet($_REQUEST,'shipping_rate_id')
. vmGet($_REQUEST,'payment_method_id')
);
}
/**
* Returns the recent subtotal
*
* @param array $d
* @return float The current order subtotal
*/
function get_order_subtotal( &$d ) {
if( $this->_subtotal === null ) {
$this->_subtotal = $this->calc_order_subtotal( $d );
}
else {
if( $this->_cartHash != $this->get_new_cart_hash() ) {
// Need to re-calculate the subtotal
$this->_subtotal = $this->calc_order_subtotal( $d );
}
}
return $this->_subtotal;
}
/**************************************************************************
** name: calc_order_subtotal()
** created by: gday
** description: Calculate the order subtotal for the current order.
** Does not include tax or shipping charges.
** parameters: $d
** returns: sub total for this order
***************************************************************************/
function calc_order_subtotal( &$d ) {
global $order_tax_details;
$order_tax_details = array();
$d['order_subtotal_withtax'] = 0;
$d['payment_discount'] = 0;
$auth = $_SESSION['auth'];
$cart = $_SESSION['cart'];
$order_subtotal = 0;
require_once(CLASSPATH.'ps_product.php');
$ps_product= new ps_product;
for($i = 0; $i < $cart["idx"]; $i++) {
$my_taxrate = $ps_product->get_product_taxrate($cart[$i]["product_id"] );
$price = $ps_product->get_adjusted_attribute_price($cart[$i]["product_id"], $cart[$i]["description"]);
$product_price = $product_price_tmp = $GLOBALS['CURRENCY']->convert( $price["product_price"], @$price["product_currency"] );
if( $auth["show_price_including_tax"] == 1 ) {
$product_price = round( ($product_price *($my_taxrate+1)), 2 );
$product_price *= $cart[$i]["quantity"];
$d['order_subtotal_withtax'] += $product_price;
$product_price = $product_price /($my_taxrate+1);
$order_subtotal += $product_price;
}
else {
$order_subtotal += $product_price * $cart[$i]["quantity"];
$product_price = round( ($product_price *($my_taxrate+1)), 2 );
$product_price *= $cart[$i]["quantity"];
$d['order_subtotal_withtax'] += $product_price;
$product_price = $product_price /($my_taxrate+1);
}
if( MULTIPLE_TAXRATES_ENABLE ) {
// Calculate the amounts for each tax rate
if( !isset( $order_tax_details[$my_taxrate] )) {
$order_tax_details[$my_taxrate] = 0;
}
$order_tax_details[$my_taxrate] += $product_price_tmp*$my_taxrate*$cart[$i]["quantity"];
}
}
return($order_subtotal);
}
/**
* Calculates the taxable order subtotal for the order.
* If an item has no weight, it is non taxable.
* @author Chris Coleman
* @param array $d
* @return float Subtotal
*/
function calc_order_taxable($d) {
$auth = $_SESSION['auth'];
$cart = $_SESSION['cart'];
$subtotal = 0.0;
require_once(CLASSPATH.'ps_product.php');
$ps_product= new ps_product;
require_once(CLASSPATH.'ps_shipping_method.php');
$db = new ps_DB;
for($i = 0; $i < $cart["idx"]; $i++) {
$price = $ps_product->get_adjusted_attribute_price($cart[$i]["product_id"], $cart[$i]["description"]);
$product_price = $GLOBALS['CURRENCY']->convert( $price["product_price"], $price['product_currency'] );
$item_weight = ps_shipping_method::get_weight($cart[$i]["product_id"]) * $cart[$i]['quantity'];
if ($item_weight != 0 or TAX_VIRTUAL=='1') {
$subtotal += $product_price * $cart[$i]["quantity"];
}
}
return($subtotal);
}
/**
* Calculate the tax charges for the current order.
* You can switch the way, taxes are calculated:
* either based on the VENDOR address,
* or based on the ship-to address.
* ! Creates the global $order_tax_details
*
* @param float $order_taxable
* @param array $d
* @return float
*/
function calc_order_tax($order_taxable, $d) {
global $order_tax_details, $discount_factor;
$total = 0;
$order_tax=0;
$auth = $_SESSION['auth'];
$ps