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.
*****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.
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.