浏览文章
文章信息
Magento2 一个完整的自定义折扣
12992
定义折扣sales.xml
<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="merge_shipping_discount" instance="Aiweline\CategoryProductOrderMerger\Model\Quote\MergeDiscount" sort_order="500"/>
</group>
</section>
</config>代码:MergeDiscount.php
<?php
/**
* 文件信息
* 作者:邹万才
* 网名:秋风雁飞(可以百度看看)
* 网站:www.aiweline.com/bbs.aiweline.com
* 工具:PhpStorm
* 日期:2020/10/17
* 时间:14:41
* 描述:此文件源码由Aiweline(秋枫雁飞)开发,请勿随意修改源码!
*/
namespace Aiweline\CategoryProductOrderMerger\Model\Quote;
use Aiweline\CategoryProductOrderMerger\Helper\Data;
use Aiweline\CategoryProductOrderMerger\Model\CheckManagement;
class MergeDiscount extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal
{
/**
* Discount calculation object
*
* @var \Magento\SalesRule\Model\Validator
*/
protected $calculator;
/**
* Core event manager proxy
*
* @var \Magento\Framework\Event\ManagerInterface
*/
protected $eventManager = null;
/**
* @var \Magento\Store\Model\StoreManagerInterface
*/
protected $storeManager;
/**
* @var \Magento\Framework\Pricing\PriceCurrencyInterface
*/
protected $priceCurrency;
/**
* @var Data
*/
private $data;
/**
* @var \Magento\Directory\Model\CurrencyFactory
*/
private $currencyFactory;
/**
* @param Data $data
* @param \Magento\Framework\Event\ManagerInterface $eventManager
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
* @param \Magento\SalesRule\Model\Validator $validator
* @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency
*/
public function __construct(
Data $data,
\Magento\Framework\Event\ManagerInterface $eventManager,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\SalesRule\Model\Validator $validator,
\Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
\Magento\Directory\Model\CurrencyFactory $currencyFactory
)
{
$this->setCode('merge_shipping_discount');
$this->eventManager = $eventManager;
$this->calculator = $validator;
$this->storeManager = $storeManager;
$this->priceCurrency = $priceCurrency;
$this->data = $data;
$this->currencyFactory = $currencyFactory;
}
/**
* Collect address discount amount
*
* @param \Magento\Quote\Model\Quote $quote
* @param \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment
* @param \Magento\Quote\Model\Quote\Address\Total $total
* @return $this
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
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 (!$quote->getCustomerId()) return $this;
$discountAmount = -floatval($quote->getData('check_merge') ? $quote->getShippingAddress()->getShippingAmount() : 0);
$baseDiscountAmount = $this->convertPrice($discountAmount);
$quote->getShippingAddress()->setShippingDiscountAmount($discountAmount);
$quote->setData('merge_origin_shipping_amount', $discountAmount);
if ($this->data->isEnabled() && $discountAmount) {
$label = $this->data->getMergeDiscountLabel();
if ($total->getDiscountDescription()) {
// If a discount exists in cart and another discount is applied, the add both discounts.
$appliedCartDiscount = $total->getDiscountAmount();
$discountAmount = $total->getDiscountAmount() + $discountAmount;
$label = $total->getDiscountDescription() . ', ' . $label;
}
$total->setDiscountDescription($label);
$total->setDiscountAmount($discountAmount);
$total->setBaseDiscountAmount($baseDiscountAmount);
$total->setSubtotalWithDiscount($total->getSubtotalWithDiscount() + $discountAmount);
$total->setBaseSubtotalWithDiscount($total->getBaseSubtotal() + $baseDiscountAmount);
if (isset($appliedCartDiscount)) {
$total->addTotalAmount($this->getCode(), $discountAmount - $appliedCartDiscount);
$total->addBaseTotalAmount($this->getCode(), $baseDiscountAmount - $appliedCartDiscount);
} else {
$total->addTotalAmount($this->getCode(), $discountAmount);
$total->addBaseTotalAmount($this->getCode(), $baseDiscountAmount);
}
}
return $this;
}
/**
* 货币价格转化
*
* @param $amountValue
* @param null $current_currency_code
* @param null $base_currency
* @return float
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function convertPrice($amountValue, $current_currency_code = null, $base_currency = null)
{
$current_currency_code = $current_currency_code ?? $currentCurrency = $this->storeManager->getStore()->getCurrentCurrency()->getCode();
$base_currency = $base_currency ?? $baseCurrency = $this->storeManager->getStore()->getBaseCurrency()->getCode();
if ($current_currency_code != $base_currency) {
$rate = $this->currencyFactory->create()->load($current_currency_code)->getAnyRate($base_currency);
$amountValue = $amountValue * $rate;
}
return $amountValue;
}
/**
* Add discount total information to address
*
* @param \Magento\Quote\Model\Quote $quote
* @param \Magento\Quote\Model\Quote\Address\Total $total
* @return array|null
*/
public function fetch(\Magento\Quote\Model\Quote $quote, \Magento\Quote\Model\Quote\Address\Total $total)
{
$result = null;
if ($this->data->isEnabled() && $amount = $quote->getData('merge_origin_shipping_amount')) {
// ONLY return 1 discount. Need to append existing
//see app/code/Magento/Quote/Model/Quote/Address.php
$description = $total->getDiscountDescription();
$result = [
'code' => $this->getCode(),
'title' => strlen($description) ? __('Discount (%1)', $description) : __('Discount'),
'value' => $amount
];
}
return $result;
}
}