Strange Toal calculation after coupon


  • Default avatar
    colin    
     12 years ago
    0

    Hi

    virtuemart 1.1.4
    Joomla 1.5.20
    Awocoupon 1.3.5


    I have a strage issue with my cart I have a coupon published for £2 off one product

    the product price is Regenovex Gel £5.99 inc vat

    when using the coupon the first time is it displayed as

    Subtotal £5.99

    Coupon discount -£2

    Total £1.59

    Where is it getting the figure of £1.59 from?

    when you procedd through the checkout and chose a shipping menthod etc and get the the confirmation screen the price is correct £3.99

    all very strange

    I have tried differnt amounts and using a percentage as well they all give differnt total values yet al work ok in the last page?

    http://www.regenovex.co.uk



  • Your avatar
    seyi    
     12 years ago
    0

    You are using discount before tax right? If so this should help:
    https://awodev.com/blog/virtuemart-coupon-error-discount-before-tax
  • Default avatar
    colin    
     12 years ago
    0

    Hi I have read the post you directed me to and completed the changes to the files for the first part and the basket works great thank you

    but I can not get the confirmation email to have the correct total nor the total sent to the payment method in this case sagepay?

    I have read on in the post ans see there is a method to correct this but the line code in the com_virtuemart/classes/ps_checkout.php do not correspond with mine at all

    can you help?

    Cheers

    Colin



  • Your avatar
    seyi    
     12 years ago
    0

    Yes, the code in ps_checkout would fix the problem. In ps_checkout look for the functon calc_order_totals. The fix is in there. If you still cannot figure it out, post the content of that function here, and I can take a quick look.
  • Default avatar
    colin    
     12 years ago
    0

    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
  • Your avatar
    seyi    
     12 years ago
    0

    hi colin, i do not see any code, it is blank.