In magento 2 cart page how add a more than one discount
-
12-03-2021 - |
Pergunta
In magento 2 cart page how add a more than one discount
I want be like this:
But i get like this
app/code/Bg/SpecialPromotion/view/frontend/web/js/view/checkout/cart/total/fee.js
define([
'ko',
'uiComponent',
'Magento_Checkout/js/model/quote',
'Magento_Catalog/js/price-utils',
'Magento_Checkout/js/model/totals'
], function (ko, Component, quote, priceUtils, totals) {
'use strict';
var show_hide_Extrafee_blockConfig = window.checkoutConfig.show_hide_Extrafee_block;
var fee_label = window.checkoutConfig.fee_label;
var custom_fee_amount = window.checkoutConfig.custom_fee_amount;
return Component.extend({
totals: quote.getTotals(),
canVisibleExtrafeeBlock: show_hide_Extrafee_blockConfig,
getFormattedPrice: ko.observable(priceUtils.formatPrice(custom_fee_amount, quote.getPriceFormat())),
getFeeLabel:ko.observable(fee_label),
isDisplayed: function () {
return this.getValue() != 0;
},
getValue: function() {
var price = 0;
if (this.totals() && totals.getSegment('fee')) {
price = totals.getSegment('fee').value;
}
return price;
}
});
});
app/code/Bg/SpecialPromotion/view/frontend/template/checkout/cart/total/fee.html
<!-- ko if: isDisplayed() -->
<tr class="totals fee excl" >
<th class="mark" colspan="1" scope="row" data-bind="text: getFeeLabel()"></th>
<td class="amount">
<span class="price" data-bind="text: getFormattedPrice()"></span>
</td>
</tr>
<!-- /ko -->
etc/sales.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Sales:etc/sales.xsd">
<section name="quote">
<group name="totals">
<item name="fee" instance="Bg\SpecialPromotion\Model\Quote\Total\Fee" sort_order="150"/>
</group>
</section>
<section name="order_invoice">
<group name="totals">
<item name="fee" instance="Bg\SpecialPromotion\Model\Invoice\Total\Fee" sort_order="160"/>
</group>
</section>
<section name="order_creditmemo">
<group name="totals">
<item name="fee" instance="Bg\SpecialPromotion\Model\Creditmemo\Total\Fee" sort_order="160"/>
</group>
</section>
</config>
app/code/Bg/SpecialPromotion/Model/Quote/Total/Fee.php
<?php
namespace Bg\SpecialPromotion\Model\Quote\Total;
use Magento\Store\Model\ScopeInterface;
class Fee extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal
{
protected $helperData;
protected $_priceCurrency;
protected $quoteValidator = null;
public function __construct(\Magento\Quote\Model\QuoteValidator $quoteValidator,
\Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
\Bg\SpecialPromotion\Helper\Data $helperData)
{
$this->quoteValidator = $quoteValidator;
$this->_priceCurrency = $priceCurrency;
$this->helperData = $helperData;
}
public function collect(
\Magento\Quote\Model\Quote $quote,
\Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment,
\Magento\Quote\Model\Quote\Address\Total $total
)
{
parent::collect($quote, $shippingAssignment, $total);
if (!count($shippingAssignment->getItems())) {
return $this;
}
// $test = $this->helperData->getExtrafee();
// print_r($test);exit;
$enabled = $this->helperData->isModuleEnabled();
$minimumOrderAmount = $this->helperData->getMinimumOrderAmount();
$subtotal = $total->getTotalAmount('subtotal');
if ($enabled && $minimumOrderAmount <= $subtotal) {
$fee = $this->helperData->getExtrafee();
//Try to test with sample value
// $fee=-50;
$total->setTotalAmount('fee', $fee);
$total->setBaseTotalAmount('fee', $fee);
$total->setFee($fee);
$quote->setFee($fee);
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$productMetadata = $objectManager->get('Magento\Framework\App\ProductMetadataInterface');
$version = (float)$productMetadata->getVersion();
if($version > 2.1)
{
//$total->setGrandTotal($total->getGrandTotal() + $fee);
}
else
{
$total->setGrandTotal($total->getGrandTotal()+$fee);
}
}
return $this;
}
/**
* @param \Magento\Quote\Model\Quote $quote
* @param \Magento\Quote\Model\Quote\Address\Total $total
* @return array
*/
public function fetch(\Magento\Quote\Model\Quote $quote, \Magento\Quote\Model\Quote\Address\Total $total)
{
$enabled = $this->helperData->isModuleEnabled();
$minimumOrderAmount = $this->helperData->getMinimumOrderAmount();
$subtotal = $quote->getSubtotal();
$fee = $quote->getFee();
$result = [];
if ($enabled && ($minimumOrderAmount <= $subtotal) && $fee) {
$result = [
'code' => 'fee',
'title' => $this->helperData->getFeeLabel(),
'value' => $fee
];
}
return $result;
}
/**
* Get Subtotal label
*
* @return \Magento\Framework\Phrase
*/
public function getLabel()
{
return __('Extra Fee');
}
/**
* @param \Magento\Quote\Model\Quote\Address\Total $total
*/
protected function clearValues(\Magento\Quote\Model\Quote\Address\Total $total)
{
$total->setTotalAmount('subtotal', 0);
$total->setBaseTotalAmount('subtotal', 0);
$total->setTotalAmount('tax', 0);
$total->setBaseTotalAmount('tax', 0);
$total->setTotalAmount('discount_tax_compensation', 0);
$total->setBaseTotalAmount('discount_tax_compensation', 0);
$total->setTotalAmount('shipping_discount_tax_compensation', 0);
$total->setBaseTotalAmount('shipping_discount_tax_compensation', 0);
$total->setSubtotalInclTax(0);
$total->setBaseSubtotalInclTax(0);
}
}
app/code/Bg/SpecialPromotion/Helper/Data.php
<?php
namespace Bg\SpecialPromotion\Helper;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Framework\App\Helper\Context;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Store\Model\ScopeInterface;
use Magento\SalesRule\Model\RuleFactory;
use \Magento\Framework\Serialize\Serializer\Json;
use \Magento\SalesRule\Model\Rule;
class Data extends AbstractHelper
{
protected $scopeConfig;
protected $_ruleFactory;
public function __construct(
Context $context,
ScopeConfigInterface $scopeInterface,
RuleFactory $ruleFactory ,
Rule $ruleModel ) {
parent::__construct($context);
$this->scopeConfig = $scopeInterface;
$this->_ruleFactory = $ruleFactory;
$this->ruleModel=$ruleModel;
}
public function isModuleEnabled()
{
return 1;
}
public function getMinimumOrderAmount()
{
return 1;
}
public function getExtrafee()
{
$amount = $this->getFinalRule();
$amt = array();
foreach ($amount as $key => $value) {
$amt[] = $value['amount'];
}
$sum_of_amount = array_sum($amt);
return $sum_of_amount;
}
public function getFeeLabel()
{
$name = $this->getFinalRule();
$label = array();
foreach ($name as $key => $value) {
$label[] = $value['name'];
}
// $label = 'Special Discount';
return $label;
}
public function getFinalRule()
{
$activeRule = $this->getActiveRule();
$result =array();
$rule_info = array();
foreach ($activeRule as $key => $rule) {
$id = $rule['rule_id'];
$action = $rule['simple_action'];
$name = $rule['description'];
$discount_amount = $rule['discount_amount'];
$max_discount = $rule['max_discount'];
$discount_qty = $rule['discount_qty'];
$discount_step = $rule['discount_step'];
$priceselector = $rule['priceselector'];
$apply_discount_to =$rule['apply_discount_to'];
// $apply_to_shipping = $rule['apply_to_shipping'];
// $stop_rules_processing = $rule[' stop_rules_processing'];
switch($action){
case "thecheapest":
$cartItem = $this->getCartItem();
$amt = array();
foreach ($cartItem as $key => $item) {
$qty = $item->getQty();
if($qty >= 2)
{
if($priceselector == 0)
{
$price = $item->getProduct()->getFinalPrice();
}
else if($priceselector == 2)
{
$price = $item->getProduct()->getPrice();
}
else
{
$price = $item->getProduct()->getFinalPrice();
}
if(($qty%2==0))
{
$x_product = ($qty/2);
$final_amt = ($price * $x_product);
$amt[] = $final_amt;
}
else
{
$x_odd = $qty - 1;
$x_product = ($x_odd/2);
$final_amt = (($price * $x_product));
$amt[] = $final_amt;
}
}
}
$amount = array_sum($amt);
$finalDiscount = -$amount;
$rule_info[]= [
'name' => $name,
'amount'=> $finalDiscount,
];
break;
case "moneyamount":
$cartTotal = $this->getCartTotal();
if($cartTotal >= $discount_step)
{
$get_x = $cartTotal/$discount_step;
$lower_round_off = floor($get_x);
$final_amt = $lower_round_off * $discount_amount;
}
else
{
$final_amt =0;
}
$finalDiscount = -$final_amt;
$rule_info[] = [
'name' => $name,
'amount'=> $finalDiscount,
];
break;
} // end of swich case
} // end of for loop
return $rule_info;
}
}
Solução
Try to get additional fee from config provider
app/code/Bg/SpecialPromotion/Helper/Data.php
<?php
namespace Bg\SpecialPromotion\Helper;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Framework\App\Helper\Context;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Store\Model\ScopeInterface;
use Magento\SalesRule\Model\RuleFactory;
use \Magento\Framework\Serialize\Serializer\Json;
use \Magento\SalesRule\Model\Rule;
class Data extends AbstractHelper
{
protected $scopeConfig;
protected $_ruleFactory;
protected $ruleModel;
public function __construct(
Context $context,
ScopeConfigInterface $scopeInterface,
RuleFactory $ruleFactory ,
Rule $ruleModel
) {
parent::__construct($context);
$this->scopeConfig = $scopeInterface;
$this->_ruleFactory = $ruleFactory;
$this->ruleModel=$ruleModel;
}
public function isModuleEnabled()
{
return true;
}
public function getMinimumOrderAmount()
{
return true;
}
public function getExtrafee()
{
$amount = $this->getFinalRule();
$amt = array();
foreach ($amount as $key => $value) {
$amt[] = $value['amount'];
}
$sum_of_amount = array_sum($amt);
return $sum_of_amount;
}
public function getFeeLabel()
{
$name = $this->getFinalRule();
$label = array();
foreach ($name as $key => $value) {
$label[] = $value['name'];
}
// $label = 'Special Discount';
return $label;
}
public function getShippingPrices()
{
$data = $this->getFinalRule();
$shippingData = array();
foreach ($data as $key => $value) {
$shippingData[$key] = [
'title' => $value['name'],
'value'=> $value['amount']
];
}
return $shippingData;
}
public function getFinalRule()
{
$activeRule = $this->getActiveRule();
$result =array();
$rule_info = array();
foreach ($activeRule as $key => $rule) {
$id = $rule['rule_id'];
$action = $rule['simple_action'];
$name = $rule['description'];
$discount_amount = $rule['discount_amount'];
$max_discount = $rule['max_discount'];
$discount_qty = $rule['discount_qty'];
$discount_step = $rule['discount_step'];
$priceselector = $rule['priceselector'];
$apply_discount_to = $rule['apply_discount_to'];
//$apply_to_shipping = $rule['apply_to_shipping'];
//$stop_rules_processing = $rule[' stop_rules_processing'];
switch($action){
case "thecheapest":
$cartItem = $this->getCartItem();
$amt = array();
foreach ($cartItem as $key => $item) {
$qty = $item->getQty();
if($qty >= 2) {
if($priceselector == 0) {
$price = $item->getProduct()->getFinalPrice();
} else if($priceselector == 2) {
$price = $item->getProduct()->getPrice();
} else {
$price = $item->getProduct()->getFinalPrice();
}
if(($qty%2==0)) {
$x_product = ($qty/2);
$final_amt = ($price * $x_product);
$amt[] = $final_amt;
} else {
$x_odd = $qty - 1;
$x_product = ($x_odd/2);
$final_amt = (($price * $x_product));
$amt[] = $final_amt;
}
}
}
$amount = array_sum($amt);
$finalDiscount = -$amount;
$rule_info[]= [
'name' => $name,
'amount'=> $finalDiscount
];
break;
case "moneyamount":
$cartTotal = $this->getCartTotal();
if($cartTotal >= $discount_step) {
$get_x = $cartTotal/$discount_step;
$lower_round_off = floor($get_x);
$final_amt = $lower_round_off * $discount_amount;
} else {
$final_amt =0;
}
$finalDiscount = -$final_amt;
$rule_info[] = [
'name' => $name,
'amount'=> $finalDiscount,
];
break;
} // end of swich case
} // end of for loop
return $rule_info;
}
}
app/code/Bg/SpecialPromotion/Model/ExtrafeeConfigProvider.php
<?php
namespace Bg\SpecialPromotion\Model;
use Magento\Checkout\Model\ConfigProviderInterface;
class ExtrafeeConfigProvider implements ConfigProviderInterface
{
/**
* @var \Magecomp\Extrafee\Helper\Data
*/
protected $dataHelper;
/**
* @var \Magento\Checkout\Model\Session
*/
protected $checkoutSession;
/**
* @var \Psr\Log\LoggerInterface
*/
protected $logger;
/**
* @param \Bg/SpecialPromotion\Helper\Data $dataHelper
* @param \Magento\Checkout\Model\Session $checkoutSession
* @param \Psr\Log\LoggerInterface $logger
*/
public function __construct(
\Bg\SpecialPromotion\Helper\Data $dataHelper,
\Magento\Checkout\Model\Session $checkoutSession,
\Psr\Log\LoggerInterface $logger
) {
$this->dataHelper = $dataHelper;
$this->checkoutSession = $checkoutSession;
$this->logger = $logger;
}
/**
* @return array
*/
public function getConfig()
{
$ExtrafeeConfig = [];
$enabled = $this->dataHelper->isModuleEnabled();
$minimumOrderAmount = $this->dataHelper->getMinimumOrderAmount();
$ExtrafeeConfig['fee_label'] = $this->dataHelper->getFeeLabel();
$quote = $this->checkoutSession->getQuote();
$subtotal = $quote->getSubtotal();
$ExtrafeeConfig['custom_fee_amount'] = $this->dataHelper->getExtrafee();
$ExtrafeeConfig['custom_shipping'] = $this->dataHelper->getShippingPrices();
$ExtrafeeConfig['show_hide_Extrafee_block'] = ($enabled && ($minimumOrderAmount <= $subtotal) && $quote->getFee()) ? true : false;
$ExtrafeeConfig['show_hide_Extrafee_shipblock'] = ($enabled && ($minimumOrderAmount <= $subtotal)) ? true : false;
return $ExtrafeeConfig;
}
}
app/code/Bg/SpecialPromotion/view/frontend/web/js/view/checkout/cart/total/fee.js
define([
'ko',
'uiComponent',
'Magento_Checkout/js/model/quote',
'Magento_Catalog/js/price-utils',
'Magento_Checkout/js/model/totals'
], function (ko, Component, quote, priceUtils, totals) {
'use strict';
var show_hide_Extrafee_blockConfig = window.checkoutConfig.show_hide_Extrafee_block;
var fee_label = window.checkoutConfig.fee_label;
var custom_fee_amount = window.checkoutConfig.custom_fee_amount;
var custom_shipping = window.checkoutConfig.custom_shipping;
return Component.extend({
totals: quote.getTotals(),
canVisibleExtrafeeBlock: show_hide_Extrafee_blockConfig,
getFormattedPrice: ko.observable(priceUtils.formatPrice(custom_fee_amount, quote.getPriceFormat())),
getFeeLabel:ko.observable(fee_label),
isDisplayed: function () {
return this.getValue() != 0;
},
getValue: function() {
var price = 0;
if (this.totals() && totals.getSegment('fee')) {
price = totals.getSegment('fee').value;
}
return price;
},
rawHtml: function() {
var $html = '';
_.each(custom_shipping, function (item) {
$html += '<tr class="totals fee excl" >';
$html += '<th class="mark" colspan="1" scope="row">'+item.title+'</th>';
$html += '<td class="amount">';
$html += '<span class="price">'+priceUtils.formatPrice(item.value)+'</span>';
$html += '</td>';
$html += '</tr>';
});
return $html;
}
});
});
app/code/Bg/SpecialPromotion/view/frontend/template/checkout/cart/total/fee.html
<!-- ko if: isDisplayed() -->
<tr data-bind="html: rawHtml()"></tr>
<!-- /ko -->
Have tested in my local env, try to code like Magento zendframework format. Your code is not aligned properly. And add comments before every function like ExtrafeeConfigProvider.php file. Happy coding :-)