[ Indice ]

Riferimento incrociato di Joomla! 1.5.14 - VM 1.1.4

Servizio fornito da VMItalia
Classe:   Funzione:   Variabile:   Costante:  
Storico Ricerche +

titolo

Corpo

[chiudi]

/administrator/components/com_virtuemart/classes/ -> ps_checkout.php (sorgente)

   1  <?php
   2  if( !defined( '_VALID_MOS' ) && !defined( '_JEXEC' ) ) die( 'Direct Access to '.basename(__FILE__).' is not allowed.' );
   3  /**

   4  *

   5  * @version $Id: ps_checkout.php 1830 2009-06-26 20:52:15Z Aravot $

   6  * @package VirtueMart

   7  * @subpackage classes

   8  * @copyright Copyright (C) 2004-2009 soeren - All rights reserved.

   9  * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php

  10  * VirtueMart is free software. This version may have been modified pursuant

  11  * to the GNU General Public License, and as distributed it includes or

  12  * is derivative of works licensed under the GNU General Public License or

  13  * other free or open source software licenses.

  14  * See /administrator/components/com_virtuemart/COPYRIGHT.php for copyright notices and details.

  15  *

  16  * http://virtuemart.net

  17  */ 
  18  
  19  define("CHECK_OUT_GET_FINAL_BASKET", 1);
  20  define("CHECK_OUT_GET_SHIPPING_ADDR", 2);
  21  define("CHECK_OUT_GET_SHIPPING_METHOD", 3);
  22  define("CHECK_OUT_GET_PAYMENT_METHOD", 4);
  23  define("CHECK_OUT_GET_FINAL_CONFIRMATION", 99);
  24  
  25  /**

  26   * The class contains the shop checkout code.  It is used to checkout

  27   * and order and collect payment information.

  28   *

  29   */
  30  class vm_ps_checkout {
  31      var $_SHIPPING = null;
  32  
  33      var $_subtotal = null;
  34      var $_shipping = null;
  35      var $_shipping_tax = null;
  36      var $_payment_discount = null;
  37      var $_coupon_discount = null;
  38      var $_order_total = null;
  39      /** @var string An md5 hash of print_r( $cart, true ) to check wether the checkout values have to be renewed */

  40      var $_cartHash;
  41  
  42      /**

  43       * Initiate Shipping Modules

  44       */
  45  	function vm_ps_checkout() {
  46          global $vendor_freeshipping, $vars, $PSHOP_SHIPPING_MODULES;
  47  
  48          // Make a snapshot of the current checkout configuration

  49          $this->generate_cart_hash();
  50  
  51          /* Ok, need to decide if we have a free Shipping amount > 0,

  52          * and IF the cart total is more than that Free Shipping amount,

  53          * let's set Order Shipping = 0

  54          */
  55  
  56          $this->_subtotal = $this->get_order_subtotal($vars);
  57          
  58          if( $vendor_freeshipping > 0 && $vars['order_subtotal_withtax'] >= $vendor_freeshipping) {
  59              $PSHOP_SHIPPING_MODULES = Array( "free_shipping" );
  60              include_once ( CLASSPATH. "shipping/free_shipping.php" );
  61              $this->_SHIPPING = new free_shipping();
  62          }
  63          elseif( !empty( $_REQUEST['shipping_rate_id'] )) {
  64  
  65              // Create a Shipping Object and assign it to the _SHIPPING attribute

  66              // We take the first Part of the Shipping Rate Id String

  67              // which holds the Class Name of the Shipping Module

  68              $rate_array = explode( "|", urldecode(vmGet($_REQUEST,"shipping_rate_id")) );
  69              $filename = basename( $rate_array[0] );
  70              if( $filename != '' && file_exists(CLASSPATH. "shipping/".$filename.".php")) {
  71                  include_once( CLASSPATH. "shipping/".$filename.".php" );
  72                  if( class_exists($filename) ) {
  73                      $this->_SHIPPING = new $filename();
  74                  }
  75              }
  76          }
  77          //$steps = ps_checkout::get_checkout_steps();

  78          if(empty($_REQUEST['ship_to_info_id']) && ps_checkout::noShipToNecessary()) {
  79  
  80              $db = new ps_DB();
  81  
  82              /* Select all the ship to information for this user id and

  83              * order by modification date; most recently changed to oldest

  84              */
  85              $q  = "SELECT user_info_id from `#__{vm}_user_info` WHERE ";
  86              $q .= "user_id='" . $_SESSION['auth']["user_id"] . "' ";
  87              $q .= "AND address_type='BT'";
  88              $db->query($q);
  89              $db->next_record();
  90  
  91              $_REQUEST['ship_to_info_id'] = $db->f("user_info_id");
  92          }
  93      }
  94      /**

  95       * Checks if Ship To can be skipped

  96       *

  97       * @return boolean

  98       */
  99  	function noShipToNecessary() {
 100          global $cart, $only_downloadable_products;
 101          if( NO_SHIPTO == '1') {
 102              return true;
 103          }
 104          if( !isset( $cart)) $cart = ps_cart::initCart();
 105          
 106          if( ENABLE_DOWNLOADS == '1') {
 107              $not_downloadable = false;
 108              require_once ( CLASSPATH .'ps_product.php');
 109              for($i = 0; $i < $cart["idx"]; $i++) {
 110                  
 111                  if( !ps_product::is_downloadable($cart[$i]['product_id']) ) {                    
 112                      $not_downloadable = true;
 113                      break;
 114                  }
 115              }
 116              return !$not_downloadable;
 117          }
 118          return false;
 119      }
 120  	function noShippingMethodNecessary() {
 121          global $cart, $only_downloadable_products;
 122          if( NO_SHIPPING == '1') {
 123              return true;
 124          }
 125          
 126          if( !isset( $cart)) $cart = ps_cart::initCart();
 127          
 128          if( ENABLE_DOWNLOADS == '1') {
 129              $not_downloadable = false;
 130              require_once ( CLASSPATH .'ps_product.php');
 131              for($i = 0; $i < $cart["idx"]; $i++) {
 132                  if( !ps_product::is_downloadable($cart[$i]['product_id']) ) {
 133                      $not_downloadable = true;
 134                      break;
 135                  }
 136              }
 137              return !$not_downloadable;
 138          }
 139          return false;
 140      }
 141  	function noShippingNecessary() {
 142          return $this->noShipToNecessary() && $this->noShippingMethodNecessary();
 143      }
 144      /**

 145       * Retrieve an array with all order steps and their details

 146       *

 147       * @return array

 148       */
 149  	function get_checkout_steps() {
 150          global $VM_CHECKOUT_MODULES;
 151          $stepnames = array_keys( $VM_CHECKOUT_MODULES );
 152          $steps = array();
 153          $i = 0;
 154          $last_order = 0;
 155          foreach( $VM_CHECKOUT_MODULES as $step ) {
 156              // Get the stepname from the array key

 157              $stepname = current($stepnames);
 158              next($stepnames);
 159              
 160              switch( $stepname ) {
 161                  case 'CHECK_OUT_GET_SHIPPING_ADDR':
 162                      if( ps_checkout::noShipToNecessary() ) $step['enabled'] = 0;
 163                      break;
 164                  case 'CHECK_OUT_GET_SHIPPING_METHOD':
 165                      if( ps_checkout::noShippingMethodNecessary() ) $step['enabled'] = 0;
 166                      break;
 167              }
 168              
 169              
 170              if( $step['enabled'] == 1 ) {
 171                  $steps[$step['order']][] = $stepname;
 172              }
 173              
 174          }
 175          ksort( $steps );
 176          
 177          return $steps;
 178      }
 179      /**

 180       * Retrieve the key name of the current checkout step

 181       *

 182       * @return string

 183       */
 184  	function get_current_stage() {
 185          $steps = ps_checkout::get_checkout_steps();
 186          $stage = key( $steps ); // $steps is sorted by key, so the first key is the first stage

 187          // First check the REQUEST parameters for other steps

 188          if( !empty( $_REQUEST['checkout_last_step'] ) && empty( $_POST['checkout_this_step'] )) {
 189              // Make sure we have an integer (max 4)

 190              $checkout_step = abs( min( $_REQUEST['checkout_last_step'], 4 ) );
 191              if( isset( $steps[$checkout_step] )) {
 192                  return $checkout_step; // it's a valid step

 193              }
 194          }
 195          $checkout_step = (int)vmGet( $_REQUEST, 'checkout_stage' );
 196          if( isset( $steps[$checkout_step] )) {
 197              return $checkout_step; // it's a valid step

 198          }
 199          // Else: we have no alternative steps given by REQUEST

 200          while ($step = current($steps)) {
 201              if( !empty($_POST['checkout_this_step']) )  {
 202                  foreach( $step as $stepname ) {
 203                      if( in_array( $stepname, $_POST['checkout_this_step'])) {
 204                          next($steps);
 205                          $key = key( $steps );
 206                          if( empty( $key )) {
 207                              // We are beyond the last index of the array and need to go "back" to the last index

 208                              end( $steps );
 209                          }
 210                          //echo "Stage: ".key( $steps );

 211                          return key($steps);
 212                          
 213                      }
 214                  }
 215              }
 216              next($steps);
 217          }
 218          return $stage;
 219      }
 220      /**

 221       * Displays the "checkout bar" using the checkout bar template

 222       *

 223       * @param array $steps_to_do Array holding all steps the customer has to make

 224       * @param array $step_msg Array containing the step messages

 225       * @param int $step_count Number of steps to make

 226       * @param int $highlighted_step The index of the recent step

 227       */
 228  	function show_checkout_bar() {
 229  
 230          global $sess, $ship_to_info_id, $shipping_rate_id, $VM_LANG;
 231          
 232          if (SHOW_CHECKOUT_BAR != '1' || defined('VM_CHECKOUT_BAR_LOADED')) {
 233              return;
 234          }
 235          // Let's assemble the steps

 236          $steps = ps_checkout::get_checkout_steps();
 237          $step_count = sizeof( $steps );
 238          $steps_tmp = $steps;
 239          $i = 0;
 240          foreach( $steps as $step ) {            
 241              foreach( $step as $step_name ) {
 242                  switch ( $step_name ) {
 243                      case 'CHECK_OUT_GET_SHIPPING_ADDR':
 244                          $step_msg = $VM_LANG->_('PHPSHOP_ADD_SHIPTO_2');
 245                          break;
 246                      case 'CHECK_OUT_GET_SHIPPING_METHOD':
 247                          $step_msg = $VM_LANG->_('PHPSHOP_ISSHIP_LIST_CARRIER_LBL');
 248                          break;
 249                      case 'CHECK_OUT_GET_PAYMENT_METHOD':
 250                          $step_msg = $VM_LANG->_('PHPSHOP_ORDER_PRINT_PAYMENT_LBL');
 251                          break;
 252                      case 'CHECK_OUT_GET_FINAL_CONFIRMATION':
 253                          $step_msg = $VM_LANG->_('PHPSHOP_CHECKOUT_CONF_PAYINFO_COMPORDER');
 254                          break;
 255                  }
 256                  $steps_to_do[$i][] = array('step_name' => $step_name,
 257                                          'step_msg' => $step_msg,
 258                                          'step_order' => key($steps_tmp) );
 259              
 260              }
 261              next( $steps_tmp );
 262              $i++;
 263          }
 264            
 265            $highlighted_step = ps_checkout::get_current_stage(); 
 266          
 267          $theme = new $GLOBALS['VM_THEMECLASS']();
 268          $theme->set_vars( array( 'step_count' => $step_count,
 269                                  'steps_to_do' => $steps_to_do,
 270                                  'steps' => $steps,
 271                                  'highlighted_step' => $highlighted_step,
 272                                  'ship_to_info_id' => vmGet($_REQUEST, 'ship_to_info_id'),
 273                                  'shipping_rate_id' => vmGet( $_REQUEST, 'shipping_rate_id')
 274                              ) );
 275                              
 276          echo $theme->fetch( 'checkout/checkout_bar.tpl.php');
 277          define('VM_CHECKOUT_BAR_LOADED', 1 );
 278      }
 279  
 280      /**

 281       * Called to validate the form values before the order is stored

 282       * 

 283       * @author gday

 284       * @author soeren

 285       * 

 286       * @param array $d

 287       * @return boolean

 288       */
 289  	function validate_form(&$d) {
 290          global $VM_LANG, $PSHOP_SHIPPING_MODULES, $vmLogger;
 291  
 292          $db = new ps_DB;
 293  
 294          $auth = $_SESSION['auth'];
 295          $cart = $_SESSION['cart'];
 296  
 297          if (!$cart["idx"]) {
 298              $q  = "SELECT order_id FROM #__{vm}_orders WHERE user_id='" . $auth["user_id"] . "' ";
 299              $q .= "ORDER BY cdate DESC";
 300              $db->query($q);
 301              $db->next_record();
 302              $d["order_id"] = $db->f("order_id");
 303              return False;
 304          }
 305          if( PSHOP_AGREE_TO_TOS_ONORDER == '1' ) {
 306              if( empty( $d["agreed"] )) {
 307                  $vmLogger->warning( $VM_LANG->_('PHPSHOP_AGREE_TO_TOS',false) );
 308                  return false;
 309              }
 310          }
 311  
 312          if ( !ps_checkout::noShippingMethodNecessary() ) {
 313              if ( !$this->validate_shipping_method($d) ) {
 314                  return False;
 315              }
 316          }
 317          if ( !$this->validate_payment_method( $d, false )) {
 318              return false;
 319          }
 320          if( CHECK_STOCK == '1' ) {
 321              for($i = 0; $i < $cart["idx"]; $i++) {
 322  
 323                  $quantity_in_stock = ps_product::get_field($cart[$i]["product_id"], 'product_in_stock');
 324                  $product_name = ps_product::get_field($cart[$i]["product_id"], 'product_name');
 325                  if( $cart[$i]["quantity"] > $quantity_in_stock ) {
 326                      $vmLogger->err( 'The Quantity for the Product "'.$product_name.'" in your Cart ('.$cart[$i]["quantity"].') exceeds the Quantity in Stock ('.$quantity_in_stock.'). 
 327                                                  We are very sorry for this Inconvenience, but you you need to lower the Quantity in Cart for this Product.');
 328                      return false;
 329                  }
 330              }
 331          }
 332          // calculate the unix timestamp for the specified expiration date

 333          // default the day to the 1st

 334          $expire_timestamp = @mktime(0,0,0,$_SESSION["ccdata"]["order_payment_expire_month"], 15,$_SESSION["ccdata"]["order_payment_expire_year"]);
 335          $_SESSION["ccdata"]["order_payment_expire"] = $expire_timestamp;
 336  
 337          return True;
 338      }
 339  
 340      /**

 341       * Validates the variables prior to adding an order

 342       *

 343       * @param array $d

 344       * @return boolean

 345       */
 346  	function validate_add(&$d) {
 347          global $auth, $VM_LANG, $vmLogger;
 348  
 349          require_once (CLASSPATH.'ps_payment_method.php');
 350          $ps_payment_method = new ps_payment_method;
 351          
 352          if( empty( $auth['user_id'] ) ) {
 353              $vmLogger->err('Sorry, but it is not possible to order without a User ID. 
 354                                          Please contact the Store Administrator if this Error occurs again.');
 355              return false;
 356          }
 357          if (!ps_checkout::noShipToNecessary()) {
 358              if (empty($d["ship_to_info_id"])) {
 359                  $vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_SHIPTO',false) );
 360                  return False;
 361              }
 362          }
 363          /*

 364          if (!$d["payment_method_id"]) {

 365              $vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_MSG_4',false) );

 366              return False;

 367          }*/
 368          if ($ps_payment_method->is_creditcard(@$d["payment_method_id"])) {
 369  
 370              if (empty($_SESSION["ccdata"]["order_payment_number"])) {
 371                  $vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_CCNR',false) );
 372                  return False;
 373              }
 374  
 375              if(!$ps_payment_method->validate_payment($d["payment_method_id"],
 376                      $_SESSION["ccdata"]["order_payment_number"])) {
 377                  $vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_CCNUM_INV',false) );
 378                  return False;
 379              }
 380  
 381              if(empty( $_SESSION["ccdata"]["order_payment_expire"])) {
 382                  $vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_CCDATE_INV',false) );
 383                  return False;
 384              }
 385          }
 386  
 387          return True;
 388      }
 389  
 390  	function validate_shipto(&$d) {
 391          //TODO to be implemented

 392      }
 393      /**

 394       * Called to validate the shipping_method

 395       *

 396       * @param array $d

 397       * @return boolean

 398       */
 399  	function validate_shipping_method(&$d) {
 400          global $VM_LANG, $PSHOP_SHIPPING_MODULES, $vmLogger;
 401          
 402          if( empty($d['shipping_rate_id']) ) {
 403              $vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_SHIP',false) );
 404              return false;
 405          }
 406          
 407          if( is_callable( array($this->_SHIPPING, 'validate') )) {
 408              
 409              if(!$this->_SHIPPING->validate( $d )) {
 410                  $vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_OTHER_SHIP',false) );
 411                  return false;
 412              }
 413          }
 414          return true;
 415      }
 416  
 417      /**

 418       * Called to validate the payment_method

 419       * If payment with CreditCard is used, than the Data must be in stored in the session

 420       * This has be done to prevent sending the CreditCard Number back in hidden fields

 421       * If the parameter $is_test is true the Number Visa Creditcard number 4111 1111 1111 1111

 422       *

 423       * @param array $d

 424       * @param boolean $is_test

 425       * @return boolean

 426       */
 427  	function validate_payment_method(&$d, $is_test) {
 428          global $VM_LANG, $vmLogger, $order_total;
 429  
 430          $auth = $_SESSION['auth'];
 431          $cart = $_SESSION['cart'];
 432          
 433          // We don't need to validate a payment method when

 434          // the user has no order total he should pay

 435          if( empty( $_REQUEST['order_total'])) {
 436              
 437              if( isset( $d['order_total'])) {
 438                  if( round( $d['order_total'], 2 ) <= 0.00 ) {
 439                      return true;
 440                  }
 441              }
 442              if( isset($order_total) && $order_total <= 0.00 ) {
 443                  return true;
 444              }
 445          }
 446          if (!isset($d["payment_method_id"]) || $d["payment_method_id"]==0 ) {
 447              $vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_PAYM',false) );
 448              return false;
 449          }
 450          require_once (CLASSPATH.'ps_payment_method.php');
 451          $ps_payment_method = new ps_payment_method;
 452  
 453          $dbp = new ps_DB; //DB Payment_method

 454  
 455          // Now Check if all needed Payment Information are entered

 456          // Bank Information is found in the User_Info

 457          $w  = "SELECT `enable_processor` FROM `#__{vm}_payment_method` WHERE ";
 458          $w .= "payment_method_id=" .  (int)$d["payment_method_id"];
 459          $dbp->query($w);
 460          $dbp->next_record();
 461          
 462          if (($dbp->f("enable_processor") == "Y") 
 463              || ($dbp->f("enable_processor") == "")) {
 464  
 465              // Creditcard

 466              if (empty( $_SESSION['ccdata']['creditcard_code']) ) {
 467                  $vmLogger->err( $VM_LANG->_('VM_CHECKOUT_ERR_CCTYPE') );
 468                  return false;
 469              }
 470  
 471              // $_SESSION['ccdata'] = $ccdata;

 472              // The Data should be in the session

 473              if (!isset($_SESSION['ccdata'])) { //Not? Then Error
 474                  $vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_CCDATA',false) );
 475                  return False;
 476              }
 477  
 478              if (!$_SESSION['ccdata']['order_payment_number']) {
 479                  $vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_CCNR_FOUND',false) );
 480                  return False;
 481              }
 482  
 483              // CREDIT CARD NUMBER CHECK

 484              // USING THE CREDIT CARD CLASS in ps_payment

 485              if(!$ps_payment_method->validate_payment( $_SESSION['ccdata']['creditcard_code'], $_SESSION['ccdata']['order_payment_number'])) {
 486                  $vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_CCDATE',false) );
 487                  return False;
 488              }
 489  
 490              if (!$is_test) {
 491                  $payment_number = ereg_replace(" |-", "", $_SESSION['ccdata']['order_payment_number']);
 492                  if ($payment_number == "4111111111111111") {
 493                      $vmLogger->warning( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_TEST',false) );
 494                      return False;
 495                  }
 496              }
 497              if(!empty($_SESSION['ccdata']['need_card_code']) && empty($_SESSION['ccdata']['credit_card_code'])) {
 498                  $vmLogger->err( $VM_LANG->_('PHPSHOP_CUSTOMER_CVV2_ERROR',false) );
 499                  return False;
 500              }
 501              if(!$_SESSION['ccdata']['order_payment_expire_month']) {
 502                  $vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_CCMON',false) );
 503                  return False;
 504              }
 505              if(!$_SESSION['ccdata']['order_payment_expire_year']) {
 506                  $vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_CCYEAR',false) );
 507                  return False;
 508              }
 509              $date = getdate( time() );
 510              if ($_SESSION['ccdata']['order_payment_expire_year'] < $date["year"] or
 511              ($_SESSION['ccdata']['order_payment_expire_year'] == $date["year"] and
 512              $_SESSION['ccdata']['order_payment_expire_month'] < $date["mon"])) {
 513                  $vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_CCDATE_INV',false) );
 514                  return False;
 515              }
 516              return True;
 517          }
 518          elseif ($dbp->f("enable_processor") == "B") {
 519              $_SESSION['ccdata']['creditcard_code'] = "";
 520              $_SESSION['ccdata']['order_payment_name']  = "";
 521              $_SESSION['ccdata']['order_payment_number']  = "";
 522              $_SESSION['ccdata']['order_payment_expire_month'] = "";
 523              $_SESSION['ccdata']['order_payment_expire_year'] = "";
 524              // Bank Account

 525              require_once ( CLASSPATH . 'ps_user.php' );
 526              $dbu =& ps_user::getUserInfo( $auth["user_id"], array( 'bank_account_holder','bank_iban','bank_account_nr','bank_sort_code','bank_name' ) ); 
 527  
 528              if ( $dbu->f("bank_account_holder") == "" || $dbu->f("bank_account_nr") =="" ) {
 529                  if( !empty($d['bank_account_holder']) && !empty($d['bank_account_nr'])) {
 530                      // Insert the given data

 531                      $fields = array( 'bank_account_holder' => $d['bank_account_holder'],
 532                              'bank_account_nr' => $d['bank_account_nr'],
 533                              'bank_sort_code' => $d['bank_sort_code'],
 534                              'bank_name' => $d['bank_name'],
 535                              'bank_iban' => $d['bank_iban']
 536                              );
 537                      ps_user::setUserInfo( $fields, $auth["user_id"] );
 538  
 539                      $dbu =& ps_user::getUserInfo( $auth["user_id"], array( 'bank_account_holder','bank_iban','bank_account_nr','bank_sort_code','bank_name' ) ); 
 540                  }
 541                  else {
 542                      $vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_USER_DATA',false) );
 543                      return False;
 544                  }
 545              }
 546              if ($dbu->f("bank_account_holder") == ""){
 547                  $vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_BA_HOLDER_NAME',false) );
 548                  return False;
 549              }
 550              if (($dbu->f("bank_iban") == "") and
 551              ($dbu->f("bank_account_nr") =="")) {
 552                  $vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_IBAN',false) );
 553                  return False;
 554              }
 555              if ($dbu->f("bank_iban") == "") {
 556                  if ($dbu->f("bank_account_nr") == ""){
 557                      $vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_BA_NUM',false) );
 558                      return False;
 559                  }
 560                  if ($dbu->f("bank_sort_code") == ""){
 561                      $vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_BANK_SORT',false) );
 562                      return False;
 563                  }
 564                  if ($dbu->f("bank_name") == ""){
 565                      $vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_BANK_NAME',false) );
 566                      return False;
 567                  }
 568              }
 569          }
 570          else {
 571              $_SESSION['ccdata']['creditcard_code'] = '';
 572              $_SESSION['ccdata']['order_payment_name']  = "";
 573              $_SESSION['ccdata']['order_payment_number']  = "";
 574              $_SESSION['ccdata']['order_payment_expire_month'] = "";
 575              $_SESSION['ccdata']['order_payment_expire_year'] = "";
 576          }
 577          // Enter additional Payment check procedures here if neccessary

 578  
 579          return True;
 580      }
 581  
 582      /**

 583       * Update order details

 584       * CURRENTLY UNUSED

 585       *

 586       * @param array $d

 587       * @return boolean

 588       */
 589  	function update(&$d) {
 590          global $vmLogger;
 591          
 592          $db = new ps_DB;
 593          $timestamp = time();
 594  
 595  
 596          if ($this->validate_update($d)) {
 597              return True;
 598          }
 599          else {
 600              $vmLogger->err( $this->error );
 601              return False;
 602          }
 603      }
 604  
 605      /**

 606       * Control Function for the Checkout Process

 607       * @author Ekkhard Domning

 608       * @author soeren

 609       * @param array $d

 610       * @return boolean

 611       */
 612  	function process(&$d) {
 613          global $checkout_this_step, $sess,$VM_LANG, $vmLogger;
 614          $ccdata = array();
 615  
 616          if( empty($d["checkout_this_step"]) || !is_array(@$d["checkout_this_step"])) {
 617              $vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_VALID_STEP',false) );
 618              return false;
 619          }
 620          
 621          foreach($d["checkout_this_step"] as $checkout_this_step) {
 622          
 623              switch($checkout_this_step) {
 624                  
 625                  case 'CHECK_OUT_GET_FINAL_BASKET' :
 626                      break;
 627      
 628                  case 'CHECK_OUT_GET_SHIPPING_ADDR' :        
 629                      // The User has choosen a Shipping address

 630                      if (empty($d["ship_to_info_id"])) {
 631                          $vmLogger->err( $VM_LANG->_('PHPSHOP_CHECKOUT_ERR_NO_SHIPTO',false) );
 632                          unset( $_POST['checkout_this_step']);
 633                          return False;
 634                      }
 635                      break;
 636      
 637                  case 'CHECK_OUT_GET_SHIPPING_METHOD':
 638                      // The User has choosen a Shipping method

 639                      if (!$this->validate_shipping_method($d)) {
 640                          unset( $_POST['checkout_this_step']);
 641                          return false;
 642                      }
 643                      break;
 644      
 645                  case 'CHECK_OUT_GET_PAYMENT_METHOD':
 646                      
 647                      // The User has choosen a payment method

 648                      $_SESSION['ccdata']['order_payment_name'] = @$d['order_payment_name'];
 649                      // VISA, AMEX, DISCOVER....

 650                      $_SESSION['ccdata']['creditcard_code'] = @$d['creditcard_code'];
 651                      $_SESSION['ccdata']['order_payment_number'] = @$d['order_payment_number'];
 652                      $_SESSION['ccdata']['order_payment_expire_month'] = @$d['order_payment_expire_month'];
 653                      $_SESSION['ccdata']['order_payment_expire_year'] = @$d['order_payment_expire_year'];
 654                      // 3-digit Security Code (CVV)

 655                      $_SESSION['ccdata']['credit_card_code'] = @$d['credit_card_code'];
 656          
 657                      if (!$this->validate_payment_method($d, false)) { //Change false to true to Let the user play with the VISA Testnumber
 658                          unset( $_POST['checkout_this_step']);
 659                          return false;
 660                      }
 661                      
 662                      break;
 663      
 664                  case 'CHECK_OUT_GET_FINAL_CONFIRMATION':
 665      
 666                      // The User wants to order now, validate everything, if OK than Add immeditialtly

 667                      return( $this->add( $d ) );
 668      
 669                  default:
 670                      $vmLogger->crit( "CheckOut step ($checkout_this_step) is undefined!" );
 671                      return false;
 672      
 673              } // end switch

 674          }
 675          return true;
 676      } // end function process

 677  
 678      /**

 679       * Prints the List of all shipping addresses of a user

 680       *

 681       * @param unknown_type $user_id

 682       * @param unknown_type $name

 683       * @param unknown_type $value

 684       */
 685  	function ship_to_addresses_radio($user_id, $name, $value) {
 686          echo ps_checkout::list_addresses( $user_id, $name, $value );
 687      }
 688      /**

 689       * Creates a Radio List of all shipping addresses of a user

 690       *

 691       * @param int $user_id

 692       * @param string $name

 693       * @param string $value

 694       */
 695  	function list_addresses( $user_id, $name, $value ) {
 696          global $sess,$VM_LANG;
 697  
 698          $db = new ps_DB;
 699  
 700          /* Select all the ship to information for this user id and

 701          * order by modification date; most recently changed to oldest

 702          */
 703          $q  = "SELECT * from #__{vm}_user_info WHERE ";
 704          $q .= "user_id=" . (int)$user_id . ' ';
 705          $q .= "AND address_type='BT'";
 706          $db->query($q);
 707          $db->next_record();
 708  
 709          $bt_user_info_id = $db->f("user_info_id");
 710  
 711          $q  = "SELECT * FROM #__{vm}_user_info i ";
 712          $q .= "INNER JOIN #__{vm}_country c ON (i.country=c.country_3_code) ";
 713          $q .= "LEFT JOIN #__{vm}_state s ON (i.state=s.state_2_code AND s.country_id=c.country_id) ";
 714          $q .= "WHERE user_id =" . (int)$user_id . ' ';
 715          $q .= "AND address_type = 'ST' ";
 716          $q .= "ORDER by address_type_name, mdate DESC";
 717  
 718          $db->query($q);
 719          
 720          $theme = vmTemplate::getInstance();
 721          $theme->set_vars(array('db' => $db,
 722                                  'user_id' => $user_id,
 723                                  'name' => $name,
 724                                  'value' => $value,
 725                                  'bt_user_info_id' => $bt_user_info_id,
 726                               )
 727                           );
 728  
 729          echo $theme->fetch( 'checkout/list_shipto_addresses.tpl.php');
 730      }
 731  
 732      /**

 733       * Fetches the address information for the currently logged in user

 734       *

 735       * @param string $address_type Can be BT (Bill To) or ST (Shipto address)

 736       */
 737  	function display_address($address_type='BT') {
 738          $auth = $_SESSION['auth'];
 739          
 740          $address_type = $address_type == 'BT' ? $address_type : 'ST';
 741          
 742          $db = new ps_DB;
 743          $q  = "SELECT * FROM #__{vm}_user_info i ";
 744          $q .= "INNER JOIN #__{vm}_country c ON (i.country=c.country_3_code OR i.country=c.country_2_code) ";
 745          $q .= "LEFT JOIN #__{vm}_state s ON (i.state=s.state_2_code AND s.country_id=c.country_id) ";
 746          $q .= "WHERE user_id='" . $auth["user_id"] . "' ";
 747          $q .= "AND address_type='BT'";
 748          $db->query($q);
 749          $db->next_record();
 750          $theme = new $GLOBALS['VM_THEMECLASS']();
 751          $theme->set('db', $db );
 752          
 753          return $theme->fetch('checkout/customer_info.tpl.php');
 754          
 755      }
 756      /**

 757       * Lists Shipping Methods of all published Shipping Modules

 758       *

 759       * @param string $ship_to_info_id

 760       * @param string $shipping_method_id

 761       */
 762  	function list_shipping_methods( $ship_to_info_id=null, $shipping_method_id=null ) {
 763          global $PSHOP_SHIPPING_MODULES, $vmLogger, $auth, $weight_total;
 764          
 765          if( empty( $ship_to_info_id )) {
 766              // Get the Bill to user_info_id

 767              $database = new ps_DB();
 768              $database->setQuery( "SELECT user_info_id FROM #__{vm}_user_info WHERE user_id=".$auth['user_id']." AND address_type='BT'" );
 769              $vars["ship_to_info_id"] = $_REQUEST['ship_to_info_id'] = $database->loadResult();
 770          } else {
 771              $vars['ship_to_info_id'] = $ship_to_info_id;
 772          }
 773          $vars['shipping_rate_id'] = $shipping_method_id;
 774          $vars["weight"] = $weight_total;
 775          $vars['zone_qty'] = vmRequest::getInt( 'zone_qty', 0 );
 776          $i = 0;
 777  
 778          $theme = new $GLOBALS['VM_THEMECLASS']();
 779          $theme->set_vars(array('vars' => $vars,
 780                                  'PSHOP_SHIPPING_MODULES' => $PSHOP_SHIPPING_MODULES
 781                               )
 782                           );
 783  
 784          echo $theme->fetch( 'checkout/list_shipping_methods.tpl.php');
 785          
 786      }
 787      /**

 788       * Lists the payment methods of all available payment modules

 789       * @static 

 790       * @param int $payment_method_id

 791       */
 792  	function list_payment_methods( $payment_method_id=0 ) {
 793          global $order_total, $sess, $VM_CHECKOUT_MODULES;
 794          $ps_vendor_id = $_SESSION['ps_vendor_id'];
 795          $auth = $_SESSION['auth'];
 796          
 797          $ship_to_info_id = vmGet( $_REQUEST, 'ship_to_info_id' );
 798          $shipping_rate_id = vmGet( $_REQUEST, 'shipping_rate_id' );
 799          
 800          require_once (CLASSPATH . 'ps_payment_method.php');
 801          $ps_payment_method = new ps_payment_method;
 802          require_once ( CLASSPATH. 'ps_creditcard.php' );
 803          $ps_creditcard = new ps_creditcard();
 804          $count = 0;
 805          // Do we have Credit Card Payments?

 806          $db_cc  = new ps_DB;
 807          $q = "SELECT * from #__{vm}_payment_method,#__{vm}_shopper_group WHERE ";
 808          $q .= "#__{vm}_payment_method.shopper_group_id=#__{vm}_shopper_group.shopper_group_id ";
 809          $q .= "AND (#__{vm}_payment_method.shopper_group_id='".$auth['shopper_group_id']."' ";
 810          $q .= "OR #__{vm}_shopper_group.default='1') ";
 811          $q .= "AND (enable_processor='' OR enable_processor='Y') ";
 812          $q .= "AND payment_enabled='Y' ";
 813          $q .= "AND #__{vm}_payment_method.vendor_id='$ps_vendor_id' ";
 814          $q .= " ORDER BY list_order";
 815          $db_cc->query($q);
 816          
 817          if ($db_cc->num_rows()) {
 818              $first_payment_method_id = $db_cc->f("payment_method_id");
 819              $count += $db_cc->num_rows();
 820              $cc_payments=true;
 821          }
 822          else {
 823              $cc_payments=false;
 824          }
 825          
 826          $db_nocc  = new ps_DB;
 827          $q = "SELECT * from #__{vm}_payment_method,#__{vm}_shopper_group WHERE ";
 828          $q .= "#__{vm}_payment_method.shopper_group_id=#__{vm}_shopper_group.shopper_group_id ";
 829          $q .= "AND (#__{vm}_payment_method.shopper_group_id='".$auth['shopper_group_id']."' ";
 830          $q .= "OR #__{vm}_shopper_group.default='1') ";
 831          $q .= "AND (enable_processor='B' OR enable_processor='N' OR enable_processor='P') ";
 832          $q .= "AND payment_enabled='Y' ";
 833          $q .= "AND #__{vm}_payment_method.vendor_id='$ps_vendor_id' ";
 834          $q .= " ORDER BY list_order";
 835          $db_nocc->query($q);
 836          if ($db_nocc->next_record()) {
 837              $nocc_payments=true;
 838              $first_payment_method_id = $db_nocc->f("payment_method_id");
 839              $count += $db_nocc->num_rows();
 840              $db_nocc->reset();
 841          }
 842          else {
 843              $nocc_payments=false;
 844          }
 845          // Redirect to the last step when there's only one payment method

 846          if( $VM_CHECKOUT_MODULES['CHECK_OUT_GET_PAYMENT_METHOD']['order'] != $VM_CHECKOUT_MODULES['CHECK_OUT_GET_FINAL_CONFIRMATION']['order'] ) {
 847              if ($count <= 1 && $cc_payments==false) {
 848                  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 ),"");
 849              }
 850              elseif( isset($order_total) && $order_total <= 0.00 ) {
 851                  // In case the order total is less than or equal zero, we don't need a payment method

 852                  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),"");
 853              }
 854          }
 855          $theme = new $GLOBALS['VM_THEMECLASS']();
 856          $theme->set_vars(array('db_nocc' => $db_nocc,
 857                                  'db_cc' => $db_cc,
 858                                  'nocc_payments' => $nocc_payments,
 859                                  'payment_method_id' => $payment_method_id,
 860                                  'first_payment_method_id' => $first_payment_method_id,
 861                                  'count' => $count,
 862                                  'cc_payments' => $cc_payments,
 863                                  'ps_creditcard' => $ps_creditcard,
 864                                  'ps_payment_method' => $ps_payment_method
 865                               )
 866                           );
 867  
 868          echo $theme->fetch( 'checkout/list_payment_methods.tpl.php');
 869          
 870      }
 871      /**

 872       * This is the main function which stores the order information in the database

 873       * 

 874       * @author gday, soeren, many others!

 875       * @param array $d The REQUEST/$vars array

 876       * @return boolean

 877       */
 878  	function add( &$d ) {
 879          global $order_tax_details, $afid, $VM_LANG, $auth, $my, $mosConfig_offset,
 880          $vmLogger, $vmInputFilter, $discount_factor;
 881  
 882          $ps_vendor_id = $_SESSION["ps_vendor_id"];
 883          
 884          $cart = $_SESSION['cart'];
 885  
 886          require_once (CLASSPATH. 'ps_payment_method.php' );
 887          $ps_payment_method = new ps_payment_method;
 888          require_once (CLASSPATH. 'ps_product.php' );
 889          $ps_product= new ps_product;
 890          require_once (CLASSPATH.'ps_cart.php');
 891          $ps_cart = new ps_cart;
 892  
 893          $db = new ps_DB;
 894  
 895          /* Set the order number */

 896          $order_number = $this->get_order_number();
 897  
 898          $totals = $this->calc_order_totals( $d );
 899          extract( $totals );
 900          
 901          //$timestamp = time() + ($mosConfig_offset*60*60);  //Original

 902          $timestamp = time();  //Custom

 903          
 904          if (!$this->validate_form($d)) {
 905              return false;
 906          }
 907  
 908          if (!$this->validate_add($d)) {
 909              return false;
 910          }
 911  
 912          // make sure Total doesn't become negative

 913          if( $order_total < 0 ) $order_total = 0;
 914  
 915          $order_total = round( $order_total, 2);
 916  
 917  
 918          $vmLogger->debug( '-- Checkout Debug--
 919          
 920  Subtotal: '.$order_subtotal.'
 921  Taxable: '.$order_taxable.'
 922  Payment Discount: '.$payment_discount.'
 923  Coupon Discount: '.$coupon_discount.'
 924  Shipping: '.$order_shipping.'
 925  Shipping Tax : '.$order_shipping_tax.'
 926  Tax : '.$order_tax.'
 927  ------------------------
 928  Order Total: '.$order_total.'
 929  ----------------------------' 
 930          );
 931  
 932          // Check to see if Payment Class File exists

 933          $payment_class = $ps_payment_method->get_field($d["payment_method_id"], "payment_class");
 934          $enable_processor = $ps_payment_method->get_field($d["payment_method_id"], "enable_processor");
 935  
 936          if (file_exists(CLASSPATH . "payment/$payment_class.php") ) {
 937              if( !class_exists( $payment_class )) {
 938                  include( CLASSPATH. "payment/$payment_class.php" );
 939              }
 940  
 941              $_PAYMENT = new $payment_class();
 942              if (!$_PAYMENT->process_payment($order_number,$order_total, $d)) {
 943                  $vmLogger->err( $VM_LANG->_('PHPSHOP_PAYMENT_ERROR',false)." ($payment_class)" );
 944                  $_SESSION['last_page'] = "checkout.index";
 945                  $_REQUEST["checkout_next_step"] = CHECK_OUT_GET_PAYMENT_METHOD;
 946                  return False;
 947              }
 948          }
 949  
 950          else {
 951              $d["order_payment_log"] = $VM_LANG->_('PHPSHOP_CHECKOUT_MSG_LOG');
 952          }
 953  
 954          // Remove the Coupon, because it is a Gift Coupon and now is used!!

 955          if( @$_SESSION['coupon_type'] == "gift" ) {
 956              $d['coupon_id'] = $_SESSION['coupon_id'];
 957              include_once ( CLASSPATH.'ps_coupon.php' );
 958              ps_coupon::remove_coupon_code( $d );
 959          }
 960          
 961          // Get the IP Address

 962          if (!empty($_SERVER['REMOTE_ADDR'])) {
 963              $ip = $_SERVER['REMOTE_ADDR'];
 964          }
 965          else {
 966              $ip = 'unknown';
 967          }
 968          
 969          // Collect all fields and values to store them!

 970          $fields = array(
 971              'user_id' => $auth["user_id"], 
 972              'vendor_id' => $ps_vendor_id, 
 973              'order_number' => $order_number, 
 974              'user_info_id' =>  $d["ship_to_info_id"], 
 975              'ship_method_id' => @urldecode($d["shipping_rate_id"]),
 976              'order_total' => $order_total, 
 977              'order_subtotal' => $order_subtotal, 
 978              'order_tax' => $order_tax, 
 979              'order_tax_details' => serialize($order_tax_details), 
 980              'order_shipping' => $order_shipping,
 981              'order_shipping_tax' => $order_shipping_tax, 
 982              'order_discount' => $payment_discount, 
 983              'coupon_discount' => $coupon_discount,
 984              'coupon_code' => @$_SESSION['coupon_code'],
 985              'order_currency' => $GLOBALS['product_currency'], 
 986              'order_status' => 'P', 
 987              'cdate' => $timestamp,
 988              'mdate' => $timestamp,
 989              'customer_note' => htmlspecialchars(vmRequest::getString('customer_note','', 'POST', 'none' ), ENT_QUOTES ),
 990              'ip_address' => $ip
 991              );
 992  
 993          // Insert the main order information

 994          $db->buildQuery( 'INSERT', '#__{vm}_orders', $fields );
 995          $result = $db->query();
 996  
 997          $d["order_id"] = $order_id = $db->last_insert_id();
 998          if( $result === false || empty( $order_id )) {
 999              $vmLogger->crit( 'Adding the Order into the Database failed! User ID: '.$auth["user_id"] );
1000              return false;
1001          }
1002  
1003          // Insert the initial Order History.        

1004          $mysqlDatetime = date("Y-m-d G:i:s", $timestamp);
1005          
1006          $fields = array(
1007                      'order_id' => $order_id,
1008                      'order_status_code' => 'P',
1009                      'date_added' => $mysqlDatetime,
1010                      'customer_notified' => 1,
1011                      'comments' => ''
1012                    );
1013          $db->buildQuery( 'INSERT', '#__{vm}_order_history', $fields );
1014          $db->query();
1015  
1016          /**

1017          * Insert the Order payment info 

1018          */
1019          $payment_number = ereg_replace(" |-", "", @$_SESSION['ccdata']['order_payment_number']);
1020  
1021          $d["order_payment_code"] = @$_SESSION['ccdata']['credit_card_code'];
1022  
1023          // Payment number is encrypted using mySQL encryption functions.

1024          $fields = array(
1025                      'order_id' => $order_id, 
1026                      'payment_method_id' => $d["payment_method_id"], 
1027                      'order_payment_log' => @$d["order_payment_log"], 
1028                      'order_payment_trans_id' => $vmInputFilter->safeSQL( @$d["order_payment_trans_id"] )
1029                    );
1030          if( !empty( $payment_number ) && VM_STORE_CREDITCARD_DATA == '1' ) {
1031              // Store Credit Card Information only if the Store Owner has decided to do so

1032              $fields['order_payment_code'] = $d["order_payment_code"];
1033              $fields['order_payment_expire'] = @$_SESSION["ccdata"]["order_payment_expire"];
1034              $fields['order_payment_name'] = @$_SESSION["ccdata"]["order_payment_name"];
1035              $fields['order_payment_number'] = VM_ENCRYPT_FUNCTION."( '$payment_number','" . ENCODE_KEY . "')";
1036              $specialfield = array('order_payment_number');
1037          } else {
1038              $specialfield = array();
1039          }
1040          $db->buildQuery( 'INSERT', '#__{vm}_order_payment', $fields, '', $specialfield );
1041          $db->query();
1042  
1043          /**

1044          * Insert the User Billto & Shipto Info

1045          */
1046          // First: get all the fields from the user field list to copy them from user_info into the order_user_info

1047          $fields = array();
1048          require_once ( CLASSPATH . 'ps_userfield.php' );
1049          $userfields = ps_userfield::getUserFields('', false, '', true, true );
1050          foreach ( $userfields as $field ) {
1051              if ($field->name=='email') $fields[] = 'user_email'; 
1052              else $fields[] = $field->name;            
1053          }
1054          $fieldstr = implode( ',', $fields );
1055          // Save current Bill To Address

1056          $q = "INSERT INTO `#__{vm}_order_user_info` 
1057              (`order_info_id`,`order_id`,`user_id`,address_type, ".$fieldstr.") ";
1058          $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'";
1059          $db->query( $q );
1060  
1061          // Save current Ship to Address if applicable

1062          $q = "INSERT INTO `#__{vm}_order_user_info` 
1063              (`order_info_id`,`order_id`,`user_id`,address_type, ".$fieldstr.") ";
1064          $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'";
1065          $db->query( $q );
1066  
1067          /**

1068          * Insert all Products from the Cart into order line items; 

1069          * one row per product in the cart 

1070          */
1071          $dboi = new ps_DB;
1072  
1073          for($i = 0; $i < $cart["idx"]; $i++) {
1074  
1075              $r = "SELECT product_id,product_in_stock,product_sales,product_parent_id,product_sku,product_name ";
1076              $r .= "FROM #__{vm}_product WHERE product_id='".$cart[$i]["product_id"]."'";
1077              $dboi->query($r);
1078              $dboi->next_record();
1079  
1080              $product_price_arr = $ps_product->get_adjusted_attribute_price($cart[$i]["product_id"], $cart[$i]["description"]);
1081              $product_price = $GLOBALS['CURRENCY']->convert( $product_price_arr["product_price"], $product_price_arr["product_currency"] );
1082  
1083              if( empty( $_SESSION['product_sess'][$cart[$i]["product_id"]]['tax_rate'] )) {
1084                  $my_taxrate = $ps_product->get_product_taxrate($cart[$i]["product_id"] );
1085              }
1086              else {
1087                  $my_taxrate = $_SESSION['product_sess'][$cart[$i]["product_id"]]['tax_rate'];
1088              }
1089              // Attribute handling

1090              $product_parent_id = $dboi->f('product_parent_id');
1091              $description = '';
1092              if( $product_parent_id > 0 ) {
1093                  
1094                  $db_atts = $ps_product->attribute_sql( $dboi->f('product_id'), $product_parent_id );
1095                  while( $db_atts->next_record()) {
1096                      $description .=    $db_atts->f('attribute_name').': '.$db_atts->f('attribute_value').'; ';
1097                  }
1098              }
1099              
1100              $description .= $ps_product->getDescriptionWithTax($_SESSION['cart'][$i]["description"], $dboi->f('product_id'));
1101              
1102              $product_final_price = round( ($product_price *($my_taxrate+1)), 2 );
1103  
1104              $vendor_id = $ps_vendor_id;
1105              
1106              $fields = array('order_id' => $order_id, 
1107                                      'user_info_id' => $d["ship_to_info_id"],
1108                                      'vendor_id' => $vendor_id, 
1109                                      'product_id' => $cart[$i]["product_id"], 
1110                                      'order_item_sku' => $dboi->f("product_sku"), 
1111                                      'order_item_name' => $dboi->f("product_name"), 
1112                                      'product_quantity' => $cart[$i]["quantity"], 
1113                                      'product_item_price' => $product_price, 
1114                                      'product_final_price' => $product_final_price,         
1115                                      'order_item_currency' => $GLOBALS['product_currency'],
1116                                      'order_status' => 'P', 
1117                                      'product_attribute' => $description, 
1118                                      'cdate' => $timestamp, 
1119                                      'mdate' => $timestamp
1120                          );
1121              $db->buildQuery( 'INSERT', '#__{vm}_order_item', $fields );
1122              $db->query();
1123  
1124              // Update Stock Level and Product Sales, decrease - no matter if in stock or not!

1125              $q = "UPDATE #__{vm}_product ";
1126              $q .= "SET product_in_stock = product_in_stock - ".(int)$cart[$i]["quantity"];
1127              $q .= " WHERE product_id = '" . $cart[$i]["product_id"]. "'";
1128              $db->query($q);
1129  
1130              $q = "UPDATE #__{vm}_product ";
1131              $q .= "SET product_sales= product_sales + ".(int)$cart[$i]["quantity"];
1132              $q .= " WHERE product_id='".$cart[$i]["product_id"]."'";
1133              $db->query($q);
1134  
1135          }
1136  
1137          ######## BEGIN DOWNLOAD MOD ###############

1138          if( ENABLE_DOWNLOADS == "1" ) {
1139              require_once ( CLASSPATH.'ps_order.php');
1140              for($i = 0; $i < $cart["idx"]; $i++) {
1141                  // only handle downloadable products here

1142                  if( ps_product::is_downloadable($cart[$i]["product_id"])) {
1143                      $params = array('product_id' => $cart[$i]["product_id"], 'order_id' => $order_id, 'user_id' => $auth["user_id"] );
1144                      ps_order::insert_downloads_for_product( $params );
1145                      
1146                      if( @VM_DOWNLOADABLE_PRODUCTS_KEEP_STOCKLEVEL == '1' ) {
1147                          // Update the product stock level back to where it was.

1148                          $q = "UPDATE #__{vm}_product ";
1149                          $q .= "SET product_in_stock = product_in_stock + ".(int)$cart[$i]["quantity"];
1150                          $q .= " WHERE product_id = '" .(int)$cart[$i]["product_id"]. "'";
1151                          $db->query($q);
1152                      }
1153                  }
1154              }
1155          }
1156          ################## END DOWNLOAD MOD ###########

1157  
1158          // Export the order_id so the checkout complete page can get it

1159          $d["order_id"] = $order_id;
1160  
1161          /*

1162           * Let the shipping module know which shipping method

1163           * was selected.  This way it can save any information

1164           * it might need later to print a shipping label.

1165           */
1166          if( is_callable( array($this->_SHIPPING, 'save_rate_info') )) {
1167              $this->_SHIPPING->save_rate_info($d);
1168          }
1169  
1170          // Now as everything else has been done, we can update

1171          // the Order Status if the Payment Method is

1172          // "Use Payment Processor", because:

1173          // Payment Processors return false on any error

1174          // Only completed payments return true!

1175          $update_order = false;
1176          if( $enable_processor == "Y" ) {
1177              if( defined($_PAYMENT->payment_code.'_VERIFIED_STATUS')) {
1178                    $d['order_status'] = constant($_PAYMENT->payment_code.'_VERIFIED_STATUS');
1179                    $update_order = true;
1180              }
1181          } elseif( $order_total == 0.00 ) {
1182              // If the Order Total is zero, we can confirm the order to automatically enable the download

1183              $d['order_status'] = ENABLE_DOWNLOAD_STATUS;
1184              $update_order = true;
1185          }
1186          if ( $update_order ) {
1187              require_once (CLASSPATH."ps_order.php");
1188              $ps_order = new ps_order();
1189              $ps_order->order_status_update($d);
1190          }
1191          
1192  
1193          // Send the e-mail confirmation messages

1194          $this->email_receipt($order_id);
1195  
1196          // Reset the cart (=empty it)

1197          $ps_cart->reset();
1198          $_SESSION['savedcart']['idx']=0;
1199          $ps_cart->saveCart();
1200  
1201          // Unset the payment_method variables

1202          $d["payment_method_id"] = "";
1203          $d["order_payment_number"] = "";
1204          $d["order_payment_expire"] = "";
1205          $d["order_payment_name"] = "";
1206          $d["credit_card_code"] = "";
1207          // Clear the sensitive Session data

1208          $_SESSION['ccdata']['order_payment_name']  = "";
1209          $_SESSION['ccdata']['order_payment_number']  = "";
1210          $_SESSION['ccdata']['order_payment_expire_month'] = "";
1211          $_SESSION['ccdata']['order_payment_expire_year'] = "";
1212          $_SESSION['ccdata']['credit_card_code'] = "";
1213          $_SESSION['coupon_discount'] = "";
1214          $_SESSION['coupon_id'] = "";
1215          $_SESSION['coupon_redeemed'] = false;
1216          
1217          $_POST["payment_method_id"] = "";
1218          $_POST["order_payment_number"] = "";
1219          $_POST["order_payment_expire"] = "";
1220          $_POST["order_payment_name"] = "";
1221          /*

1222          if( empty($my->id) && !empty( $auth['user_id'])) {

1223              require_once(CLASSPATH.'ps_user.php');

1224              ps_user::logout();

1225          }

1226          */
1227          return True;
1228      }
1229  
1230      /**

1231       * Create an order number using the session id, session

1232       * name, and the current unix timestamp.

1233       *

1234       * @return string

1235       */
1236  	function get_order_number() {
1237          global $auth;
1238  
1239          /* Generated a unique order number */

1240  
1241          $str = session_id();
1242          $str .= (string)time();
1243  
1244          $order_number = $auth['user_id'] .'_'. md5($str);
1245  
1246          return substr($order_number, 0, 32);
1247      }
1248      /**

1249           * Stores the md5 hash of the recent cart in the var _cartHash

1250           *

1251           */
1252  	function generate_cart_hash() {
1253          $this->_cartHash = $this->get_new_cart_hash();
1254      }
1255      
1256  	function get_order_total( &$d ) {
1257          global $discount_factor;
1258          $totals = $this->calc_order_totals($d);
1259          return $totals['order_total'];
1260      }
1261      
1262      /**

1263       * Calculates the current order totals and fills an array with all the values

1264       *

1265       * @param array $d

1266       * @return array

1267       */
1268  	function calc_order_totals( &$d ) {
1269          global $discount_factor, $mosConfig_offset;
1270          
1271          $totals = array();
1272          
1273          /* sets _subtotal */

1274          $totals['order_subtotal'] = $tmp_subtotal = $this->calc_order_subtotal($d);
1275          
1276          $totals['order_taxable'] = $this->calc_order_taxable($d);
1277          
1278          if( !empty($d['payment_method_id'])) {
1279              $totals['payment_discount'] = $d['payment_discount'] = $this->get_payment_discount($d['payment_method_id'], $totals['order_subtotal']);
1280          } else {
1281              $totals['payment_discount'] = $d['payment_discount'] = 0.00;
1282          }
1283  
1284          /* DISCOUNT HANDLING */

1285          if( !empty($_SESSION['coupon_discount']) ) {
1286              $totals['coupon_discount'] = floatval($_SESSION['coupon_discount']);
1287          }
1288          else {
1289              $totals['coupon_discount'] = 0.00;
1290          }
1291  
1292          // make sure Total doesn't become negative

1293          if( $tmp_subtotal < 0 ) $totals['order_subtotal'] = $tmp_subtotal = 0;
1294          if( $totals['order_taxable'] < 0 ) $totals['order_taxable'] = 0;
1295  
1296          // from now on we have $order_tax_details

1297          $d['order_tax'] = $totals['order_tax'] = round( $this->calc_order_tax($totals['order_taxable'], $d), 2 );
1298          
1299          if( is_object($this->_SHIPPING) ) {
1300              /* sets _shipping */

1301              $d['order_shipping'] = $totals['order_shipping'] = round( $this->calc_order_shipping( $d ), 2 );
1302  
1303              /* sets _shipping_tax

1304              * btw: This is WEIRD! To get an exactly rounded value we have to convert

1305              * the amount to a String and call "round" with the string. */
1306              $d['order_shipping_tax'] = $totals['order_shipping_tax'] = round( strval($this->calc_order_shipping_tax($d)), 2 );
1307          }
1308          else {
1309              $d['order_shipping'] = $totals['order_shipping'] = $totals['order_shipping_tax'] = $d['order_shipping_tax'] = 0.00;
1310          }
1311  
1312          $d['order_total'] = $totals['order_total'] =     $tmp_subtotal 
1313                                              + $totals['order_tax']
1314                                              + $totals['order_shipping']
1315                                              + $totals['order_shipping_tax']
1316                                              - $totals['coupon_discount']
1317                                              - $totals['payment_discount'];
1318          
1319          $totals['order_tax'] *= $discount_factor;
1320  
1321          return $totals;
1322      }
1323      /**

1324           * Generates the md5 hash of the recent cart / checkout constellation

1325           *

1326           * @return unknown

1327           */
1328  	function get_new_cart_hash() {
1329  
1330          return md5( print_r( $_SESSION['cart'], true)
1331          . vmGet($_REQUEST,'shipping_rate_id')
1332          . vmGet($_REQUEST,'payment_method_id')
1333          );
1334  
1335      }
1336  
1337      /**

1338           * Returns the recent subtotal

1339           *

1340           * @param array $d

1341           * @return float The current order subtotal

1342           */
1343  	function get_order_subtotal( &$d ) {
1344  
1345          if( $this->_subtotal === null ) {
1346              $this->_subtotal = $this->calc_order_subtotal( $d );
1347          }
1348          else {
1349              if( $this->_cartHash != $this->get_new_cart_hash() ) {
1350                  // Need to re-calculate the subtotal

1351                  $this->_subtotal = $this->calc_order_subtotal( $d );
1352              }
1353          }
1354          return $this->_subtotal;
1355      }
1356  
1357      /**************************************************************************

1358      ** name: calc_order_subtotal()

1359      ** created by: gday

1360      ** description:  Calculate the order subtotal for the current order.

1361      **               Does not include tax or shipping charges.

1362      ** parameters: $d

1363      ** returns: sub total for this order

1364      ***************************************************************************/
1365  	function calc_order_subtotal( &$d ) {
1366          global $order_tax_details;
1367          
1368          $order_tax_details = array();
1369          $d['order_subtotal_withtax'] = 0;
1370          $d['payment_discount'] = 0;
1371          $auth = $_SESSION['auth'];
1372          $cart = $_SESSION['cart'];
1373          $order_subtotal = 0;
1374  
1375          require_once (CLASSPATH.'ps_product.php');
1376          $ps_product= new ps_product;
1377  
1378          for($i = 0; $i < $cart["idx"]; $i++) {
1379              $my_taxrate = $ps_product->get_product_taxrate($cart[$i]["product_id"] );
1380              $price = $ps_product->get_adjusted_attribute_price($cart[$i]["product_id"], $cart[$i]["description"]);
1381              $product_price = $product_price_tmp = $GLOBALS['CURRENCY']->convert( $price["product_price"], @$price["product_currency"] );
1382              
1383              if( $auth["show_price_including_tax"] == 1 ) {
1384                  $product_price = round( ($product_price *($my_taxrate+1)), 2 );
1385                  $product_price *= $cart[$i]["quantity"];
1386                  
1387                  $d['order_subtotal_withtax'] += $product_price;
1388                  $product_price = $product_price /($my_taxrate+1);
1389                  $order_subtotal += $product_price;
1390                  
1391              }
1392              else {
1393                  $order_subtotal += $product_price * $cart[$i]["quantity"];
1394                  
1395                  $product_price = round( ($product_price *($my_taxrate+1)), 2 );
1396                  $product_price *= $cart[$i]["quantity"];
1397                  $d['order_subtotal_withtax'] += $product_price;
1398                  $product_price = $product_price /($my_taxrate+1);
1399              }
1400              if( MULTIPLE_TAXRATES_ENABLE ) {
1401                  // Calculate the amounts for each tax rate

1402                  if( !isset( $order_tax_details[$my_taxrate] )) {
1403                      $order_tax_details[$my_taxrate] = 0;
1404                  }
1405                  $order_tax_details[$my_taxrate] += $product_price_tmp*$my_taxrate*$cart[$i]["quantity"];
1406              }
1407          }
1408  
1409          return($order_subtotal);
1410      }
1411  
1412  
1413      /**

1414       * Calculates the taxable order subtotal for the order.

1415       * If an item has no weight, it is non taxable.

1416       * @author Chris Coleman

1417       * @param array $d

1418       * @return float Subtotal

1419       */
1420  	function calc_order_taxable($d) {
1421          $auth = $_SESSION['auth'];
1422          $cart = $_SESSION['cart'];
1423  
1424          $subtotal = 0.0;
1425          
1426          require_once (CLASSPATH.'ps_product.php');
1427          $ps_product= new ps_product;
1428          require_once (CLASSPATH.'ps_shipping_method.php');
1429  
1430          $db = new ps_DB;
1431  
1432          for($i = 0; $i < $cart["idx"]; $i++) {
1433              $price = $ps_product->get_adjusted_attribute_price($cart[$i]["product_id"], $cart[$i]["description"]);
1434              $product_price = $GLOBALS['CURRENCY']->convert( $price["product_price"], $price['product_currency'] );
1435              $item_weight = ps_shipping_method::get_weight($cart[$i]["product_id"]) * $cart[$i]['quantity'];
1436  
1437              if ($item_weight != 0 or TAX_VIRTUAL=='1') {
1438                  $subtotal += $product_price * $cart[$i]["quantity"];
1439              }
1440          }
1441          return($subtotal);
1442      }
1443      
1444      /**

1445       * Calculate the tax charges for the current order.

1446       * You can switch the way, taxes are calculated:

1447       * either based on the VENDOR address,

1448       * or based on the ship-to address.

1449       * ! Creates the global $order_tax_details

1450       *

1451       * @param float $order_taxable

1452       * @param array $d

1453       * @return float

1454       */
1455  	function calc_order_tax($order_taxable, $d) {
1456          global $order_tax_details, $discount_factor;
1457          $total = 0; 
1458          $order_tax=0;
1459          $auth = $_SESSION['auth'];
1460          $ps_vendor_id = $_SESSION["ps_vendor_id"];
1461          $db = new ps_DB;
1462          $ship_to_info_id = vmGet( $_REQUEST, 'ship_to_info_id');
1463          
1464          
1465          require_once (CLASSPATH.'ps_tax.php');
1466          $ps_tax = new ps_tax;
1467          
1468          $discount_factor = 1;
1469          
1470              // Shipping address based TAX

1471          if ( !ps_checkout::tax_based_on_vendor_address () ) {
1472              $q = "SELECT state, country FROM #__{vm}_user_info ";
1473              $q .= "WHERE user_info_id='".$ship_to_info_id. "'";
1474              $db->query($q);
1475              $db->next_record();
1476              $state = $db->f("state");
1477              $country = $db->f("country");
1478              $q = "SELECT * FROM #__{vm}_tax_rate WHERE tax_country='$country' ";
1479              if( !empty($state)) {
1480                  $q .= "AND (tax_state='$state' OR tax_state=' $state ')";
1481              }
1482              $db->query($q);
1483              if ($db->next_record()) {
1484                  $rate = $order_taxable * floatval( $db->f("tax_rate") );
1485                  if (empty($rate)) {
1486                      $order_tax = 0.0;
1487                  } else {
1488                      $cart = $_SESSION['cart'];
1489                      $order_tax = 0.0;
1490                      if( (!empty( $_SESSION['coupon_discount'] ) || !empty( $d['payment_discount'] ))
1491                          && PAYMENT_DISCOUNT_BEFORE == '1' ) {
1492  
1493                          require_once (CLASSPATH.'ps_product.php');
1494                          $ps_product= new ps_product;
1495  
1496                          for($i = 0; $i < $cart["idx"]; $i++) {
1497                              $item_weight = ps_shipping_method::get_weight($cart[$i]["product_id"]) * $cart[$i]['quantity'];
1498  
1499                              if ($item_weight !=0 or TAX_VIRTUAL) {
1500                                  $price = $ps_product->get_adjusted_attribute_price($cart[$i]["product_id"], $cart[$i]["description"]);
1501                                  $price['product_price'] = $GLOBALS['CURRENCY']->convert( $price['product_price'], $price['product_currency']);
1502                                  $tax_rate = $db->f("tax_rate");
1503  
1504                                  $use_coupon_discount= @$_SESSION['coupon_discount'];
1505                                  //if( !empty( $_SESSION['coupon_discount'] )) {

1506                                  //    if( $auth["show_price_including_tax"] == 1 ) {

1507                                  //        $use_coupon_discount = $_SESSION['coupon_discount'] / ($tax_rate+1);

1508                                  //    }

1509                                  //}

1510                                  $factor = (100 * ($use_coupon_discount + @$d['payment_discount'])) / $this->_subtotal;
1511                                  $price["product_price"] = $price["product_price"] - ($factor * $price["product_price"] / 100);
1512                                  @$order_tax_details[$tax_rate] += $price["product_price"] * $tax_rate * $cart[$i]["quantity"];
1513  
1514                                  $order_tax += $price["product_price"] * $tax_rate * $cart[$i]["quantity"];
1515                                  $total += $price["product_price"] * $cart[$i]["quantity"];
1516                              } else {
1517                                  $order_tax += 0.0;
1518                              }
1519                          }
1520                      } else {
1521                          $order_tax = $rate;
1522                      }
1523                  }
1524              } else {
1525                  $order_tax = 0.0;
1526              }
1527              $order_tax_details[$db->f('tax_rate')] = $order_tax;
1528          }
1529          // Store Owner Address based TAX

1530          else {
1531  
1532                  // Calculate the Tax with a tax rate for every product

1533                  $cart = $_SESSION['cart'];
1534                  $order_tax = 0.0;
1535                  $total = 0.0;
1536                  if( (!empty( $_SESSION['coupon_discount'] ) || !empty( $d['payment_discount'] ))
1537                      && PAYMENT_DISCOUNT_BEFORE == '1' ) {
1538                      // We need to recalculate the tax details when the discounts are applied

1539                      // BEFORE taxes - because they affect the product subtotals then

1540                      $order_tax_details = array();
1541                  }
1542                  require_once (CLASSPATH.'ps_product.php');
1543                  $ps_product= new ps_product;
1544                  require_once (CLASSPATH.'ps_shipping_method.php');
1545  
1546                  for($i = 0; $i < $cart["idx"]; $i++) {
1547                      $item_weight = ps_shipping_method::get_weight($cart[$i]["product_id"]) * $cart[$i]['quantity'];
1548  
1549                      if ($item_weight !=0 or TAX_VIRTUAL) {
1550                          $price = $ps_product->get_adjusted_attribute_price($cart[$i]["product_id"], $cart[$i]["description"]);
1551                          $price['product_price'] = $GLOBALS['CURRENCY']->convert( $price['product_price'], $price['product_currency']);
1552                          $tax_rate = $ps_product->get_product_taxrate($cart[$i]["product_id"]);
1553                          
1554                          if( (!empty( $_SESSION['coupon_discount'] ) || !empty( $d['payment_discount'] ))
1555                              && PAYMENT_DISCOUNT_BEFORE == '1' ) {
1556                              $use_coupon_discount= @$_SESSION['coupon_discount'];
1557                              if( !empty( $_SESSION['coupon_discount'] )) {
1558                                  if( $auth["show_price_including_tax"] == 1 ) {
1559                                      $use_coupon_discount = $_SESSION['coupon_discount'] / ($tax_rate+1);
1560                                  }
1561                              }
1562                              $factor = (100 * ($use_coupon_discount + @$d['payment_discount'])) / $this->_subtotal;
1563                              $price["product_price"] = $price["product_price"] - ($factor * $price["product_price"] / 100);
1564                              @$order_tax_details[$tax_rate] += $price["product_price"] * $tax_rate * $cart[$i]["quantity"];
1565                          }
1566                          
1567                          $order_tax += $price["product_price"] * $tax_rate * $cart[$i]["quantity"];
1568                          $total += $price["product_price"] * $cart[$i]["quantity"];
1569                      }
1570                  }
1571  
1572                  if( (!empty( $_SESSION['coupon_discount'] ) || !empty( $d['payment_discount'] ))
1573                      && PAYMENT_DISCOUNT_BEFORE != '1' ) {
1574                          
1575                      // Here we need to re-calculate the Discount

1576                      // because we assume the Discount is "including Tax"

1577                      $discounted_total = @$d['order_subtotal_withtax'] - @$_SESSION['coupon_discount'] - @$d['payment_discount'];
1578                      
1579                      if( $discounted_total != @$d['order_subtotal_withtax'] && @$d['order_subtotal_withtax'] > 0.00) {
1580                          $discount_factor = $discounted_total / $d['order_subtotal_withtax'];
1581                          
1582                          foreach( $order_tax_details as $rate => $value ) {
1583                              $order_tax_details[$rate] = $value * $discount_factor;
1584                          }
1585                      }
1586                      
1587                  }
1588                  if( is_object($this->_SHIPPING) ) {
1589                      $taxrate = $this->_SHIPPING->get_tax_rate();
1590                      if( $taxrate ) {
1591                          $rate = $this->_SHIPPING->get_rate( $d );
1592                          if( $auth["show_price_including_tax"] == 1 ) {
1593                              @$order_tax_details[$taxrate] += $rate - ($rate / ($taxrate+1));
1594                          }
1595                          else {
1596                              @$order_tax_details[$taxrate] += $rate * $taxrate;
1597                          }
1598                      }
1599                  }
1600  
1601  
1602          }
1603          return( round( $order_tax, 2 ) );
1604      }
1605    
1606      /**************************************************************************

1607      ** name: calc_order_shipping()

1608      ** created by: soeren

1609      ** description:  Get the Shipping costs WITHOUT TAX

1610      ** parameters: $d,

1611      ** returns: a decimal number, excluding taxes

1612      ***************************************************************************/
1613  	function calc_order_shipping( &$d ) {
1614  
1615          $auth = $_SESSION['auth'];
1616  
1617          $shipping_total = $this->_SHIPPING->get_rate( $d );
1618          $shipping_taxrate = $this->_SHIPPING->get_tax_rate();
1619  
1620          // When the Shipping rate is shown including Tax

1621          // we have to extract the Tax from the Shipping Total

1622          // before returning the value

1623          if( $auth["show_price_including_tax"] == 1 ) {
1624              $d['shipping_tax'] = $shipping_total - ($shipping_total / ($shipping_taxrate+1));
1625              $d['shipping_total'] = $shipping_total - $d['shipping_tax'];
1626          }
1627          else {
1628              $d['shipping_tax'] = $shipping_total * $shipping_taxrate;
1629              $d['shipping_total'] = $shipping_total;
1630          }
1631          $d['shipping_tax'] = $GLOBALS['CURRENCY']->convert( $d['shipping_tax'] );
1632          $d['shipping_total'] = $GLOBALS['CURRENCY']->convert( $d['shipping_total'] );
1633          
1634          return $d['shipping_total'];
1635      }
1636  
1637  
1638  
1639  
1640      /**************************************************************************

1641      ** name: calc_order_shipping_tax()

1642      ** created by: Soeren

1643      ** description:  Calculate the tax for the shipping of the current order

1644      ** Assumes that the function calc_order_shipping has been called before

1645      ** parameters: $d

1646      ** returns: Tax for the shipping of this order

1647      ***************************************************************************/
1648  	function calc_order_shipping_tax($d) {
1649  
1650          return $d['shipping_tax'];
1651  
1652      }
1653  
1654      /**************************************************************************

1655      ** name: get_vendor_currency()

1656      ** created by: gday

1657      ** description:  Get the currency type used by the $vendor_id

1658      ** parameters: $vendor_id - vendor id to return currency type

1659      ** returns: Currency type for this vendor

1660      ***************************************************************************/
1661  	function get_vendor_currency($vendor_id) {
1662          $db = new ps_DB;
1663  
1664          $q = "SELECT vendor_currency FROM #__{vm}_vendor WHERE vendor_id='$vendor_id'";
1665  
1666          $db->query($q);
1667          $db->next_record();
1668  
1669          $currency = $db->f("vendor_currency");
1670  
1671          return($currency);
1672      }
1673  
1674  
1675      /**************************************************************************

1676      ** name: get_payment_discount()

1677      ** created by: soeren

1678      ** description:  Get the discount for the selected payment

1679      ** parameters: $payment_method_id

1680      ** returns: Discount as a decimal if found

1681      **          0 if nothing is found

1682      ***************************************************************************/
1683  	function get_payment_discount( $payment_method_id, $subtotal = '' ) {
1684          
1685          if( empty( $payment_method_id )) {
1686              return 0;
1687          }
1688          $db = new ps_DB();
1689          //MOD ei

1690          // There is a special payment method, which fee is depend on subtotal

1691          // it is a type of cash on delivery

1692          // comment soeren: Payment methods can implement their own method

1693          // how to calculate the discount: the function "get_payment_rate"

1694          // should return a float value from the payment class

1695          require_once (CLASSPATH.'ps_payment_method.php');
1696          $ps_payment_method = new ps_payment_method;
1697  
1698          $payment_class = $ps_payment_method->get_field($payment_method_id, "payment_class");
1699  
1700          // Check to see if Payment Class File exists

1701          if (file_exists(CLASSPATH . "payment/$payment_class.php") ) {
1702  
1703              require_once( CLASSPATH. "payment/$payment_class.php" );
1704              eval( "\$_PAYMENT = new $payment_class();" );
1705  
1706              if(is_callable(array($payment_class, 'get_payment_rate'))) {
1707                  return $_PAYMENT->get_payment_rate($subtotal);
1708              }
1709          }
1710          //End of MOD ei

1711  
1712          // If a payment method has no special way of calculating a discount,

1713          // let's do this on our own from the payment_method_discount settings

1714          $q = 'SELECT `payment_method_discount`,`payment_method_discount_is_percent`,`payment_method_discount_max_amount`, `payment_method_discount_min_amount`
1715                                  FROM `#__{vm}_payment_method` WHERE payment_method_id='.$payment_method_id;
1716          $db->query($q);$db->next_record();
1717  
1718          $discount = $db->f('payment_method_discount');
1719          $is_percent = $db->f('payment_method_discount_is_percent');
1720  
1721          if( !$is_percent ) {
1722              // Standard method: absolute amount

1723              if (!empty($discount)) {
1724                  return(floatval( $GLOBALS['CURRENCY']->convert($discount)));
1725              }
1726              else {
1727                  return(0);
1728              }
1729          }
1730          else {
1731  
1732              if( $subtotal === '') {
1733                  $subtotal = $this->get_order_subtotal( $vars );
1734              }
1735  
1736              // New: percentage of the subtotal, limited by minimum and maximum

1737              $max = $db->f('payment_method_discount_max_amount');
1738              $min = $db->f('payment_method_discount_min_amount');
1739              $value = (float) ($discount/100) * $subtotal;
1740  
1741              if( abs($value) > $max && $max > 0 ) {
1742                  $value = -$max;
1743              }
1744              elseif( abs($value) < $min && $min > 0 ) {
1745                  $value = -$min;
1746              }
1747              return $value;
1748          }
1749  
1750      }
1751  
1752      /**

1753      * Create a receipt for the current order and email it to

1754      * the customer and the vendor.

1755      * @author gday

1756      * @author soeren

1757      * @param int $order_id

1758      * @return boolean True on success, false on failure

1759      */
1760  	function email_receipt($order_id) {
1761          global $sess, $ps_product, $VM_LANG, $CURRENCY_DISPLAY, $vmLogger,
1762          $mosConfig_fromname, $mosConfig_lang, $database;
1763  
1764          $ps_vendor_id = vmGet( $_SESSION, 'ps_vendor_id', 1 );
1765          $auth = $_SESSION["auth"];
1766  
1767          require_once ( CLASSPATH.'ps_order_status.php');
1768          require_once ( CLASSPATH.'ps_userfield.php');
1769          require_once (CLASSPATH.'ps_product.php');
1770          $ps_product = new ps_product;
1771  
1772          // Connect to database and gather appropriate order information

1773          $db = new ps_DB;
1774          $q  = "SELECT * FROM #__{vm}_orders WHERE order_id='$order_id'";
1775          $db->query($q);
1776          $db->next_record();
1777          $user_id = $db->f("user_id");
1778          $customer_note = $db->f("customer_note");
1779          $order_status = ps_order_status::getOrderStatusName($db->f("order_status") );
1780  
1781          $dbbt = new ps_DB;
1782          $dbst = new ps_DB;
1783  
1784          $qt = "SELECT * FROM #__{vm}_user_info WHERE user_id='".$user_id."' AND address_type='BT'";
1785          $dbbt->query($qt);
1786          $dbbt->next_record();
1787  
1788          $qt = "SELECT * FROM #__{vm}_user_info WHERE user_info_id='". $db->f("user_info_id") . "'";
1789          $dbst->query($qt);
1790          $dbst->next_record();
1791  
1792          $dbv = new ps_DB;
1793          $qt = "SELECT * from #__{vm}_vendor ";
1794          /* Need to decide on vendor_id <=> order relationship */

1795          $qt .= "WHERE vendor_id = '".$ps_vendor_id."'";
1796          $dbv->query($qt);
1797          $dbv->next_record();
1798  
1799          $dboi = new ps_DB;
1800          $q_oi = "SELECT * FROM #__{vm}_product, #__{vm}_order_item, #__{vm}_orders ";
1801          $q_oi .= "WHERE #__{vm}_product.product_id=#__{vm}_order_item.product_id ";
1802          $q_oi .= "AND #__{vm}_order_item.order_id='$order_id' ";
1803          $q_oi .= "AND #__{vm}_orders.order_id=#__{vm}_order_item.order_id";
1804          $dboi->query($q_oi);
1805  
1806          $db_payment = new ps_DB;
1807          $q  = "SELECT op.payment_method_id, pm.payment_method_name FROM #__{vm}_order_payment as op, #__{vm}_payment_method as pm
1808                WHERE order_id='$order_id' AND op.payment_method_id=pm.payment_method_id";
1809          $db_payment->query($q);
1810          $db_payment->next_record();
1811  
1812          if ($auth["show_price_including_tax"] == 1) {
1813  
1814              $order_shipping = $db->f("order_shipping");
1815              $order_shipping += $db->f("order_shipping_tax");
1816              $order_shipping_tax = 0;
1817              $order_tax = $db->f("order_tax") + $db->f("order_shipping_tax");
1818          }
1819          else {
1820  
1821              $order_shipping = $db->f("order_shipping");
1822              $order_shipping_tax = $db->f("order_shipping_tax");
1823              $order_tax = $db->f("order_tax");
1824          }
1825          $order_total = $db->f("order_total");
1826          $order_discount = $db->f("order_discount");
1827          $coupon_discount = $db->f("coupon_discount");
1828  
1829          // Email Addresses for shopper and vendor

1830          // **************************************

1831          $shopper_email = $dbbt->f("user_email");
1832          $shopper_name = $dbbt->f("first_name")." ".$dbbt->f("last_name");
1833  
1834          $from_email = $dbv->f("contact_email");
1835  
1836          $shopper_subject = $dbv->f("vendor_name") . " ".$VM_LANG->_('PHPSHOP_ORDER_PRINT_PO_LBL',false)." - " . $db->f("order_id");
1837          $vendor_subject = $dbv->f("vendor_name") . " ".$VM_LANG->_('PHPSHOP_ORDER_PRINT_PO_LBL',false)." - " . $db->f("order_id");
1838  
1839          $shopper_order_link = $sess->url( SECUREURL ."index.php?page=account.order_details&order_id=$order_id", true, false );
1840          $vendor_order_link = $sess->url( SECUREURL ."index2.php?page=order.order_print&order_id=$order_id&pshop_mode=admin", true, false );
1841  
1842          /**

1843           * Prepare the payment information, including Credit Card information when not empty

1844           */
1845          $payment_info_details = $db_payment->f("payment_method_name");
1846          if( !empty( $_SESSION['ccdata']['order_payment_name'] )
1847              && !empty($_SESSION['ccdata']['order_payment_number'])) {
1848                $payment_info_details .= '<br />'.$VM_LANG->_('PHPSHOP_CHECKOUT_CONF_PAYINFO_NAMECARD',false).': '.$_SESSION['ccdata']['order_payment_name'].'<br />';
1849                $payment_info_details .= $VM_LANG->_('PHPSHOP_CHECKOUT_CONF_PAYINFO_CCNUM',false).': '.$this->asterisk_pad($_SESSION['ccdata']['order_payment_number'], 4 ).'<br />';
1850                $payment_info_details .= $VM_LANG->_('PHPSHOP_CHECKOUT_CONF_PAYINFO_EXDATE',false).': '.$_SESSION['ccdata']['order_payment_expire_month'].' / '.$_SESSION['ccdata']['order_payment_expire_year'].'<br />';
1851                if( !empty($_SESSION['ccdata']['credit_card_code'])) {
1852                    $payment_info_details .= 'CVV code: '.$_SESSION['ccdata']['credit_card_code'].'<br />';
1853                }
1854          }
1855          // Convert HTML into Text

1856          $payment_info_details_text = str_replace( '<br />', "\n", $payment_info_details );
1857          
1858          // Get the Shipping Details

1859          $shipping_arr = explode("|", urldecode(vmGet($_REQUEST,"shipping_rate_id")) );
1860          
1861          // Headers and Footers

1862          // ******************************

1863          // Shopper Header

1864          $shopper_header = $VM_LANG->_('PHPSHOP_CHECKOUT_EMAIL_SHOPPER_HEADER1',false)."\n";
1865          
1866          $legal_info_title = '';
1867          $legal_info_html = '';
1868          // Get the legal information about the returns/order cancellation policy

1869          if( @VM_ONCHECKOUT_SHOW_LEGALINFO == '1' ) {
1870              $article = intval(@VM_ONCHECKOUT_LEGALINFO_LINK);
1871              if( $article > 0 ) {
1872                  $db_legal = new ps_DB();
1873                  // Get the content article, which contains the Legal Info

1874                  $db_legal->query( 'SELECT id, title, introtext FROM #__content WHERE id='.$article );
1875                  $db_legal->next_record();
1876                  if( $db_legal->f('introtext') ) {
1877                      $legal_info_title = $db_legal->f('title');
1878                      $legal_info_text = strip_tags( str_replace( '<br />', "\n", $db_legal->f('introtext') ));
1879                      $legal_info_html = $db_legal->f('introtext');
1880                  }
1881              }
1882          }
1883          //Shopper Footer

1884          $shopper_footer = "\n\n".$VM_LANG->_('PHPSHOP_CHECKOUT_EMAIL_SHOPPER_HEADER2',false)."\n";
1885          if( VM_REGISTRATION_TYPE != 'NO_REGISTRATION' ) {
1886              $shopper_footer .= "\n\n".$VM_LANG->_('PHPSHOP_CHECKOUT_EMAIL_SHOPPER_HEADER5',false)."\n";
1887              $shopper_footer .= $shopper_order_link;
1888          }
1889          $shopper_footer .= "\n\n".$VM_LANG->_('PHPSHOP_CHECKOUT_EMAIL_SHOPPER_HEADER3',false)."\n";
1890          $shopper_footer .= "Email: " . $from_email;
1891          // New in version 1.0.5

1892          if( @VM_ONCHECKOUT_SHOW_LEGALINFO == '1' && !empty( $legal_info_title )) {
1893              $shopper_footer .= "\n\n____________________________________________\n";
1894              $shopper_footer .= $legal_info_title."\n";
1895              $shopper_footer .= $legal_info_text."\n";
1896          }
1897          
1898          // Vendor Header

1899          $vendor_header = $VM_LANG->_('PHPSHOP_CHECKOUT_EMAIL_SHOPPER_HEADER4',false)."\n";
1900  
1901          // Vendor Footer

1902          $vendor_footer = "\n\n".$VM_LANG->_('PHPSHOP_CHECKOUT_EMAIL_SHOPPER_HEADER5',false)."\n";
1903          $vendor_footer .= $vendor_order_link;
1904  
1905          $vendor_email = $from_email;
1906  
1907          /////////////////////////////////////

1908          // set up text mail

1909          //

1910  
1911          // Main Email Message Purchase Order

1912          // *********************************

1913          $shopper_message  = "\n".$VM_LANG->_('PHPSHOP_ORDER_PRINT_PO_LBL',false)."\n";
1914          $shopper_message .= "------------------------------------------------------------------------\n";
1915          $shopper_message .= $VM_LANG->_('PHPSHOP_ORDER_PRINT_PO_NUMBER',false).": " . $db->f("order_id") . "\n";
1916          $shopper_message .= $VM_LANG->_('PHPSHOP_ORDER_PRINT_PO_DATE',false).":   ";
1917          $shopper_message .= strftime( $VM_LANG->_('DATE_FORMAT_LC'), $db->f("cdate") ) . "\n";
1918          $shopper_message .= $VM_LANG->_('PHPSHOP_ORDER_PRINT_PO_STATUS',false).": ";
1919                  
1920          $shopper_message .= $order_status."\n\n";
1921                  
1922          // BillTo Fields        

1923          $registrationfields = ps_userfield::getUserFields('registration', false, '', false, true );
1924          foreach( $registrationfields as $field ) {
1925              if( $field->name == 'email') $field->name = 'user_email';
1926              if( $field->name == 'delimiter_sendregistration' || $field->type == 'captcha') continue;
1927              
1928              if( $field->type == 'delimiter') {
1929                  $shopper_message .= ($VM_LANG->_($field->title) != '' ? $VM_LANG->_($field->title) : $field->title)."\n";
1930                  $shopper_message .= "--------------------\n\n";
1931              } else {
1932                  $shopper_message .= ($VM_LANG->_($field->title) != '' ? $VM_LANG->_($field->title) : $field->title).':    ';
1933                  $shopper_message .= $dbbt->f($field->name) . "\n";
1934              }
1935          }
1936          
1937          // Shipping Fields

1938          $shopper_message .= "\n\n";
1939          $shopper_message .= $VM_LANG->_('PHPSHOP_ORDER_PRINT_SHIP_TO_LBL')."\n";
1940          $shopper_message .= "-------\n\n";
1941          
1942          $shippingfields = ps_userfield::getUserFields('shipping', false, '', false, true );
1943          foreach( $shippingfields as $field ) {            
1944              
1945              if( $field->type == 'delimiter') {
1946                  $shopper_message .= ($VM_LANG->_($field->title) != '' ? $VM_LANG->_($field->title) : $field->title)."\n";
1947                  $shopper_message .= "--------------------\n\n";
1948              } else {
1949                  $shopper_message .= ($VM_LANG->_($field->title) != '' ? $VM_LANG->_($field->title) : $field->title).':    ';
1950                  $shopper_message .= $dbst->f($field->name) . "\n";
1951              }
1952          }
1953          
1954          $shopper_message .= "\n\n";
1955  
1956          $shopper_message .= $VM_LANG->_('PHPSHOP_ORDER_PRINT_ITEMS_LBL',false)."\n";
1957          $shopper_message .= "-----------";
1958          $sub_total = 0.00;
1959          while($dboi->next_record()) {
1960              $shopper_message .= "\n\n";
1961              $shopper_message .= $VM_LANG->_('PHPSHOP_PRODUCT',false)."  = ";
1962              if ($dboi->f("product_parent_id")) {
1963                  $shopper_message .= $dboi->f("order_item_name") . "\n";
1964                  $shopper_message .= "SERVICE  = ";
1965              }
1966              $shopper_message .= $dboi->f("product_name") . "; ".$dboi->f("product_attribute") ."\n";
1967              $shopper_message .= $VM_LANG->_('PHPSHOP_ORDER_PRINT_QUANTITY',false)." = ";
1968              $shopper_message .= $dboi->f("product_quantity") . "\n";
1969              $shopper_message .= $VM_LANG->_('PHPSHOP_ORDER_PRINT_SKU',false)."      = ";
1970              $shopper_message .= $dboi->f("order_item_sku") . "\n";
1971  
1972              $shopper_message .= $VM_LANG->_('PHPSHOP_ORDER_PRINT_PRICE',false)."    = ";
1973              if ($auth["show_price_including_tax"] == 1) {
1974                  $sub_total += ($dboi->f("product_quantity") * $dboi->f("product_final_price"));
1975                  $shopper_message .= $CURRENCY_DISPLAY->getFullValue($dboi->f("product_final_price"), '', $db->f('order_currency'));
1976              } else {
1977                  $sub_total += ($dboi->f("product_quantity") * $dboi->f("product_final_price"));
1978                  $shopper_message .= $CURRENCY_DISPLAY->getFullValue($dboi->f("product_item_price"), '', $db->f('order_currency'));
1979              }
1980          }
1981  
1982          $shopper_message .= "\n\n";
1983  
1984          $shopper_message .= $VM_LANG->_('PHPSHOP_ORDER_PRINT_SUBTOTAL',false)." = ";
1985          $shopper_message .= $CURRENCY_DISPLAY->getFullValue($sub_total, '', $db->f('order_currency'))."\n";
1986  
1987          if ( PAYMENT_DISCOUNT_BEFORE == '1') {
1988              if( !empty($order_discount)) {
1989                  if ($order_discount > 0) {
1990                      $shopper_message .= $VM_LANG->_('PHPSHOP_PAYMENT_METHOD_LIST_DISCOUNT',false)." = ";
1991                      $shopper_message .= "- ".$CURRENCY_DISPLAY->getFullValue(abs($order_discount), '', $db->f('order_currency')) . "\n";
1992                  } else {
1993                      $shopper_message .= $VM_LANG->_('PHPSHOP_FEE',false)." = ";
1994                      $shopper_message .= "+ ".$CURRENCY_DISPLAY->getFullValue(abs($order_discount), '', $db->f('order_currency')) . "\n";
1995                  }
1996              }
1997              if( !empty($coupon_discount)) {
1998                  /* following 2 lines added by Erich for coupon hack */

1999                  $shopper_message .= $VM_LANG->_('PHPSHOP_COUPON_DISCOUNT',false) . ": ";
2000                  $shopper_message .= $CURRENCY_DISPLAY->getFullValue($coupon_discount, '', $db->f('order_currency')) . "\n";
2001              }
2002          }
2003  
2004          if ($auth["show_price_including_tax"] != 1) {
2005              $shopper_message .= $VM_LANG->_('PHPSHOP_ORDER_PRINT_TOTAL_TAX',false)."      = ";
2006              $shopper_message .= $CURRENCY_DISPLAY->getFullValue($order_tax, '', $db->f('order_currency')) . "\n";
2007          }
2008          $shopper_message .= $VM_LANG->_('PHPSHOP_ORDER_PRINT_SHIPPING',false)." = ";
2009          $shopper_message .= $CURRENCY_DISPLAY->getFullValue($order_shipping, '', $db->f('order_currency')) . "\n";
2010          if( !empty($order_shipping_tax)) {
2011              $shopper_message .= $VM_LANG->_('PHPSHOP_ORDER_PRINT_SHIPPING_TAX',false)."   = ";
2012              $shopper_message .= $CURRENCY_DISPLAY->getFullValue($order_shipping_tax, '', $db->f('order_currency'));
2013          }
2014          $shopper_message .= "\n\n";
2015          if ( PAYMENT_DISCOUNT_BEFORE != '1') {
2016              if( !empty($order_discount)) {
2017                  if ($order_discount > 0) {
2018                      $shopper_message .= $VM_LANG->_('PHPSHOP_PAYMENT_METHOD_LIST_DISCOUNT',false)." = ";
2019                      $shopper_message .= "- ".$CURRENCY_DISPLAY->getFullValue(abs($order_discount), '', $db->f('order_currency')) . "\n";
2020                  } else {
2021                      $shopper_message .= $VM_LANG->_('PHPSHOP_FEE',false)." = ";
2022                      $shopper_message .= "+ ".$CURRENCY_DISPLAY->getFullValue(abs($order_discount), '', $db->f('order_currency')) . "\n";
2023                  }
2024              }
2025              if( !empty($coupon_discount)) {
2026                  /* following 2 lines added by Erich for coupon hack */

2027                  $shopper_message .= $VM_LANG->_('PHPSHOP_COUPON_DISCOUNT',false) . ": ";
2028                  $shopper_message .= $CURRENCY_DISPLAY->getFullValue($coupon_discount, '', $db->f('order_currency')) . "\n";
2029              }
2030          }
2031          $shopper_message .= $VM_LANG->_('PHPSHOP_ORDER_PRINT_TOTAL',false)."    = ";
2032          $shopper_message .= $CURRENCY_DISPLAY->getFullValue($order_total, '', $db->f('order_currency'));
2033  
2034          if ($auth["show_price_including_tax"] == 1) {
2035              $shopper_message .= "\n---------------";
2036              $shopper_message .= "\n";
2037              $shopper_message .= $VM_LANG->_('PHPSHOP_ORDER_PRINT_TOTAL_TAX',false)."      = ";
2038              $shopper_message .= $CURRENCY_DISPLAY->getFullValue($order_tax, '', $db->f('order_currency')) . "\n";
2039          }
2040          if( $db->f('order_tax_details') ) {
2041              $shopper_message .= str_replace( '<br />', "\n", ps_checkout::show_tax_details( $db->f('order_tax_details'), $db->f('order_currency') ));
2042          }
2043          // Payment Details

2044          $shopper_message .= "\n\n------------------------------------------------------------------------\n";
2045          $shopper_message .= $payment_info_details_text;
2046          
2047          // Shipping Details

2048          if( is_object($this->_SHIPPING) ) {
2049              $shopper_message .= "\n\n------------------------------------------------------------------------\n";
2050              $shopper_message .= $VM_LANG->_('PHPSHOP_ORDER_PRINT_SHIPPING_LBL',false).":\n";
2051              $shopper_message .= $shipping_arr[1]." (".$shipping_arr[2].")";
2052          }
2053          // Customer Note

2054          $shopper_message .= "\n\n------------------------------------------------------------------------\n";
2055          $shopper_message .= "\n".$VM_LANG->_('PHPSHOP_ORDER_PRINT_CUSTOMER_NOTE',false)."\n";
2056          $shopper_message .= "---------------";
2057          $shopper_message .= "\n";
2058          if( !empty( $customer_note )) {
2059              $shopper_message .= $customer_note."\n";
2060          }
2061          else {
2062              $shopper_message .= " ./. \n";
2063          }
2064          $shopper_message .= "------------------------------------------------------------------------\n";
2065          
2066          // Decode things like &euro; => €

2067          $shopper_message = vmHtmlEntityDecode( $shopper_message );
2068          
2069          // End of Purchase Order

2070          // *********************

2071  
2072          //

2073          //END: set up text mail

2074          /////////////////////////////////////

2075          // Send text email

2076          //

2077          if (ORDER_MAIL_HTML == '0') {
2078  
2079              $msg = $shopper_header . $shopper_message . $shopper_footer;
2080  
2081              // Mail receipt to the shopper

2082              vmMail( $from_email, $mosConfig_fromname, $shopper_email, $shopper_subject, $msg, "" );
2083  
2084              $msg = $vendor_header . $shopper_message . $vendor_footer;
2085  
2086              // Mail receipt to the vendor

2087              vmMail($from_email, $mosConfig_fromname, $vendor_email, $vendor_subject,    $msg, "" );
2088  
2089          }
2090  
2091          ////////////////////////////

2092          // set up the HTML email

2093          //

2094          elseif (ORDER_MAIL_HTML == '1') {
2095  
2096              $dboi->query($q_oi);
2097  
2098              // Create Template Object 

2099              $template = vmTemplate::getInstance();
2100              
2101              if ($order_discount > 0) {
2102                  $order_discount_lbl = $VM_LANG->_('PHPSHOP_PAYMENT_METHOD_LIST_DISCOUNT');
2103                  $order_discount_plusminus = '-';
2104              } else {
2105                  $order_discount_lbl = $VM_LANG->_('PHPSHOP_FEE');
2106                  $order_discount_plusminus = '+';
2107              }
2108              if ($coupon_discount > 0) {
2109                  $coupon_discount_lbl = $VM_LANG->_('PHPSHOP_PAYMENT_METHOD_LIST_DISCOUNT');
2110                  $coupon_discount_plusminus = '-';
2111              } else {
2112                  $coupon_discount_lbl = $VM_LANG->_('PHPSHOP_FEE');
2113                  $coupon_discount_plusminus = '+';
2114              }
2115  
2116              if( is_object($this->_SHIPPING) ) {
2117                  $shipping_info_details = stripslashes($shipping_arr[1])." (".stripslashes($shipping_arr[2]).")";
2118              }
2119              else {
2120                  $shipping_info_details = ' ./. ';
2121              }
2122              // These are a lot of vars to import for the email confirmation

2123              $template->set_vars(array(
2124                                                          'is_email_to_shopper' => true,
2125                                                          'db' => $db,
2126                                                          'dboi' => $dboi,
2127                                                          'dbbt' => $dbbt,
2128                                                          'dbst' => $dbst,
2129                                                          'ps_product' => $ps_product,
2130                                                          'shippingfields' => $shippingfields,
2131                                                          'registrationfields' => $registrationfields,
2132                                                          'order_id' => $order_id,
2133                                                          'order_discount' => $order_discount,
2134                                                          'order_discount_lbl' => $order_discount_lbl,
2135                                                          'order_discount_plusminus' => $order_discount_plusminus,            
2136                                                          'coupon_discount' => $coupon_discount,
2137                                                          'coupon_discount_lbl' => $coupon_discount_lbl,
2138                                                          'coupon_discount_plusminus' => $coupon_discount_plusminus,
2139                                                          'order_date' => $VM_LANG->convert( vmFormatDate($db->f("cdate"), $VM_LANG->_('DATE_FORMAT_LC') )),
2140                                                          'order_status' => $order_status,
2141                                                          'legal_info_title' => $legal_info_title,
2142                                                          'legal_info_html' => $legal_info_html,
2143                                                          'order_link' => $shopper_order_link,
2144              
2145                                                          'payment_info_lbl' => $VM_LANG->_('PHPSHOP_ORDER_PRINT_PAYINFO_LBL'),
2146                                                          'payment_info_details' => $payment_info_details,
2147                                                          'shipping_info_lbl' => $VM_LANG->_('PHPSHOP_ORDER_PRINT_SHIPPING_LBL'),
2148                                                          'shipping_info_details' => $shipping_info_details,
2149              
2150                                                          'from_email' => $from_email,
2151                                                          'customer_note' => nl2br($customer_note),
2152                                                          'order_header_msg' => $shopper_header,
2153              
2154                                                          'order_subtotal' => $CURRENCY_DISPLAY->getFullValue($sub_total, '', $db->f('order_currency')),
2155                                                          'order_shipping' => $CURRENCY_DISPLAY->getFullValue($order_shipping, '', $db->f('order_currency')),
2156                                                          'order_tax' => $CURRENCY_DISPLAY->getFullValue($order_tax, '', $db->f('order_currency')). ps_checkout::show_tax_details( $db->f('order_tax_details'), $db->f('order_currency') ),
2157                                                          'order_total' => $CURRENCY_DISPLAY->getFullValue($order_total, '', $db->f('order_currency')),
2158              
2159                                              ));
2160              $shopper_html = $template->fetch('order_emails/confirmation_email.tpl.php');
2161              
2162              // Reset the list of order items for use in the vendor email

2163              $dboi->reset();
2164              
2165              // Override some vars for the vendor email, so we can use the same template

2166              $template->set_vars(array(
2167                                                          'order_header_msg' => $vendor_header,
2168                                                          'order_link' => $vendor_order_link,
2169                                                          'is_email_to_shopper' => false
2170                                              ));
2171                                              
2172              $vendor_html = $template->fetch('order_emails/confirmation_email.tpl.php');
2173  
2174  
2175              /*

2176              * Add the text, html and embedded images.

2177              * The name of the image should match exactly

2178              * (case-sensitive) to the name in the html.

2179              */
2180              $shopper_mail_Body = $shopper_html;
2181              $shopper_mail_AltBody = $shopper_header . $shopper_message . $shopper_footer;
2182  
2183              $vendor_mail_Body = $vendor_html;
2184              $vendor_mail_AltBody = $vendor_header . $shopper_message . $vendor_footer;
2185  
2186              $imagefile = pathinfo($dbv->f("vendor_full_image"));
2187              $extension = $imagefile['extension'] == "jpg" ? "jpeg" : "jpeg";
2188  
2189              $EmbeddedImages[] = array(    'path' => IMAGEPATH."vendor/".$dbv->f("vendor_full_image"),
2190                                  'name' => "vendor_image", 
2191                                  'filename' => $dbv->f("vendor_full_image"),
2192                                  'encoding' => "base64",
2193                                  'mimetype' => "image/".$extension );
2194  
2195              
2196              $shopper_mail = vmMail( $from_email, $mosConfig_fromname, $shopper_email, $shopper_subject, $shopper_mail_Body, $shopper_mail_AltBody, true, null, null, $EmbeddedImages);
2197  
2198              $vendor_mail = vmMail( $from_email, $mosConfig_fromname, $vendor_email, $vendor_subject, $vendor_mail_Body, $vendor_mail_AltBody, true, null, null, $EmbeddedImages, null, $shopper_email);
2199  
2200              if ( !$shopper_mail || !$vendor_mail ) {
2201                  
2202                  $vmLogger->debug( 'Something went wrong while sending the order confirmation email to '.$from_email.' and '.$shopper_email );
2203                  return false;
2204              }
2205              //

2206              // END: set up and send the HTML email

2207              ////////////////////////////////////////

2208          }
2209  
2210          return true;
2211  
2212      } // end of function email_receipt()

2213  
2214  
2215  
2216      /**

2217       * Return $str with all but $display_length at the end as asterisks.

2218       * @author gday

2219       *

2220       * @param string $str The string to mask

2221       * @param int $display_length The length at the end of the string that is NOT masked

2222       * @param boolean $reversed When true, masks the end. Masks from the beginning at default

2223       * @return string The string masked by asteriks

2224       */
2225  	function asterisk_pad($str, $display_length, $reversed = false) {
2226  
2227          $total_length = strlen($str);
2228  
2229          if($total_length > $display_length) {
2230              if( !$reversed) {
2231                  for($i = 0; $i < $total_length - $display_length; $i++) {
2232                      $str[$i] = "*";
2233                  }
2234              }
2235              else {
2236                  for($i = $total_length-1; $i >= $total_length - $display_length; $i--) {
2237                      $str[$i] = "*";
2238                  }
2239              }
2240          }
2241  
2242          return($str);
2243      }
2244  
2245      /**

2246       * Displays the order_tax_details array when it contains

2247       * more than one 

2248       * @param mixed $details

2249       * @return string

2250       */
2251  	function show_tax_details( $details, $currency = ''  ) {
2252          global $discount_factor, $CURRENCY_DISPLAY, $VM_LANG;
2253          
2254          if( !isset( $discount_factor) || !empty($_REQUEST['discount_factor'])) {
2255              $discount_factor = 1;
2256          }
2257          $auth = $_SESSION['auth'];
2258          if( !is_array( $details )) {
2259              $details = @unserialize( $details );
2260              if( !is_array($details)) {
2261                  return false;
2262              }
2263          }
2264          $html_rate = '';
2265          $html = '';
2266          if( sizeof( $details) > 1 ) {
2267              foreach ($details as $rate => $value ) {
2268                  if( !$auth['show_price_including_tax']) {
2269                      $value /= $discount_factor;
2270                  }
2271                  if ( !empty($value) ){
2272                  $rate = str_replace( '-', $CURRENCY_DISPLAY->decimal, $rate )*100;
2273                  $html_rate .= $CURRENCY_DISPLAY->getFullValue( $value, 5, $currency ).' ('.$rate.'% '.$VM_LANG->_('PHPSHOP_CART_TAX').')<br />';
2274                  }
2275              }
2276              if ( !empty( $html_rate )){
2277                  $html = '<br />'.$VM_LANG->_('VM_TAXDETAILS_LABEL').':<br />'.$html_rate ;
2278              }
2279          }
2280          return $html;
2281      }
2282      
2283      /*

2284      * @abstract This function is very useful to round totals with definite decimals.

2285      *

2286      * @param float   $value

2287      * @param integer $dec

2288      * @return float

2289      */
2290  	function approx( $value, $dec = 2 ) {
2291          $value += 0.0;
2292          $unit  = floor( $value * pow( 10, $dec + 1 ) ) / 10;
2293          $round = round( $unit );
2294          return $round / pow( 10, $dec );
2295      }
2296  
2297  
2298  
2299      /**

2300       * If the customer is in the EU then tax should be charged according to the

2301       *  vendor's address, and this function will return true.

2302       */
2303  	function tax_based_on_vendor_address ($ship_to_info_id = '') {
2304          global $__tax_based_on_vendor_address;
2305          global $vmLogger;
2306      
2307          if (!isset ($__tax_based_on_vendor_address)) {
2308              $__tax_based_on_vendor_address = ps_checkout::_tax_based_on_vendor_address ($ship_to_info_id);
2309              if ($__tax_based_on_vendor_address)
2310                  $vmLogger->debug ('calculating tax based on vendor address');
2311              else
2312                  $vmLogger->debug ('calculating tax based on shipping address');
2313          }
2314          return $__tax_based_on_vendor_address;
2315      }
2316      
2317  	function _tax_based_on_vendor_address ($ship_to_info_id = '') {
2318          global $auth;
2319          global $vmLogger;
2320      
2321          switch (TAX_MODE) {
2322          case '0':
2323              return false;
2324      
2325          case '1':
2326              return true;
2327      
2328          case '17749':
2329  
2330              $ship_to_info_id = !empty($ship_to_info_id)? $ship_to_info_id : vmGet( $_REQUEST, 'ship_to_info_id');
2331  
2332              $db = new ps_DB;
2333              $q  = "SELECT country FROM #__{vm}_user_info WHERE user_info_id='" . $ship_to_info_id ."'";
2334              $db->query($q);
2335              $db->next_record();
2336              $ship_country = $db->f("country");
2337  
2338              if (! array_key_exists ('country', $auth) || empty( $ship_country ) ) {
2339                  $vmLogger->debug ('shopper\'s country is not known; defaulting to vendor-based tax');
2340                  return true;
2341              }
2342  
2343              if ( $ship_to_info_id ) {
2344                  $vmLogger->debug ('shopper shipping in ' . $ship_country);
2345                  $auth_country = $ship_country;
2346              }
2347              else {
2348                  $vmLogger->debug ('shopper is in ' . $auth['country']);
2349                  $auth_country = $auth['country'];
2350              }
2351                  return ps_checkout::country_in_eu_common_vat_zone ( $auth_country );
2352  
2353          default:
2354              $vmLogger->warning ('unknown TAX_MODE "' . TAX_MODE . '"');
2355              return true;
2356          }
2357      }
2358      
2359  	function country_in_eu_common_vat_zone ($country) {
2360          $eu_countries = array ('AUT', 'BGR', 'BEL', 'CYP', 'CZE', 'DEU', 'DNK', 'ESP', 'EST', 
2361                                  'FIN', 'FRA', 'FXX', 'GBR', 'GRC', 'HUN', 'IRL', 'ITA', 'LVA', 'LTU', 
2362                                  'LUX', 'MLT', 'NLD', 'POL', 'PRT', 'ROM', 'SVK', 'SVN', 'SWE');
2363          return in_array ($country, $eu_countries);
2364      }
2365  }
2366  
2367  // Check if there is an extended class in the Themes and if it is allowed to use them

2368  // If the class is called outside Virtuemart, we have to make sure to load the settings

2369  // Thomas Kahl - Feb. 2009

2370  if (!defined('VM_ALLOW_EXTENDED_CLASSES') && file_exists(dirname(__FILE__).'/../virtuemart.cfg.php')) {
2371      include_once(dirname(__FILE__).'/../virtuemart.cfg.php');
2372  }
2373  // If settings are loaded, extended Classes are allowed and the class exisits...

2374  if (defined('VM_ALLOW_EXTENDED_CLASSES') && defined('VM_THEMEPATH') && VM_ALLOW_EXTENDED_CLASSES && file_exists(VM_THEMEPATH.'user_class/'.basename(__FILE__))) {
2375      // Load the theme-user_class as extended

2376      include_once(VM_THEMEPATH.'user_class/'.basename(__FILE__));
2377  } else {
2378      // Otherwise we have to use the original classname to extend the core-class

2379      class ps_checkout extends vm_ps_checkout {}
2380  }
2381  ?>


Generato il: Mon Oct 19 20:29:27 2009 Generato con PHPXref 0.7