Hi,
As the title suggests I´m looking for a way to programmatically set a specific Shipment or Payment method in VM3.
Specifically I need to set a default shipment or payment if none is already selected. (the shop has multiple shipment and payment options)
I found a hack which should work in VM2 but this method does not work in VM3 because the cart helper in VM3 is very different from VM2.
I´m referring to this thread:
http://forum.virtuemart.net/index.php?topic=101681.0
In VM2 you could add this code to /components/com_virtuemart/views/cart/view.html.php:
if( $cart->virtuemart_shipmentmethod_id == 0 ){ $cart->setShipment( 3 ); } //<< Use the ID of whichever method suits you best
if( $cart->virtuemart_paymentmethod_id == 0 ){ $cart->setPaymentMethod( 1 ); } //<< Use the ID of whichever method suits you best
But it seems that the function "setShipment()" is completely missing in VM3 and "setPaymentMethod()" is also altered I think..
Please Milbo, or someone else involved with the cart helper, give me some pointers on how I can set Shipment and Payment programmatically.
This is very important for our shop so I hope a developer will be so kind and give me the required information.
If there are no function for this in VM3 I will need to hack the cart helper and modify the two functions "setShipmentMethod()" and "setPaymentMethod()"
found in /components/com_virtuemart/helpers/cart.php on line 807 and 839
Of course I hope that this will not be needed..
There is already in Vm3 an option : select shipment/payment automatically
Isn't that sufficient?
Kind regards,
Bluezeyes
That does not work when you have more than one shipment and payment option...
in helpers/cart.php
the shipment method is now.
public function setShipmentMethod($force=false, $redirect=true)
in views/cart/html.php
you have
$selectedShipment = (empty($this->cart->virtuemart_shipmentmethod_id) ? 0 : $this->cart->virtuemart_shipmentmethod_id);
what have you tried to do for VM3 ?
Well I don't know the function behind it, but if there are two shipment methods, which meets both in requirements like weight and price, it should select the one, which is cheaper for the customer in shipping costs...
That would the expected behavior..
Same on payment.
Have You set your ranges in shipment correctly?
The thing is overall, how should this functionally know, which shipment / payment should be selected at all, especially when You have over lapping methods for the same range..
In general with a correctly set up of ranges (from - to) it work as designed.
What are your requirements in which order a payment / shipment option should be Pre-selected?
Regards,
Bluezeyes
Genius WebDesign what you try todo, works only with js, atm. believe me.
Hello Milbo!
Thanks for answering :)
I came up with a solution, though I had to do some core hacking.
Here it goes..:
1. I replaced the functions "setShipmentMethod" & "setPaymentMethod" in /components/com_virtuemart/helpers/cart.php, with these modified functions:
public function setShipmentMethod($force=false, $redirect=true, $customshipmentid=false) {
if ($customshipmentid > 0) {
$virtuemart_shipmentmethod_id = $customshipmentid;
} else {
$virtuemart_shipmentmethod_id = vRequest::getInt('virtuemart_shipmentmethod_id', $this->virtuemart_shipmentmethod_id);
}
if($this->virtuemart_shipmentmethod_id != $virtuemart_shipmentmethod_id or $force){
$this->_dataValidated = false;
//Now set the shipment ID into the cart
$this->virtuemart_shipmentmethod_id = $virtuemart_shipmentmethod_id;
if (!class_exists('vmPSPlugin')) require(JPATH_VM_PLUGINS . DS . 'vmpsplugin.php');
JPluginHelper::importPlugin('vmshipment');
//Add a hook here for other payment methods, checking the data of the choosed plugin
$_dispatcher = JDispatcher::getInstance();
$_retValues = $_dispatcher->trigger('plgVmOnSelectCheckShipment', array( &$this));
$dataValid = true;
foreach ($_retValues as $_retVal) {
if ($_retVal === true ) {
// Plugin completed successfull; nothing else to do
break;
} else if ($_retVal === false ) {
if ($redirect) {
$mainframe = JFactory::getApplication();
$mainframe->redirect(JRoute::_('index.php?option=com_virtuemart&view=cart&task=edit_shipment',$this->useXHTML,$this->useSSL), $_retVal);
break;
} else {
return;
}
}
}
$this->setCartIntoSession();
}
}
public function setPaymentMethod($force=false, $redirect=true, $custompaymentid=false) {
if ($custompaymentid > 0) {
$virtuemart_paymentmethod_id = $custompaymentid;
} else {
$virtuemart_paymentmethod_id = vRequest::getInt('virtuemart_paymentmethod_id', $this->virtuemart_paymentmethod_id);
}
if($this->virtuemart_paymentmethod_id != $virtuemart_paymentmethod_id or $force){
$this->_dataValidated = false;
$this->virtuemart_paymentmethod_id = $virtuemart_paymentmethod_id;
if(!class_exists('vmPSPlugin')) require(JPATH_VM_PLUGINS.DS.'vmpsplugin.php');
JPluginHelper::importPlugin('vmpayment');
//Add a hook here for other payment methods, checking the data of the choosed plugin
$msg = '';
$_dispatcher = JDispatcher::getInstance();
$_retValues = $_dispatcher->trigger('plgVmOnSelectCheckPayment', array( $this, &$msg));
$dataValid = true;
foreach ($_retValues as $_retVal) {
if ($_retVal === true ) {
// Plugin completed succesfull; nothing else to do
break;
} else if ($_retVal === false ) {
if ($redirect) {
$app = JFactory::getApplication();
$app->redirect(JRoute::_('index.php?option=com_virtuemart&view=cart&task=editpayment',$this->useXHTML,$this->useSSL), $msg);
break;
} else {
return;
}
}
}
$this->setCartIntoSession();
}
}
2. Then in /components/com_virtuemart/views/cart/view.html.php, I added this code just after "$this->cart = VirtueMartCart::getCart();" (at line 57)
if( $this->cart->virtuemart_shipmentmethod_id == 0 ) { $this->cart->setShipmentMethod( false,false,6 ); } //<< Use the ID of whichever method suits you best
if( $this->cart->virtuemart_paymentmethod_id == 0 ) { $this->cart->setPaymentMethod( false,false,10 ); } //<< Use the ID of whichever method suits you best
So all in all it required 2 hacks, but now it works as needed.
I could of course do more coding to add the preferred default shipping and payment option as an admin parameter, but that must wait for another day.
You can also just use vRequest::setVar('virtuemart_payment_id',$yourId);
and then call the function. You can also just set it directly to the cart object itself, imho.
Thanks Milbo,
"You can also just use vRequest::setVar('virtuemart_payment_id',$yourId);"
I don´t know why I didn´t think of that.
Actually that would theoretically be the most clean solution, though I guess I still need to execute this code within the view.html.php file, making this a non-template (hack) solution.
If I have time I will do some further testing so check this out.