How do I programmatically set specific Shipment or Payment method in VM3?

Started by Genius WebDesign, January 31, 2015, 04:12:56 AM

Previous topic - Next topic

Genius WebDesign

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.


Genius WebDesign

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

bluezeyes

There is already in Vm3 an option : select shipment/payment automatically

Isn't that sufficient?

Kind regards,

Bluezeyes

Genius WebDesign

That does not work when you have more than one shipment and payment option...

PRO

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 ?

bluezeyes

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

Milbo

Genius WebDesign what you try todo, works only with js, atm. believe me.
Should I fix your bug, please support the VirtueMart project and become a member
______________________________________
Extensions approved by the core team: http://extensions.virtuemart.net/

Genius WebDesign

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.


Milbo

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.
Should I fix your bug, please support the VirtueMart project and become a member
______________________________________
Extensions approved by the core team: http://extensions.virtuemart.net/

Genius WebDesign

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.