Code to filter payment display based on products

  • Posts: 23
  • Thank you received: 0
14 years 1 week ago #16141

Hi Nicolas,
I am trying to filter a payment display based on categories of products in cart. That is, if only one product on order is within an array of categories id, that payment method should be displayed, otherwise it should be not available.

This is my coding:

function onPaymentDisplay(&$order,&$methods,&$usable_methods){
if(!empty($methods)){
    		foreach($methods as $method){
				if($method->payment_type!='MyPlugin' || !$method->enabled){
					continue;
				}
				
                                /* filter on category id of products on order */
				$catIds_to_search = array(39, 5, 3);
				$found = false; 
				
				foreach($order->products as $product){
				  foreach($product->categories as $category){
				    if (in_array($category->category_id,$catIds_to_search)) {
				      $found = true;
				      break 2;
				     }
				  }
				}
				if (!found) {
				  continue;
				}
				/* end filter categories */
                                
				if(!empty($method->payment_zone_namekey)){
					$zoneClass=hikashop::get('class.zone');
	    			$zones = $zoneClass->getOrderZones($order);
					if(!in_array($method->payment_zone_namekey,$zones)){
						return true;
					}
				}
				
				$usable_methods[$method->ordering]=$method;
    		}
    	}
    	return true;
    }
It does not work. I have figured out that $product->categories is empty

Would you please tell me where is the mistake?

Thanks in advance,
Emilio

Last edit: 12 years 5 months ago by Jerome.

Please Log in or Create an account to join the conversation.

  • Posts: 83799
  • Thank you received: 13571
  • MODERATOR
14 years 1 week ago #16150

Of course it doesn't work because hikashop does not load the list of categories in $product->categories.
That means that you need to load them yourself in your plugin:
$db =& JFactory::getDBO();
$db->setQuery('SELECT category_id FROM '.hikashop::table('product_category').' WHERE product_id = '.$product->product_id);
$product->categories = $db->loadResultArray();

Please Log in or Create an account to join the conversation.

  • Posts: 65
  • Thank you received: 0
12 years 5 months ago #80215

Hi Nicolas,
sorry but I'm not such an expert.. Could you explain step by step to me how can implement the following.
One of our products shall NOT have the payment method "on invoice".
If this product is in the cart with others, the whole delivery shall NOT be possible to be paid on invoice.

Thank you!

Please Log in or Create an account to join the conversation.

  • Posts: 13201
  • Thank you received: 2322
12 years 5 months ago #80421

Hi,

In the payment plugin file, you have to add a check on your product:

if($product->product_id == '22') continue;
Replace 22 by your product id, by this way this payment method will not be displayed if the product is in the cart.

If this product is in the cart with others, you will have to edit the file "administrator/components/com_hikashop/classes/cart.php" to check if the product is present in the cart with other products.
If it's the case, you disable all the payment methods and display an error message. Something like:
		$no1 = 0; $no2 = 0;
		foreach($order->products as $k => $product){
			if(($product->product_id == '22' && $product->product_parent_id == '0') || $product->product_parent_id == '22') $no1 = 1;
			else $no2 = 1;
		}
		if($no1 == 1 && $no2 ==1){
			$app = JFactory::getApplication();
			$app->enqueueMessage(JText::_('NO_PAYMENT_METHODS_FOUND'));
			$usable_methods=false;
		}

It should work. Replace '22' by your product id.

The following user(s) said Thank You: phamosa

Please Log in or Create an account to join the conversation.

  • Posts: 65
  • Thank you received: 0
12 years 5 months ago #80489

Dear Xavier, I will try when I'm back in my office, thank you.
What happens by default, if the product is in the cart with other products and I do not edit the mentioned file "administrator/components/com_hikashop/classes/cart.php" before?
Thank you!

Please Log in or Create an account to join the conversation.

  • Posts: 65
  • Thank you received: 0
12 years 5 months ago #80525

Where in the code do I have to add the check on the product in the file?


<?php

/**

* @package HikaShop for Joomla!

* @version 1.5.7

* @author hikashop.com

* @copyright (C) 2010-2012 HIKARI SOFTWARE. All rights reserved.

* @license GNU/GPLv3 www.gnu.org/licenses/gpl-3.0.html

*/

defined('_JEXEC') or die('Restricted access');

?>

<?php
class plgHikashoppaymentBanktransfer extends JPlugin

{
function onPaymentDisplay(&$order,&$methods,&$usable_methods){
if(!empty($methods)){
foreach($methods as $method){
if($method->payment_type!='banktransfer' || !$method->enabled){
continue;
}
if(!empty($method->payment_zone_namekey)){
$zoneClass=hikashop_get('class.zone');
$zones = $zoneClass->getOrderZones($order);
if(!in_array($method->payment_zone_namekey,$zones)){
return true;
}
}

$usable_methods[$method->ordering]=$method;
}
}
return true;
}
function onPaymentSave(&$cart,&$rates,&$payment_id){
$usable = array();
$this->onPaymentDisplay($cart,$rates,$usable);
$payment_id = (int) $payment_id;
foreach($usable as $usable_method){
if($usable_method->payment_id==$payment_id){
return $usable_method;
}
}
return false;
}
function onPaymentConfiguration(&$element){
$this->banktransfer = JRequest::getCmd('name','banktransfer');
if(empty($element)){
$element = null;
$element->payment_name='Bank transfer';
$element->payment_description='You can pay by sending us a bank transfer.';
$element->payment_images='Bank_transfer';
$element->payment_type=$this->banktransfer;
$element->payment_params=null;
$element->payment_params->information='Account owner: XXXXX<br/>
<br/>
Owner address:<br/>
<br/>
XX XXXX XXXXXX<br/>
<br/>
XXXXX XXXXXXXX<br/>
<br/>
IBAN International Bank Account Number:<br/>
<br/>
XXXX XXXX XXXX XXXX XXXX XXXX XXX<br/>
<br/>
BIC swift Bank Identification Code:<br/>
<br/>
XXXXXXXXXXXXXX<br/>
<br/>
Bank name: XXXXXXXXXXX<br/>
<br/>
Bank address:<br/>
<br/>
XX XXXX XXXXXX<br/>
<br/>
XXXXX XXXXXXXX';
$element->payment_params->order_status='created';
$element = array($element);
}
$bar = & JToolBar::getInstance('toolbar');
JToolBarHelper::save();
JToolBarHelper::apply();
JToolBarHelper::cancel();
JToolBarHelper::divider();
$bar->appendButton( 'Pophelp','payment-banktransfer-form');
hikashop_setTitle(JText::_('BANK_TRANSFER'),'plugin','plugins&plugin_type=payment&task=edit&name='.$this->banktransfer);
$app =& JFactory::getApplication();
$app->setUserState( HIKASHOP_COMPONENT.'.payment_plugin_type', $this->banktransfer);
$this->category = hikashop_get('type.categorysub');
$this->category->type = 'status';
$this->editor = hikashop_get('helper.editor');
}
function onPaymentConfigurationSave(&$element){
$element->payment_params->information = JRequest::getVar('bank_account_information','','','string',JREQUEST_ALLOWRAW);
return true;
}
function onAfterOrderConfirm(&$order,&$methods,$method_id){
$method =& $methods[$method_id];
$orderObj = null;
$orderObj->order_status = $method->payment_params->order_status;
$orderObj->order_id = $order->order_id;
$orderClass = hikashop_get('class.order');
$orderClass->save($orderObj);
$app =& JFactory::getApplication();
$this->removeCart = true;
$name = $method->payment_type.'_end.php';
$path = JPATH_THEMES.DS.$app->getTemplate().DS.'hikashoppayment'.DS.$name;
if(!file_exists($path)){
if(version_compare(JVERSION,'1.6','<')){
$path = JPATH_PLUGINS .DS.'hikashoppayment'.DS.$name;
}else{
$path = JPATH_PLUGINS .DS.'hikashoppayment'.DS.$method->payment_type.DS.$name;
}
if(!file_exists($path)){
return true;
}
}
$information = $method->payment_params->information;
if(preg_match('#^[a-z0-9_]*$#i',$information)){
$information = JText::_($information);
}
$currencyClass = hikashop_get('class.currency');
$amount = $currencyClass->format($order->order_full_price,$order->order_currency_id);
$order_number = $order->order_number;
require($path);
return true;
}

}

Please Log in or Create an account to join the conversation.

  • Posts: 83799
  • Thank you received: 13571
  • MODERATOR
12 years 5 months ago #80582

It should be done before that line:
$usable_methods[$method->ordering]=$method;

note that you will have to loop through the $order->products array in order to use $product.

Please Log in or Create an account to join the conversation.

  • Posts: 65
  • Thank you received: 0
12 years 5 months ago #80651

dear nicolas, i don't know what "note that you will have to loop through the $order->products array in order to use $product. " means..

How do I "loop through" an array?
Sorry..

Please Log in or Create an account to join the conversation.

  • Posts: 13201
  • Thank you received: 2322
12 years 5 months ago #80694

Hi,

To loop through, you have do to something like:

foreach($products as $product){
    //your action.
}

Please Log in or Create an account to join the conversation.

  • Posts: 65
  • Thank you received: 0
12 years 5 months ago #80716

Could you add "the loop" and the add-on for the exclusion of the payment method for my specific article (if($product->product_id == '22') continue;) to the code that I posted above, at the right position, so that I can copy the whole code and insert it into my php?

Sorry, I have never worked with a php file before and need some help with it..
Thank you!

Please Log in or Create an account to join the conversation.

  • Posts: 65
  • Thank you received: 0
12 years 5 months ago #80766

Hi Xavier,

I added the code you suggested but when checking it, it didn't work: it still displays the ON INVOICE payment method.
Here is the code:

function onPaymentDisplay(&$order,&$methods,&$usable_methods){
    	if(!empty($methods)){
    		foreach($methods as $method){
				if($method->payment_type!='banktransfer' || !$method->enabled){
					continue;
				}
				if(!empty($method->payment_zone_namekey)){
					$zoneClass=hikashop_get('class.zone');
	    			$zones = $zoneClass->getOrderZones($order);
					if(!in_array($method->payment_zone_namekey,$zones)){
						return true;
					}
				}
        foreach($products as $product){
          if($product->product_id == '165') continue;
        } 
				$usable_methods[$method->ordering]=$method;
    		}
    	}
    	return true;
    }

Could you please have a look and tell me why it doesn't work? Thank you!

Please Log in or Create an account to join the conversation.

  • Posts: 13201
  • Thank you received: 2322
12 years 5 months ago #80812

Hi,

Can you try with:

function onPaymentDisplay(&$order,&$methods,&$usable_methods){
    	if(!empty($methods)){
    		foreach($methods as $method){
				if($method->payment_type!='banktransfer' || !$method->enabled){
					continue;
				}
				if(!empty($method->payment_zone_namekey)){
					$zoneClass=hikashop_get('class.zone');
	    			$zones = $zoneClass->getOrderZones($order);
					if(!in_array($method->payment_zone_namekey,$zones)){
						return true;
					}
				}
        $hide = 0;
        foreach($products as $product){
          if($product->product_id == '165') $hide = 1;
        } 
				if($hide == 0) $usable_methods[$method->ordering]=$method;
    		}
    	}
    	return true;
    }

Please Log in or Create an account to join the conversation.

  • Posts: 65
  • Thank you received: 0
12 years 5 months ago #80819

ciao xavier,
this is what I have as a code now:

<?php

/**

 * @package		HikaShop for Joomla!

 * @version		1.5.7

 * @author		hikashop.com

 * @copyright	(C) 2010-2012 HIKARI SOFTWARE. All rights reserved.

 * @license		GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html

 */

defined('_JEXEC') or die('Restricted access');

?>

<?php
class plgHikashoppaymentBanktransfer extends JPlugin

{
function onPaymentDisplay(&$order,&$methods,&$usable_methods){
    	if(!empty($methods)){
    		foreach($methods as $method){
				if($method->payment_type!='banktransfer' || !$method->enabled){
					continue;
				}
				if(!empty($method->payment_zone_namekey)){
					$zoneClass=hikashop_get('class.zone');
	    			$zones = $zoneClass->getOrderZones($order);
					if(!in_array($method->payment_zone_namekey,$zones)){
						return true;
					}
				}
        $hide = 0;
        foreach($products as $product){
          if($product->product_id == '165') $hide = 1;
        } 
				if($hide == 0) $usable_methods[$method->ordering]=$method;
    		}
    	}
    	return true;
    }
    function onPaymentSave(&$cart,&$rates,&$payment_id){
    	$usable = array();
    	$this->onPaymentDisplay($cart,$rates,$usable);
    	$payment_id = (int) $payment_id;
    	foreach($usable as $usable_method){
    		if($usable_method->payment_id==$payment_id){
    			return $usable_method;
    		}
    	}
    	return false;
    }
    function onPaymentConfiguration(&$element){
    	$this->banktransfer = JRequest::getCmd('name','banktransfer');
    	if(empty($element)){
    		$element = null;
    		$element->payment_name='Bank transfer';
    		$element->payment_description='You can pay by sending us a bank transfer.';
    		$element->payment_images='Bank_transfer';
    		$element->payment_type=$this->banktransfer;
    		$element->payment_params=null;
    		$element->payment_params->information='Account owner: XXXXX<br/>
<br/>
Owner address:<br/>
<br/>
XX XXXX XXXXXX<br/>
<br/>
XXXXX XXXXXXXX<br/>
<br/>
IBAN International Bank Account Number:<br/>
<br/>
XXXX XXXX XXXX XXXX XXXX XXXX XXX<br/>
<br/>
BIC swift Bank Identification Code:<br/>
<br/>
XXXXXXXXXXXXXX<br/>
<br/>
Bank name: XXXXXXXXXXX<br/>
<br/>
Bank address:<br/>
<br/>
XX XXXX XXXXXX<br/>
<br/>
XXXXX XXXXXXXX';
    		$element->payment_params->order_status='created';
    		$element = array($element);
    	}
    	$bar = & JToolBar::getInstance('toolbar');
		JToolBarHelper::save();
		JToolBarHelper::apply();
		JToolBarHelper::cancel();
		JToolBarHelper::divider();
		$bar->appendButton( 'Pophelp','payment-banktransfer-form');
		hikashop_setTitle(JText::_('BANK_TRANSFER'),'plugin','plugins&plugin_type=payment&task=edit&name='.$this->banktransfer);
		$app =& JFactory::getApplication();
		$app->setUserState( HIKASHOP_COMPONENT.'.payment_plugin_type', $this->banktransfer);
		$this->category = hikashop_get('type.categorysub');
		$this->category->type = 'status';
		$this->editor = hikashop_get('helper.editor');
    }
    function onPaymentConfigurationSave(&$element){
    	$element->payment_params->information = JRequest::getVar('bank_account_information','','','string',JREQUEST_ALLOWRAW);
    	return true;
    }
    function onAfterOrderConfirm(&$order,&$methods,$method_id){
    	$method =& $methods[$method_id];
    	$orderObj = null;
    	$orderObj->order_status = $method->payment_params->order_status;
    	$orderObj->order_id = $order->order_id;
    	$orderClass = hikashop_get('class.order');
    	$orderClass->save($orderObj);
    	$app =& JFactory::getApplication();
    	$this->removeCart = true;
		$name = $method->payment_type.'_end.php';
    	$path = JPATH_THEMES.DS.$app->getTemplate().DS.'hikashoppayment'.DS.$name;
    	if(!file_exists($path)){
    		if(version_compare(JVERSION,'1.6','<')){
    			$path = JPATH_PLUGINS .DS.'hikashoppayment'.DS.$name;
    		}else{
    			$path = JPATH_PLUGINS .DS.'hikashoppayment'.DS.$method->payment_type.DS.$name;
    		}
    		if(!file_exists($path)){
    			return true;
    		}
    	}
    	$information = $method->payment_params->information;
    	if(preg_match('#^[a-z0-9_]*$#i',$information)){
    		$information = JText::_($information);
    	}
    	$currencyClass = hikashop_get('class.currency');
    	$amount = $currencyClass->format($order->order_full_price,$order->order_currency_id);
    	$order_number = $order->order_number;
    	require($path);
		return true;
    }

}

and this is the message I get in the front end:


Warning: Invalid argument supplied for foreach() in /kunden/70889_37318/rufrecords_2012/plugins/hikashoppayment/banktransfer/banktransfer.php on line 39


There must still be something wrong there..

Please Log in or Create an account to join the conversation.

  • Posts: 26233
  • Thank you received: 4036
  • MODERATOR
12 years 5 months ago #80909

Hi,

It is not "$products" but "$order->products" like Nicolas said in a previous post.
So, you have to use $order->products, like this:

				$hide = 0;
				foreach($order->products as $product){
					if($product->product_id == '165')
						$hide = 1;
				}
				if($hide == 0)
					$usable_methods[$method->ordering]=$method;

Regards,


Jerome - Obsidev.com
HikaMarket & HikaSerial developer / HikaShop core dev team.

Also helping the HikaShop support team when having some time or couldn't sleep.
By the way, do not send me private message, use the "contact us" form instead.

Please Log in or Create an account to join the conversation.

  • Posts: 65
  • Thank you received: 0
12 years 5 months ago #80920

Ciao Jerome,

thank you for your post. I applied your suggestion and used the following code. Now what happens is that if you add the article 165 to your cart and then click on "proceed to checkout", you get a message "your cart is empty" and the content of the cart (article 165) is deleted.

<?php

/**

 * @package		HikaShop for Joomla!

 * @version		1.5.7

 * @author		hikashop.com

 * @copyright	(C) 2010-2012 HIKARI SOFTWARE. All rights reserved.

 * @license		GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html

 */

defined('_JEXEC') or die('Restricted access');

?>

<?php
class plgHikashoppaymentBanktransfer extends JPlugin

{
function onPaymentDisplay(&$order,&$methods,&$usable_methods){
    	if(!empty($methods)){
    		foreach($methods as $method){
				if($method->payment_type!='banktransfer' || !$method->enabled){
					continue;
				}
				if(!empty($method->payment_zone_namekey)){
					$zoneClass=hikashop_get('class.zone');
	    			$zones = $zoneClass->getOrderZones($order);
					if(!in_array($method->payment_zone_namekey,$zones)){
						return true;
					}
				}
        $hide = 0;
        foreach($order->products as $product){
          if($product->product_id == '165') $hide = 1;
        } 
				if($hide == 0) $usable_methods[$method->ordering]=$method;
    		}
    	}
    	return true;
    }
    function onPaymentSave(&$cart,&$rates,&$payment_id){
    	$usable = array();
    	$this->onPaymentDisplay($cart,$rates,$usable);
    	$payment_id = (int) $payment_id;
    	foreach($usable as $usable_method){
    		if($usable_method->payment_id==$payment_id){
    			return $usable_method;
    		}
    	}
    	return false;
    }
    function onPaymentConfiguration(&$element){
    	$this->banktransfer = JRequest::getCmd('name','banktransfer');
    	if(empty($element)){
    		$element = null;
    		$element->payment_name='Bank transfer';
    		$element->payment_description='You can pay by sending us a bank transfer.';
    		$element->payment_images='Bank_transfer';
    		$element->payment_type=$this->banktransfer;
    		$element->payment_params=null;
    		$element->payment_params->information='Account owner: XXXXX<br/>
<br/>
Owner address:<br/>
<br/>
XX XXXX XXXXXX<br/>
<br/>
XXXXX XXXXXXXX<br/>
<br/>
IBAN International Bank Account Number:<br/>
<br/>
XXXX XXXX XXXX XXXX XXXX XXXX XXX<br/>
<br/>
BIC swift Bank Identification Code:<br/>
<br/>
XXXXXXXXXXXXXX<br/>
<br/>
Bank name: XXXXXXXXXXX<br/>
<br/>
Bank address:<br/>
<br/>
XX XXXX XXXXXX<br/>
<br/>
XXXXX XXXXXXXX';
    		$element->payment_params->order_status='created';
    		$element = array($element);
    	}
    	$bar = & JToolBar::getInstance('toolbar');
		JToolBarHelper::save();
		JToolBarHelper::apply();
		JToolBarHelper::cancel();
		JToolBarHelper::divider();
		$bar->appendButton( 'Pophelp','payment-banktransfer-form');
		hikashop_setTitle(JText::_('BANK_TRANSFER'),'plugin','plugins&plugin_type=payment&task=edit&name='.$this->banktransfer);
		$app =& JFactory::getApplication();
		$app->setUserState( HIKASHOP_COMPONENT.'.payment_plugin_type', $this->banktransfer);
		$this->category = hikashop_get('type.categorysub');
		$this->category->type = 'status';
		$this->editor = hikashop_get('helper.editor');
    }
    function onPaymentConfigurationSave(&$element){
    	$element->payment_params->information = JRequest::getVar('bank_account_information','','','string',JREQUEST_ALLOWRAW);
    	return true;
    }
    function onAfterOrderConfirm(&$order,&$methods,$method_id){
    	$method =& $methods[$method_id];
    	$orderObj = null;
    	$orderObj->order_status = $method->payment_params->order_status;
    	$orderObj->order_id = $order->order_id;
    	$orderClass = hikashop_get('class.order');
    	$orderClass->save($orderObj);
    	$app =& JFactory::getApplication();
    	$this->removeCart = true;
		$name = $method->payment_type.'_end.php';
    	$path = JPATH_THEMES.DS.$app->getTemplate().DS.'hikashoppayment'.DS.$name;
    	if(!file_exists($path)){
    		if(version_compare(JVERSION,'1.6','<')){
    			$path = JPATH_PLUGINS .DS.'hikashoppayment'.DS.$name;
    		}else{
    			$path = JPATH_PLUGINS .DS.'hikashoppayment'.DS.$method->payment_type.DS.$name;
    		}
    		if(!file_exists($path)){
    			return true;
    		}
    	}
    	$information = $method->payment_params->information;
    	if(preg_match('#^[a-z0-9_]*$#i',$information)){
    		$information = JText::_($information);
    	}
    	$currencyClass = hikashop_get('class.currency');
    	$amount = $currencyClass->format($order->order_full_price,$order->order_currency_id);
    	$order_number = $order->order_number;
    	require($path);
		return true;
    }

}

Please Log in or Create an account to join the conversation.

  • Posts: 83799
  • Thank you received: 13571
  • MODERATOR
12 years 5 months ago #81070

That's not related to your modification as far as I understand.

It must be something else like if you set restrictions on the product quantities.

Please Log in or Create an account to join the conversation.

  • Posts: 65
  • Thank you received: 0
12 years 5 months ago #81412

You were right - now it seems to work! Thank you!

How can I expand the restriction to more product IDs? Not only the 165 but 3 more..

Thank you!

Kind regards
Carolin

Please Log in or Create an account to join the conversation.

  • Posts: 13201
  • Thank you received: 2322
12 years 5 months ago #81577

You can do like that:

				$hide = 0;
                                $pIds = array('165','166','167');
				foreach($order->products as $product){
					if(in_array($product->product_id, $pIds))
						$hide = 1;
				}
				if($hide == 0)
					$usable_methods[$method->ordering]=$method;

The following user(s) said Thank You: phamosa, daveturner101

Please Log in or Create an account to join the conversation.

Time to create page: 0.090 seconds
Powered by Kunena Forum