Hide Specified Payment method if stock is below threshold - prestashop-1.7

I want to disable a card payment method if a product has the stock below a threshold or is 0 because i have a lot of products that can be put on backorder but i don't want to allow payment by debit or credit card because there have been a lot of clients that canceled the order and payment after placing the order even if it was clearly stated that the product is on backorder.
Does anyone have any idea how i could do that ?

I'd suggest edit or override of hookPaymentOption in your module.
Check for $this->context->cart->getProducts(), loop through products and if there's something wrong just return;

This is the solution i used after to suggestion from Krystian Podemski
$products = $this->context->cart->getProducts();
foreach($products as $product){
//var_dump($product);
if($product['quantity_available'] == 0){
return;
}
}

Related

Magento: Is Tablerate Shipping based on the cart sum with or without taxes?

I have a Shop with Products that have different Taxrates. Some have 0%, some 19% etc...
For Shipping im using Tablerates, for example:
up to 2000€ = 10€ shipping cost
up to or over 2400€ = 15€ shipping cost
Now comes the thing that at first i just want to understand, so there is not really a bug to fix here. I just need to know how it works to plan my tablerates accordingly.
I have orders with a total over 2400€ (incl. Tax), but the customer still gets the 10€ Shipping rate. This can only be if the System is using the Price without Tax to check against the table rates. Because only then would the price be in the Tablerate range for the lower rate. And yes i double checked the Tablerates Setup (not my first Magento Install).
1) Is this assumption correct that table rates are checked against the total without taxes?
2) Is there a way to set up tablerates to check against the cart total including taxes?
Anyone got any info on how that works in the background? I couldnt find anything as when youre searching the topic you mostly get tutorial on how to set up table rates.
Super thankful for any tipps or maybe other threads or places i could check for detailed infos on how that works.
note: i use Magento 1.9.2.1
For Question 1:
It would appear to be without tax.
Mage_Shipping_Model_Shipping::collectRatesByAddress calls setPackageValue to set the package value for the rate request.
This gets passed to Mage_Shipping_Model_Carrier_Tablerate::collectRates.
collectRates subtracts free shipping from the package value.
Then Mage_Shipping_Model_Carrier_Tablerate::getRate is called
$result = Mage::getModel('shipping/rate_result');
$rate = $this->getRate($request);
...
public function getRate(Mage_Shipping_Model_Rate_Request $request)
{
return Mage::getResourceModel('shipping/carrier_tablerate')->getRate($request);
}
This calls Mage_Shipping_Model_Resource_Carrier_Tablerate::getRate which binds the condition value to the query. (The condition name should be package_value in your case).
// Render condition by condition name
if (is_array($request->getConditionName())) {
$orWhere = array();
$i = 0;
foreach ($request->getConditionName() as $conditionName) {
$bindNameKey = sprintf(':condition_name_%d', $i);
$bindValueKey = sprintf(':condition_value_%d', $i);
$orWhere[] = "(condition_name = {$bindNameKey} AND condition_value <= {$bindValueKey})";
$bind[$bindNameKey] = $conditionName;
$bind[$bindValueKey] = $request->getData($conditionName);
$i++;
}
if ($orWhere) {
$select->where(implode(' OR ', $orWhere));
}
} else {
$bind[':condition_name'] = $request->getConditionName();
$bind[':condition_value'] = $request->getData($request->getConditionName());
$select->where('condition_name = :condition_name');
$select->where('condition_value <= :condition_value');
}
While it is possible to modify the order, baseSubtotal should be before tax.
See collectRatesByAddress:
$request->setBaseSubtotalInclTax($address->getBaseSubtotalInclTax()
+ $address->getBaseExtraTaxAmount());
As for your question 2.
As noted above, we have the data in the request, but we do not have an easy touchpoint.
One suggestion is to rewrite the Mage_Shipping_Model_Carrier_Tablerate and override getRate. What you would do would be to set the BaseSubtotal to the BaseSubtotalInclTax, call parent, then reset the request.
public function getRate(Mage_Shipping_Model_Rate_Request $request)
{
// TODO: wrap in try catch, to reset the value ??
// TODO: clone the request ??
// TODO: Test This
$oldPackageValue = $request->getPackageValue();
$request->setPackageValue($request->getBaseSubtotalInclTax());
$returnvalue = Mage::getResourceModel('shipping/carrier_tablerate')->getRate($request);
$request->setPackageValue($oldPackageValue);
return $returnvalue;
}
This is hacky, but minimally intrusive. It should withstand unrelated changes without forcing you to modify the code.
Another method involves rewriting and modifying Mage_Shipping_Model_Resource_Carrier_Tablerate::getRate to use the value you want.
NOTE: Neither of these methods are tested.

Enable/disable cash-on-delivery only for some specific products

I want to disable cash on delivery payment method option for some specific products. I want to show cash on delivery method only for specific products and need to hide other payment options.
How can I do this? I read
this other question but it did not solve my problem.
you can use following free extension to solve your problem
http://www.magentocommerce.com/magento-connect/shipping-and-payment-filters.html
Using payment_method_is_active observer you could load the current checkout session quote and check what city the order is be shipped to.
$checkout = Mage::getSingleton('checkout/session')->getQuote();
$shipping = $checkout->getShippingAddress();
$cashOnDeliveryCities = array('city name 1','city name 2',..)
if(in_array($shipping->getCity(), $cashOnDeliveryCities)){
$result->isAvailable = true;
}else{
$result->isAvailable = false;
}
Here's how to do it without an extension.
Just go to admin > per motions > Shopping Cart Price Rule and create rules for this "cash on delivery payment method option for some specific products".
First in conditions select payment method "COD" in options. After that in "Action" add product SKU, for multiple using add SKU by comma. Activate the rule and check your payment method for those products to ensure it's working.

How to disable products that are not assigned to a category?

Could someone assist with this issue I am having please... I need to disable all products that are not assigned to a category in Magento but the problem is there are some 10,000+ products that I will need to sort through.
I would like to ask what the best approach would be so I could at least begin to solve the problem.
Would it be possible to set all products to disabled if they are not assigned to a category using an Observer? Should I echo the list of unassigned products in a loop then set the status to disabled...
I'm not sure how to go about this one...
Best way to do this is using Magento collections.
Create a new PHP file, include Mage.php, initialize the application and make your changes.
It might take a while depending on product count.
I think you want to do something like that:
require_once('../app/Mage.php');
Mage::init();
$product = Mage::getModel('catalog/product')->getCollection()->addAttributeToSelect('*');
$store_id = 1;
foreach ($product as $prod)
{
if ($prod->getCategoryIds() == NULL)
{
Mage::getModel('catalog/product_status')
->updateProductStatus($prod->getId(), $store_id, Mage_Catalog_Model_Product_Status::STATUS_DISABLED);
}
}

Sending POST data from Codeigniter controller

I am currently developing a small shopping cart where payment options are cash on delivery and other prepaid payment options using a payment gateway. Now my cart's flow chart is like
Places order,enters address
Selects payment options ( COD or Prepaid )
If COD confirm order
If prepaid, redirect to the payment gateway page
So when the customer selects an option , the controller function handlePayment() checks if its COD or Prepaid. If its COD it shows a view page, or if its prepaid, it should redirect to the payment gateway with all necessary data in POST.
So how will I be able to accomplish this task?
You have to write if COD then $this->view->load('pagename); else you have to call another function $this->functionname($_POST);
Try this, Its a rough assumption of what you need:
function handlePayment(){
if($this->input->post('type') == "COD"){
$data = array();
$data = $this->input->post(null);
$this->load->view('cod', $data);
}else if($this->input->post('type') == "prepaid"){
$data = array();
$data = $this->input->post(null);
$this->prepaidPayment($data);
}
}
function prepaidPayment($data){
//do something with the data which contains all the post variables
}
different angle -- can you ask them the COD or Prepaid question -- first?
and then make each 'path' completely separate.
Long term that could be better for your application especially if it grows.
and might help if you can do more stringent form validation on the Prepaid track,
( like if some of that information is used as part of the credit card validation )
versus COD where the payment happens in person

Magento - How to add multiple items to the cart programmatically?

I'm trying to add multiple simple products to the cart at the same time using a query string as below, however it only adds the last product to the cart instead of both:
Can someone let me know what I'm doing wrong?
http://www.domain.co.uk/checkout/cart/add?product=9916&qty=4&product=15749&qty=4
I have also tried this:
http://www.domain.co.uk/checkout/cart/add?product[]=9916&qty[]=4&product[]=15749&qty[]=4
Any help much appreciated!
Add Product To Cart With Querystring
Add simple product in shopping cart with no attribute.
http://yourserver.com/checkout/cart/add?product=PRODUCT_ID&qty=PRODUCT_QUANTITY
Here PRODUCT_ID = 'Product Id',PRODUCT_QUANTITY = 'product quantity to purchase'.
Add product into shopping cart with single custome option.
http://yourserver.com/checkout/cart/add?product=PRODUCT_ID&qty=PRODUCT_QUANTITY&super_attribute[OPTION_ID]=OPTION_VALUE
Here OPTION_ID = 'Custom attribute option id',OPTION_VALUE = 'Custom attribute option value'.
Add product into shopping cart with multipal custome option.
http://yourserver.com/checkout/cart/add?product=PRODUCT_ID&qty=PRODUCT_QUANTITY&super_attribute[OPTION_ID_1]=OPTION_VALUE_1&super_attribute[OPTION_ID_2]=OPTION_VALUE_2
Here OPTION_ID_1 & OPTION_ID_1 = 'Custom attribute option ids',OPTION_VALUE_1 & OPTION_VALUE_2 = 'Custom attribute option values'.Here add more options in `super_attribute` array
Add Extra products with mail product with only 1 quantity.
http://yourserver.com/checkout/cart/add?product=PRODUCT_ID&qty=PRODUCT_QUANTITY&related_product=PRODUCT_ID_1,PRODUCT_ID_2
Here PRODUCT_ID_1 and PRODUCT_ID_2 is other products id. add more product by id using `,` separator. Example:- &related_product=1,2,3,4.
Default magento there is not setting for add related product quantity into cart.so if you want to add this code than open app/code/core/Mage/Checkout/controllers/CartController.php find public function addAction().
if (!empty($related)) {
$cart->addProductsByIds(explode(',', $related));
}
Replace with
$rel_qty = $this->getRequest()->getParam('related_qty');
if (!empty($related)) {
$relatedproducts = explode(',', $related);
$relatedqtys = explode(',',$rel_qty);
$i = 0;
foreach($relatedproducts as $relatedproduct)
{
$cart->addProduct($relatedproduct, array('qty'=>$relatedqtys[$i]));
$i++;
}
}
Now use query string for add related products with quantity.
http://yourserver.com/cart/add?product=PRODUCT_ID&qty=PRODUCT_QUANTITY&related_product=PRODUCT_ID_1,PRODUCT_ID_2&related_qty=PRODUCT_ID_1_QUANTITY,PRODUCT_ID_2_QUANTITY
If you don't want to change any code, you can try to utilize related products functionality by adding related_product parameter to your request. So your url will look like this:
http://www.domain.co.uk/checkout/cart/add?product=9916&qty=4&related_product=15749
If you want to add more products, just list them with comma separator: related_product=1,2,3
The only drawback from that is that you actually can't specify the qty for related products.
To see how it works - Mage_Checkout_Model_Cart::addProductsByIds(array_of_ids)
If qty for subsequent products is a mandatory for you, you'll need to create your own controller, or override the Mage_Checkout_CartController::addAction method.
I found a cheeky way I found of getting around the quantity limitation of the related_products query string field noted above in other answers. If you just put the SAME ID MULTIPLE TIMES in the value of related_products, as many times as the quantity you need, then that will achieve the same effect as if there was an explicit qty field for each related product. So taking himansu's answer above and adapting it we get:
http://yourserver.com/checkout/cart/add?product=PRODUCT_ID&qty=PRODUCT_QUANTITY&related_product=PRODUCT_ID_1,PRODUCT_ID_1,PRODUCT_ID_1,PRODUCT_ID_2,PRODUCT_ID_2
This will add to the cart PRODUCT_QUANTITY of PRODUCT_ID, 3 of PRODUCT_ID_1, and 2 of PRODUCT_ID_2.
So as long as you're happy doing a little work to generate the same ID multiple times this works a treat. And no custom code changes required on your magento server.

Resources