| [ Indice ] |
Riferimento incrociato di Joomla! 1.5.14 - VM 1.1.4Servizio fornito da VMItalia |
[Vedi sommario] [Stampa] [Vedi testo]
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 € => € 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 ?>
titolo
Descrizione
Corpo
titolo
Descrizione
Corpo
titolo
Descrizione
Corpo
titolo
Corpo
| Generato il: Mon Oct 19 20:29:27 2009 | Generato con PHPXref 0.7 |