1

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;
}
1
  • How are you overriding model. Better if you can share the code.
    – Gagan
    Sep 13, 2018 at 7:18

1 Answer 1

1

If you want free extension for extra fee than you can check this out:

Magento 2 Extra Fee

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.