浏览文章

文章信息

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;
   }
}


原创