Setting a maximum discount amount for promotions on an e-commerce platform is crucial for maintaining profitability and protecting the business's bottom line. It helps to prevent excessive discounting that could erode margins and devalue products. Additionally, it ensures consistency in pricing strategy and prevents potential revenue loss. Moreover, it fosters customer trust by establishing clear and fair discounting practices, enhancing brand reputation and loyalty. Lastly, it enables effective budget management by limiting the financial impact of promotional activities while still incentivizing purchases.
Implementing a "maximum discount amount" customization on core Magento can significantly enhance the platform's flexibility and control over promotional activities. Please follow the below steps to add this feature:
Add a new column on salesrule table using db_schema.xml
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="salesrule">
<column xsi:type="varchar" name="max_discount_amount" length="255" default="0" comment="Maximum Discount Amount"/>
</table>
</schema>
Then add the above column as a field in the cart rule by overriding ui_component: sales_rule_form.xml
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<fieldset name="actions">
<field name="max_discount_amount" formElement="input" sortOrder="2">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="source" xsi:type="string">sales_rule</item>
<item name="notice" xsi:type="string">This is only applicable in case of percent based discount rule.</item>
</item>
</argument>
<settings>
<validation>
<rule name="required-entry" xsi:type="boolean">true</rule>
<rule name="validate-number" xsi:type="boolean">true</rule>
<rule name="validate-zero-or-greater" xsi:type="boolean">true</rule>
</validation>
<dataType>text</dataType>
<label translate="true">Max Discount Amount</label>
<dataScope>max_discount_amount</dataScope>
</settings>
</field>
</fieldset>
</form>
Then we need to create a plugin to add logic for a max_discount_amount
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\SalesRule\Model\Rule\Action\Discount\ByPercent">
<plugin name="max_discount" type="MageInsight\SocialReferral\Plugin\SalesRule\Rule\Action\SetMaxDiscountPlugin" sortOrder="1" disabled="false" />
</type>
</config>
<?php
namespace MageInsight\SocialReferral\Plugin\SalesRule\Rule\Action;
use Magento\Framework\Pricing\PriceCurrencyInterface;
use Magento\SalesRule\Model\Rule\Action\Discount\ByPercent;
use MageInsight\SocialReferral\Helper\Data as SocialReferralHelper;
class SetMaxDiscountPlugin
{
/**
* @var array
*/
public static $maxDiscount = [];
/**
* @var array
*/
private $processedRule = [];
/**
* @var SocialReferralHelper
*/
private $socialReferralHelper;
/**
* @var PriceCurrencyInterface
*/
private $priceCurrency;
public function __construct(
SocialReferralHelper $socialReferralHelper,
PriceCurrencyInterface $priceCurrency
) {
$this->socialReferralHelper = $socialReferralHelper;
$this->priceCurrency = $priceCurrency;
}
public function aroundCalculate(
ByPercent $subject,
callable $proceed,
$rule,
$item,
$qty
) {
$discountData = $proceed($rule, $item, $qty);
if (! $this->socialReferralHelper->isEnabled()) {
return $discountData;
}
$store = $item->getQuote()->getStore();
$itemId = $item->getId();
$cachedKey = $itemId . '_' . $discountData->getBaseAmount();
if (! strlen($rule->getMaxDiscountAmount()) || $rule->getMaxDiscountAmount() < 0.0001) {
return $discountData;
}
if (! isset(self::$maxDiscount[$rule->getId()]) || isset($this->processedRule[$rule->getId()][$cachedKey])) {
self::$maxDiscount[$rule->getId()] = $rule->getMaxDiscountAmount();
$this->processedRule[$rule->getId()] = null;
}
if (self::$maxDiscount[$rule->getId()] - $discountData->getBaseAmount() < 0) {
$convertedPrice = $this->priceCurrency->convert(self::$maxDiscount[$rule->getId()], $store);
$discountData->setBaseAmount(self::$maxDiscount[$rule->getId()]);
$discountData->setAmount($this->priceCurrency->round($convertedPrice));
$discountData->setBaseOriginalAmount(self::$maxDiscount[$rule->getId()]);
$discountData->setOriginalAmount($this->priceCurrency->round($convertedPrice));
self::$maxDiscount[$rule->getId()] = 0;
} else {
self::$maxDiscount[$rule->getId()] =
self::$maxDiscount[$rule->getId()] - $discountData->getBaseAmount();
}
$this->processedRule[$rule->getId()][$cachedKey] = true;
return $discountData;
}
}
Once you complete this process, you will be able to see the field under the Actions section of the "Cart Price Rule" feature.
Comments
Post a Comment