Magento provides by default Discount using shopping cart price rule. I want to create the same rule to Add Extra fee in this discount rule.
I have added one extra field(extrafee) in salesrule table in database same as discount amount, but have no idea for how to add the extra charge of given field value and which file to override.
I have followed his extension based on Shopping Cart Price Rule functionality.
It is in Magento 1 but I tried to build same functionality in Magento 2 but in middle of developing I got stuck when I was trying to override model files as I am not finding functions in Magento 2 please help me
My model sales rule validator file
public function process(AbstractItem $item)
{
$item->setExtraFeeRuleAmount(0);
$item->setBaseExtraFeeRuleAmount(0);
$item->setExtraFeeRulePercent(0);
$quote = $item->getQuote();
$address = $this->_getAddress($item);
$itemPrice = $this->_getItemPrice($item);
$baseItemPrice = $this->_getItemBasePrice($item);
if ($itemPrice < 0) {
return $this;
}
$appliedRuleIds = array();
$this->_stopFurtherRules = false;
foreach ($this->_getRules() as $rule) {
if (!$this->_isRuleApplicableForItem($rule, $item)) {
continue;
}
$qty = $this->_getItemQty($item, $rule);
$extraFeeAmount = 0;
$baseExtraFeeAmount = 0;
switch ($rule->getSimpleAction()) {
case \Magento\SalesRule\Model\Rule::BY_PERCENT_ACTION:
$extraFeePercent = min(100, $rule->getExtraFeeAmount());
$step = $rule->getDiscountStep();
if ($step) {
$qty = floor($qty/$step)*$step;
}
$_rulePct = $extraFeePercent/100;
$extraFeeAmount = ($qty * $itemPrice - $item->getExtraFeeRuleAmount()) * $_rulePct;
$baseExtraFeeAmount = ($qty * $baseItemPrice - $item->getBaseExtraFeeRuleAmount()) * $_rulePct;
if (!$rule->getDiscountQty() || $rule->getDiscountQty()>$qty) {
$extraFeePercent = min(100, $item->getExtraFeeRulePercent()+$extraFeePercent);
$item->setExtraFeeRulePercent($extraFeePercent);
}
break;
case \Magento\SalesRule\Model\Rule::BY_FIXED_ACTION:
$step = $rule->getDiscountStep();
if ($step) {
$qty = floor($qty/$step)*$step;
}
$quoteAmount = $quote->getStore()->convertPrice($rule->getExtraFeeAmount());
$extraFeeAmount = $qty * $quoteAmount;
$baseExtraFeeAmount = $qty * $rule->getExtraFeeAmount();
break;
case \Magento\SalesRule\Model\Rule::CART_FIXED_ACTION:
if (empty($this->_rulesItemTotals[$rule->getId()])) {
throw new \Magento\Framework\Exception\LocalizedException(Mage::helper('salesrule')->__('Item totals are not set for rule.'));
}
/**
* prevent applying whole cart discount for every shipping order, but only for first order
*/
if ($quote->getIsMultiShipping()) {
$usedForAddressId = $this->getCartFixedRuleUsedForAddress($rule->getId());
if ($usedForAddressId && $usedForAddressId != $address->getId()) {
break;
} else {
$this->setCartFixedRuleUsedForAddress($rule->getId(), $address->getId());
}
}
$cartRules = $address->getCartFixedRules();
if (!isset($cartRules[$rule->getId()])) {
$cartRules[$rule->getId()] = $rule->getExtraFeeAmount();
}
if ($cartRules[$rule->getId()] > 0) {
if ($this->_rulesItemTotals[$rule->getId()]['items_count'] <= 1) {
$quoteAmount = $quote->getStore()->convertPrice($cartRules[$rule->getId()]);
$baseExtraFeeAmount= $cartRules[$rule->getId()];
} else {
$discountRate = $baseItemPrice * $qty /
$this->_rulesItemTotals[$rule->getId()]['base_items_price'];
$maximumItemDiscount = $rule->getExtraFeeAmount() * $discountRate;
$quoteAmount = $quote->getStore()->convertPrice($maximumItemDiscount);
$baseExtraFeeAmount = $maximumItemDiscount;
$this->_rulesItemTotals[$rule->getId()]['items_count']--;
}
$extraFeeAmount = $quoteAmount;
$extraFeeAmount = $quote->getStore()->roundPrice($extraFeeAmount);
$baseExtraFeeAmount = $quote->getStore()->roundPrice($baseExtraFeeAmount);
$cartRules[$rule->getId()] -= $baseExtraFeeAmount;
}
$address->setCartFixedRules($cartRules);
break;
}
$percentKey = $item->getExtraFeeRulePercent();
/**
* Process "delta" rounding
*/
if ($percentKey) {
$delta = isset($this->_roundingDeltas[$percentKey]) ? $this->_roundingDeltas[$percentKey] : 0;
$baseDelta = isset($this->_baseRoundingDeltas[$percentKey])
? $this->_baseRoundingDeltas[$percentKey]
: 0;
$extraFeeAmount += $delta;
$baseExtraFeeAmount += $baseDelta;
$this->_roundingDeltas[$percentKey] = $extraFeeAmount -
$quote->getStore()->roundPrice($extraFeeAmount);
$this->_baseRoundingDeltas[$percentKey] = $baseExtraFeeAmount -
$quote->getStore()->roundPrice($baseExtraFeeAmount);
$extraFeeAmount = $quote->getStore()->roundPrice($extraFeeAmount);
$baseExtraFeeAmount = $quote->getStore()->roundPrice($baseExtraFeeAmount);
} else {
$extraFeeAmount = $quote->getStore()->roundPrice($extraFeeAmount);
$baseExtraFeeAmount = $quote->getStore()->roundPrice($baseExtraFeeAmount);
}
/**
* We can't use row total here because row total not include tax
* Discount can be applied on price included tax
*/
$itemExtraFeeRuleAmount = $item->getExtraFeeRuleAmount();
$itemBaseExtraFeeRuleAmount = $item->getBaseExtraFeeRuleAmount();
$extraFeeAmount = $itemExtraFeeRuleAmount + $extraFeeAmount;
$baseExtraFeeAmount = $itemBaseExtraFeeRuleAmount + $baseExtraFeeAmount;
$item->setExtraFeeRuleAmount($extraFeeAmount);
$item->setBaseExtraFeeRuleAmount($baseExtraFeeAmount);
$appliedRuleIds[$rule->getRuleId()] = $rule->getRuleId();
$this->_maintainAddressCouponCode($address, $rule);
$this->_addDiscountDescription($address, $rule);
if ($rule->getStopRulesProcessing()) {
$this->_stopFurtherRules = true;
break;
}
}
$item->setAppliedRuleIds(join(',',$appliedRuleIds));
$address->setAppliedRuleIds($this->mergeIds($address->getAppliedRuleIds(), $appliedRuleIds));
$quote->setAppliedRuleIds($this->mergeIds($quote->getAppliedRuleIds(), $appliedRuleIds));
return $this;
}