As per the answer from here I have created an event for salesrule_validator_process and the code is below.
class CustomCartPriceRules implements ObserverInterface {
public function __construct() {
}
/**
*
* @param \Magento\Framework\Event\Observer $observer
* @return void
*/
public function execute(\Magento\Framework\Event\Observer $observer) {
$result = $observer->getEvent()->getResult();
$item = $observer->getEvent()->getItem();
$rule = $observer->getEvent()->getRule();
$address = $observer->getEvent()->getAddress();
$qty = $item->getQty();
if ($rule->getData('name') == 'Buy 2 get 1 free'):
// overriding magento rules here and updating Almusbah Offer
$result->setAmount(0)
->setBaseAmount(0)
->setOriginalAmount(0)
->setBaseOriginalAmount(0);
$item->setDiscountPercent(0);
$products = [];
$z = 0;
$totalQty = 0;
$dA = 0;
foreach ($address->getAllItems() as $q):
$validate = $rule->getActions()->validate($q);
if ($validate):
$products[$z]['sku'] = $q->getData('sku');
$products[$z]['qty'] = $q->getData('qty');
$totalQty += $q->getData('qty');
$products[$z]['totalQty'] = $totalQty;
$freeQty = (int) ($totalQty / 3);
$products[$z]['freeQty'] = $freeQty;
if ($products[$z]['freeQty'] > 0):
$products[$z]['applyDiscount'] = 1;
$dicountPercent = 100;
$dA = ($products[$z]['freeQty'] * $q->getData('calculation_price'));
$products[$z]['discountAmount'] = $dA;
$totalQty -= 3*$products[$z]['freeQty']; // appying on each 3 items
endif;
$z++;
endif;
endforeach;
//echo '<pre>';print_r($products);exit;
$chkCurrentSku = $item->getSku();
foreach ($products as $p):
if(isset($p['applyDiscount']) && !empty($p['applyDiscount']) && $chkCurrentSku == $p['sku']):
$discountAmount = $p['discountAmount'];
$fullDiscount = 100;
$item->setDiscountPercent($fullDiscount);
$this->almusbahBuy2Get1Offer($discountAmount,$result);
endif;
endforeach;
endif;
}
public function almusbahBuy2Get1Offer($discountAmount, $result) {
$result->setAmount($discountAmount)
->setBaseAmount($discountAmount)
->setOriginalAmount($discountAmount)
->setBaseOriginalAmount($discountAmount);
}
}
My admin configuration is as follows.
When I add 2 items to the product with product A 4 qty and B with 2 qty.Where B is cheaper than A.So B should be free for 4 products of A.Instead one product from A and one from B are added into discount.
See the screenshot below.
In this case products with price 14 and qty 2 should be added as discounted instead of 1 from 14 and another of 145.
Can someone please help how I can add the cheaper product as discounted in the above code?