Order reuse in VM broken

If you are runnig Joomla 3.x and Virtuemart 3.x please post to this forum your questions or support tickets about One Page Checkout

Order reuse in VM broken

Postby admin » Thu May 19, 2016 7:38 pm

Order reuse on all VM versions till now (VM3.0.16) is broken and can produce unexpected results or wrong order details.

in VM3.0.16 an ACL was added to remove functions at the order model and thus if the order is being reused (after an unfinished paypal payment that leads to the pending status of the order)

problems detected in core virtuemart:
- order reuse starts working only from a 3rd order attempt
- order reuse is enabled by default even though it's a hidden virtuemart configuration (virtuemart.cfg) and further more it also does the reuse in other cases regarless of the configuration variable
- the order being reused may not get stored to the database properly if the order is loaded with wrongly cached getOrder functions that loads previous order and orderStatusSchange is triggered which refreshes the order once again
- the order being reused is the first one done in the last hour and not the last one done by the customer in the pending state
- order being reused may be a completely different order that should have got reused

to fix some of these issues we:
- in OPC 3.0.312 we disabled order reuse by default
- if you choose to use it, opc will search for these errors in your VM installation and update your:
\administrator\components\com_virtuemart\models\orders.php

fucntion gets renamed and a new function is added:
Code: Select all
function removeOrderItems ($virtuemart_order_id){

      if(!vmAccess::manager('orders.edit')) {
         return false;
      }
      $q ='DELETE from `#__virtuemart_order_items` WHERE `virtuemart_order_id` = ' .(int) $virtuemart_order_id;
      $db = JFactory::getDBO();
      $db->setQuery($q);

      if ($db->execute() === false) {
         vmError($db->getError());
         return false;
      }
      return true;
   }


updated function:
Code: Select all

function removeOrderItems ($virtuemart_order_id){
/*this whole funciton was added by rupostel opc to fix double items for order reuse */
if (empty($virtuemart_order_id)) return true;
$q = 'DELETE from `#__virtuemart_order_items` WHERE `virtuemart_order_id` = ' .(int) $virtuemart_order_id; $db = JFactory::getDBO(); $db->setQuery($q);
$db->query();
$q = 'DELETE from `#__virtuemart_order_calc_rules` WHERE `virtuemart_order_id` = ' .(int) $virtuemart_order_id; $db->setQuery($q);
$db->query();
return true;
}



a fix that is introduced in vm3.0.17 and later:
line (1036 in vm3.0.16):
Code: Select all
$db->setQuery($q . ' WHERE `order_number`= "'.$_cart->virtuemart_order_id.'" AND `order_status` = "P" ');


is changed to proper line:
Code: Select all
$db->setQuery($q . ' WHERE `virtuemart_order_id`= "'.$_cart->virtuemart_order_id.'" AND `order_status` = "P" ');



further more if you are a 3rd party developer having problem of getting the order udpated properly:

before calling this function:
$order = $orderModel->getOrder($virtuemart_order_id);

we suggest to clear the cache:
Code: Select all
            if (method_exists($orderModel, 'emptyCache')) {
              $orderModel->emptyCache();
            }


if you still experience issues with this you can comment whole section of the order reuse on your Virtuemart version, search and comment this:
Code: Select all

if($_cart->_inConfirm){
         $order = false;
         $db = JFactory::getDbo();
         $q = 'SELECT * FROM `#__virtuemart_orders` ';
         if(!empty($_cart->virtuemart_order_id)){
            $db->setQuery($q . ' WHERE `order_number`= "'.$_cart->virtuemart_order_id.'" AND `order_status` = "P" ');
            $order = $db->loadAssoc();
            if(!$order){
               vmdebug('This should not happen, there is a cart with order_number, but not order stored '.$_cart->virtuemart_order_id);
            }
         }

         if(VmConfig::get('reuseorders',true) and !$order){
            $jnow = JFactory::getDate();
            $jnow->sub(new DateInterval('PT1H'));
            $minushour = $jnow->toSQL();
            $q .= ' WHERE `customer_number`= "'.$_orderData->customer_number.'" ';
            $q .= '   AND `order_status` = "P"
            AND `created_on` > "'.$minushour.'" ';
            $db->setQuery($q);
            $order = $db->loadAssoc();
         }

         if($order){
            if(!empty($order['virtuemart_order_id'])){
               $_orderData->virtuemart_order_id = $order['virtuemart_order_id'];
            }

            //Dirty hack
            $this->removeOrderItems($order['virtuemart_order_id']);
         }
      }



so it looks like:

Code: Select all
/*
if($_cart->_inConfirm){
         $order = false;
         $db = JFactory::getDbo();
         $q = 'SELECT * FROM `#__virtuemart_orders` ';
         if(!empty($_cart->virtuemart_order_id)){
            $db->setQuery($q . ' WHERE `order_number`= "'.$_cart->virtuemart_order_id.'" AND `order_status` = "P" ');
            $order = $db->loadAssoc();
            if(!$order){
               vmdebug('This should not happen, there is a cart with order_number, but not order stored '.$_cart->virtuemart_order_id);
            }
         }

         if(VmConfig::get('reuseorders',true) and !$order){
            $jnow = JFactory::getDate();
            $jnow->sub(new DateInterval('PT1H'));
            $minushour = $jnow->toSQL();
            $q .= ' WHERE `customer_number`= "'.$_orderData->customer_number.'" ';
            $q .= '   AND `order_status` = "P"
            AND `created_on` > "'.$minushour.'" ';
            $db->setQuery($q);
            $order = $db->loadAssoc();
         }

         if($order){
            if(!empty($order['virtuemart_order_id'])){
               $_orderData->virtuemart_order_id = $order['virtuemart_order_id'];
            }

            //Dirty hack
            $this->removeOrderItems($order['virtuemart_order_id']);
         }
      }
*/


best regards, stan
admin
Site Admin
 
Posts: 2708
Joined: Wed Jan 06, 2010 11:43 pm

Return to One Page Checkout for Virtuemart 3 on Joomla 3.x

cron