Author Topic: How do I programmatically set specific Shipment or Payment method in VM3?  (Read 3184 times)

Genius WebDesign

  • 3rd party VirtueMart Developer
  • Jr. Member
  • *
  • Posts: 175
    • 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:

Code: [Select]
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

  • 3rd party VirtueMart Developer
  • Jr. Member
  • *
  • Posts: 175
    • 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

  • Jr. Member
  • **
  • Posts: 80
  • VirtueMart Version: 3.0.3
Re: How do I programmatically set specific Shipment or Payment method in VM3?
« Reply #2 on: February 01, 2015, 02:29:03 am »
There is already in Vm3 an option : select shipment/payment automatically

Isn't that sufficient?

Kind regards,

Bluezeyes

Genius WebDesign

  • 3rd party VirtueMart Developer
  • Jr. Member
  • *
  • Posts: 175
    • Genius WebDesign
Re: How do I programmatically set specific Shipment or Payment method in VM3?
« Reply #3 on: February 01, 2015, 02:47:12 am »
That does not work when you have more than one shipment and payment option...

PRO

  • Global Moderator
  • Super Hero
  • *
  • Posts: 10432
  • VirtueMart Version: 3+
Re: How do I programmatically set specific Shipment or Payment method in VM3?
« Reply #4 on: February 01, 2015, 11:08:15 am »
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

  • Jr. Member
  • **
  • Posts: 80
  • VirtueMart Version: 3.0.3
Re: How do I programmatically set specific Shipment or Payment method in VM3?
« Reply #5 on: February 01, 2015, 11:16:51 am »
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

  • Virtuemart Projectleader
  • Administrator
  • Super Hero
  • *
  • Posts: 10273
  • VM3.9 Eagle Owl
    • VM3 Extensions
  • VirtueMart Version: VirtueMart 3 on joomla 3
Re: How do I programmatically set specific Shipment or Payment method in VM3?
« Reply #6 on: February 01, 2015, 12:01:26 pm »
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

  • 3rd party VirtueMart Developer
  • Jr. Member
  • *
  • Posts: 175
    • Genius WebDesign
Re: How do I programmatically set specific Shipment or Payment method in VM3?
« Reply #7 on: February 01, 2015, 21:11:17 pm »
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:

Code: [Select]
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)

Code: [Select]
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

  • Virtuemart Projectleader
  • Administrator
  • Super Hero
  • *
  • Posts: 10273
  • VM3.9 Eagle Owl
    • VM3 Extensions
  • VirtueMart Version: VirtueMart 3 on joomla 3
Re: How do I programmatically set specific Shipment or Payment method in VM3?
« Reply #8 on: February 01, 2015, 21:39:56 pm »
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

  • 3rd party VirtueMart Developer
  • Jr. Member
  • *
  • Posts: 175
    • Genius WebDesign
Re: How do I programmatically set specific Shipment or Payment method in VM3?
« Reply #9 on: February 01, 2015, 22:14:18 pm »
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.