Shipping and Payment Method Issue - if a Member of multiple Shopper Gorups

Started by mjkstk, June 16, 2012, 06:17:29 AM

Previous topic - Next topic

mjkstk

Our shoppers may be members of more than one shopper group, but are always members of the -default- shopper group. If I add a user to more than one shopper group, on check out they get no Shipping Method Choices nor do they get any Payment method choices.

I have tried setting the option to just -default- in the shipping method and payment methods, I have tried removing everything, and then I tried adding every shopper group. No matter what, if a shopper is a member of multiple groups - it does not work.  We are trying to go live with this site and this is our last road block.  Can anyone help?

Thanks in advance for your suggestions and time.

mjkstk

*****UPDATE OF THIS ISSUE*****

I have found the error in the VM2 code (administrator/components/com_virtuemart/plugins/vmpsplugin.php) and hope that it will be corrected by VirtueMart for work going forward. For now, this is my solution that is working and an explanation of what I feel is the issue.

***EXPLANATION***
In the protected function getPluginMethods, the PHP code checks the DB for information about the shopper groups a user is a member of, if a Shopper was a member of more than one group, in any combination I could find, the code failed to find Shipment or Payment methods.  In my case, I needed shoppers to be in more than one group - BUT - there is only 2 shipping methods for everyone, and 1 payment method for everyone.
***END EXPLANATION***

***CODE CAUSING ISSUE***
   $user = $usermodel->getUser();
   $user->shopper_groups = (array) $user->shopper_groups;

   $db = JFactory::getDBO();

   $select = 'SELECT l.*, v.*, ';

   if (JVM_VERSION === 1) {
       $extPlgTable = '#__plugins';
       $extField1 = 'id';
       $extField2 = 'element';

       $select .= 'j.`' . $extField1 . '`, j.`name`, j.`element`, j.`folder`, j.`client_id`, j.`access`,
            j.`params`,  j.`checked_out`, j.`checked_out_time`,  s.virtuemart_shoppergroup_id ';
   } else {
       $extPlgTable = '#__extensions';
       $extField1 = 'extension_id';
       $extField2 = 'element';

       $select .= 'j.`' . $extField1 . '`,j.`name`, j.`type`, j.`element`, j.`folder`, j.`client_id`, j.`enabled`, j.`access`, j.`protected`, j.`manifest_cache`,
            j.`params`, j.`custom_data`, j.`system_data`, j.`checked_out`, j.`checked_out_time`, j.`state`,  s.virtuemart_shoppergroup_id ';
   }

   $q = $select . ' FROM   `#__virtuemart_' . $this->_psType . 'methods_' . VMLANG . '` as l ';
   $q.= ' JOIN `#__virtuemart_' . $this->_psType . 'methods` AS v   USING (`virtuemart_' . $this->_psType . 'method_id`) ';
   $q.= ' LEFT JOIN `' . $extPlgTable . '` as j ON j.`' . $extField1 . '` =  v.`' . $this->_psType . '_jplugin_id` ';
   $q.= ' LEFT OUTER JOIN `#__virtuemart_' . $this->_psType . 'method_shoppergroups` AS s ON v.`virtuemart_' . $this->_psType . 'method_id` = s.`virtuemart_' . $this->_psType . 'method_id` ';
   $q.= ' WHERE v.`published` = "1" AND j.`' . $extField2 . '` = "' . $this->_name . '"
                         AND  (v.`virtuemart_vendor_id` = "' . $vendorId . '" OR   v.`virtuemart_vendor_id` = "0")
                         AND  (';

   foreach ($user->shopper_groups as $groups) {
       $q .= 's.`virtuemart_shoppergroup_id`= "' . (int) $groups . '" OR';
   }
   $q .= ' (s.`virtuemart_shoppergroup_id`) IS NULL ) ORDER BY v.`ordering`';

   $db->setQuery($q);

***END CODE CAUSING ISSUE***

***WHAT I THINK IS HAPPENING***
I believe that the code is checking the database for a Shipping Method/Payment Method that matched ALL Shopper Groups the Shopper is a member of, but it should return ALL Shipping Methos/Payment Methods that are "available" to members of ANY of the Shopper Groups the Shopper is a member of.

For me, the following solution works - it essentially says that I should show any Shipping Method(s)/Payment Method(s) that the "-default-" shopper group can see.
***END WHAT I THINK IS HAPPENING***

***FIXED CODE***
   $user = $usermodel->getUser();
   $user->shopper_groups = (array) $user->shopper_groups;

   $db = JFactory::getDBO();

   $select = 'SELECT l.*, v.*, ';

   if (JVM_VERSION === 1) {
       $extPlgTable = '#__plugins';
       $extField1 = 'id';
       $extField2 = 'element';

       $select .= 'j.`' . $extField1 . '`, j.`name`, j.`element`, j.`folder`, j.`client_id`, j.`access`,
            j.`params`,  j.`checked_out`, j.`checked_out_time`,  s.virtuemart_shoppergroup_id ';
   } else {
       $extPlgTable = '#__extensions';
       $extField1 = 'extension_id';
       $extField2 = 'element';

       $select .= 'j.`' . $extField1 . '`,j.`name`, j.`type`, j.`element`, j.`folder`, j.`client_id`, j.`enabled`, j.`access`, j.`protected`, j.`manifest_cache`,
            j.`params`, j.`custom_data`, j.`system_data`, j.`checked_out`, j.`checked_out_time`, j.`state`,  s.virtuemart_shoppergroup_id ';
   }

   $q = $select . ' FROM   `#__virtuemart_' . $this->_psType . 'methods_' . VMLANG . '` as l ';
   $q.= ' JOIN `#__virtuemart_' . $this->_psType . 'methods` AS v   USING (`virtuemart_' . $this->_psType . 'method_id`) ';
   $q.= ' LEFT JOIN `' . $extPlgTable . '` as j ON j.`' . $extField1 . '` =  v.`' . $this->_psType . '_jplugin_id` ';
   $q.= ' LEFT OUTER JOIN `#__virtuemart_' . $this->_psType . 'method_shoppergroups` AS s ON v.`virtuemart_' . $this->_psType . 'method_id` = s.`virtuemart_' . $this->_psType . 'method_id` ';
   $q.= ' WHERE v.`published` = "1" AND j.`' . $extField2 . '` = "' . $this->_name . '"
                         AND  (v.`virtuemart_vendor_id` = "' . $vendorId . '" OR   v.`virtuemart_vendor_id` = "0")
                         AND  (';

   if ($this->_psType == "shipment" || $this->_psType == "payment"){
      $q .= 's.`virtuemart_shoppergroup_id`= "' .(int) "1".'" OR';

   } else {
      foreach ($user->shopper_groups as $groups) {
          $q .= 's.`virtuemart_shoppergroup_id`= "' . (int) $groups . '" OR';
      }
   }
   $q .= ' (s.`virtuemart_shoppergroup_id`) IS NULL ) ORDER BY v.`ordering`';
   
   
   $db->setQuery($q);

***END FIXED CODE***

Hope this helps someone else, also, if anyone at VirtueMart can fix this properly it would be much appreciated, that is why I spent the time to be extremely detailed.

mattcowan

I had a different problem and yet mjkstk's code above helped- I wanted to limit shipping & payment options for a specific shoppergroup (5) and not show the -default- methods. Added:

if (in_array("5",$user->shopper_groups)){
$q .= 's.`virtuemart_shoppergroup_id`= "' .(int) "5".'" OR';
} else {
foreach ($user->shopper_groups as $groups) {
$q .= ' s.`virtuemart_shoppergroup_id`= "' . (int)$groups . '" OR';
}
}


in place of where his altered code was.

Now if a user is a member of that shopper group, they only get shown methods for that shopper group.