繁体   English   中英

Magento 2.4.4 - 为运输计算添加包装皮重

[英]Magento 2.4.4 - Add a Tare weight for packaging for shipping calculation

问题是我们有很多非常小的物品 2-50 克,一盒 + 包装重 100-200 克

package 通常是最重的部分

如果我们将物品重量(在产品中)设置为物品的实际重量,那么当人们订购很多东西时,箱子重量可以使总重量超过所选邮资方式 go。

如果我们将包装盒重量添加到商品中,那么邮费就会非常昂贵,这意味着人们不会购买。

如何为每个 package 类型设置一个盒子重量。

在 Magento 计算 package 的重量之前,是否有一个扩展或者是否有一种方法可以添加一些逻辑来为盒子添加皮重。这似乎很奇怪,这不是 Magento 的功能,因为这似乎是每个人的功能必须在网上销售商品。

我想我需要一些东西来检查订单商品的重量

如果物品总重量小于 1KG,则添加(小箱子输入重量) 如果物品总重量小于 2GK 但大于 1KG,则添加(为中箱输入重量) 如果物品总重量大于 2KG,则添加(输入重量)对于大箱子)

希望能够输入包裹的包装基重

此流程设置为假设包裹重量和类型信息供管理员使用并且运费是固定的。

第 1 步:- 创建 etc/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="sales_order" resource="default" engine="innodb" comment="sales_order">
        <column xsi:type="int" name="box_weight" default="0" comment="Box Weight" />
        <column xsi:type="varchar" name="box_type" nullable="false" length="255" comment="Box Type" />
    </table>
    <table name="sales_order_grid" resource="default" engine="innodb" comment="sales_order">
        <column xsi:type="int" name="box_weight" default="0" comment="Box Weight" />
        <column xsi:type="varchar" name="box_type" nullable="false" length="255" comment="Box Type" />
    </table>
</schema>

第 2 步:创建 Model/ResourceModel/Order/Grid/Collection.php 文件

<?php

namespace Sunarc\Custom\Model\ResourceModel\Order\Grid;
 
use Magento\Framework\Data\Collection\Db\FetchStrategyInterface as CoreFetchStrategy;
use Magento\Framework\Data\Collection\EntityFactoryInterface as CoreEntityFactory;
use Magento\Framework\Event\ManagerInterface as CoreEventManager;
use Magento\Sales\Model\ResourceModel\Order\Grid\Collection as CoreSalesGrid;
use Psr\Log\LoggerInterface as Logger;
 

class Collection extends CoreSalesGrid
{
    /**
     * @param CoreEntityFactory $entityFactory
     * @param Logger            $logger       
     * @param CoreFetchStrategy $fetchStrategy
     * @param CoreEventManager  $eventManager 
     * @param string            $mainTable    
     * @param string            $resourceModel
     */
    public function __construct(
        CoreEntityFactory $entityFactory,
        Logger $logger,
        CoreFetchStrategy $fetchStrategy,
        CoreEventManager $eventManager,
        $mainTable = 'sales_order_grid',
        $resourceModel = \Magento\Sales\Model\ResourceModel\Order::class
    ) {
        parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $mainTable, $resourceModel);
    }
 
    protected function _renderFiltersBefore()
    {
        $joinTable = $this->getTable('sales_order');
        $this->getSelect()->joinLeft(
            $joinTable,
            'main_table.entity_id = sales_order.entity_id',
            ['box_weight','box_type']
        );
        parent::_renderFiltersBefore();
    }
}

第 3 步:现在,创建 etc/di.xml 文件以将自定义列数据添加到订单网格中。

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Sales\Controller\Order\History" type="Sunarc\Custom\Controller\Order\History" />

    <type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
        <arguments>
            <argument name="collections" xsi:type="array">
                <item name="sales_order_grid_data_source" xsi:type="string">Sunarc\Custom\Model\ResourceModel\Order\Grid\Collection</item>
            </argument>
        </arguments>
    </type>
    <type name="Sunarc\Custom\Model\ResourceModel\Order\Grid\Collection">
        <arguments>
            <argument name="mainTable" xsi:type="string">sales_order_grid</argument>
            <argument name="resourceModel" xsi:type="string">Magento\Sales\Model\ResourceModel\Order</argument>
        </arguments>
    </type>

</config>

第四步:创建视图/adminhtml/ui_component/sales_order_grid.xml

<?xml version="1.0" encoding="UTF-8"?>

<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <columns name="sales_order_columns">

        <column name="box_weight">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">text</item>
                    <item name="label" xsi:type="string" translate="true">Parcel Weight</item>
                </item>
            </argument>
        </column>

        <column name="box_type">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">text</item>
                    <item name="label" xsi:type="string" translate="true">Box Type</item>
                </item>
            </argument>
        </column>
    </columns>
</listing>

第 5 步:- 创建 etc/events.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="sales_order_save_before">
        <observer name="weight" instance="Sunarc\Custom\Observer\Weight" />
    </event>
</config>

第 6 步:创建 Observer/Weight.php 并编写您的自定义逻辑

<?php

namespace Sunarc\Custom\Observer;

use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Quote\Model\QuoteFactory;

class Weight implements ObserverInterface
{

    public function __construct(QuoteFactory $quoteFactory)
    {
        $this->quoteFactory = $quoteFactory;
    }
    /**
     * Below is the method that will fire whenever the event runs!
     *
     * @param Observer $observer
     */
    public function execute(Observer $observer)
    {

        //WRITE YOUR CUSTOM LOGIC HERE
        $order = $observer->getEvent()->getOrder();

        if ($order->getData('weight') == 1) {
            $order->setData('box_weight', 5); // Assumed wight of small parcel
            $order->setData('box_type', 'Small');
        } elseif ($order->getData('weight') > 1 && $order->getData('weight') <= 2) {
            $order->setData('box_weight', 7); // Assumed wight of Medium parcel
            $order->setData('box_type', 'Medium');
        } else {
            $order->setData('box_weight', 10);  // Assumed wight of Large parcel
            $order->setData('box_type', 'Large');
        }
    }
}

这是 CSV

第 1 步:- 创建 di.xml

<?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\OfflineShipping\Model\Carrier\Tablerate'>         
        <plugin name='tablerate_plugin' type='Sunarc\Custom\Plugin\TableratePlugin' sortOrder='10' disabled='false'  />     
    </type>

</config>

第 2 步:- 创建一个插件以添加您的自定义代码

<?php

namespace Sunarc\Custom\Plugin;

use Magento\Framework\Exception\LocalizedException;
use Magento\Quote\Model\Quote\Address\RateRequest;

class TableratePlugin
{


    /**
     * @var \Magento\Catalog\Api\ProductRepositoryInterface
     */
    private $productRepository;

    /**
     * @var \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory
     */
    private $rateErrorFactory;

    /**
     * @var string
     */
    protected $_code = 'tablerate';
    /**
     * @var string
     */
    protected $_defaultConditionName = 'package_weight';

    /**
     * @var \Magento\Shipping\Model\Rate\ResultFactory
     */
    protected $_rateResultFactory;

    /**
     * @var \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory
     */
    protected $_resultMethodFactory;

    public function __construct(
        \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory,
        \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $resultMethodFactory,
        \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
        \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
    ) {
        $this->_rateResultFactory = $rateResultFactory;
        $this->_resultMethodFactory = $resultMethodFactory;
        $this->rateErrorFactory = $rateErrorFactory;
        $this->productRepository = $productRepository;
    }
    public function aroundCollectRates(
        \Magento\OfflineShipping\Model\Carrier\Tablerate $subject,
        \Closure $proceed,
        RateRequest $request
    ) {

        if (!$subject->getConfigFlag('active')) {
            return false;
        }
        // exclude Virtual products price from Package value if pre-configured
        if (!$subject->getConfigFlag('include_virtual_price') && $request->getAllItems()) {
            foreach ($request->getAllItems() as $item) {
                if ($item->getParentItem()) {
                    continue;
                }
                if ($item->getHasChildren() && $item->isShipSeparately()) {
                    foreach ($item->getChildren() as $child) {
                        if ($child->getProduct()->isVirtual()) {
                            $request->setPackageValue($request->getPackageValue() - $child->getBaseRowTotal());
                        }
                    }
                } elseif ($item->getProduct()->isVirtual()) {
                    $request->setPackageValue($request->getPackageValue() - $item->getBaseRowTotal());
                }
            }
        }

        // Free shipping by qty
        $freeQty = 0;
        $freePackageValue = 0;

        if ($request->getAllItems()) {
            foreach ($request->getAllItems() as $item) {
                if ($item->getProduct()->isVirtual() || $item->getParentItem()) {
                    continue;
                }

                if ($item->getHasChildren() && $item->isShipSeparately()) {
                    foreach ($item->getChildren() as $child) {
                        if ($child->getFreeShipping() && !$child->getProduct()->isVirtual()) {
                            $freeShipping = is_numeric($child->getFreeShipping()) ? $child->getFreeShipping() : 0;
                            $freeQty += $item->getQty() * ($child->getQty() - $freeShipping);
                        }
                    }
                } elseif ($item->getFreeShipping() || $item->getAddress()->getFreeShipping()) {
                    $freeShipping = $item->getFreeShipping() ?
                        $item->getFreeShipping() : $item->getAddress()->getFreeShipping();
                    $freeShipping = is_numeric($freeShipping) ? $freeShipping : 0;
                    $freeQty += $item->getQty() - $freeShipping;
                    $freePackageValue += $item->getBaseRowTotal();
                }
            }
            $oldValue = $request->getPackageValue();
            $request->setPackageValue($oldValue - $freePackageValue);
        }

        if (!$request->getConditionName()) {
            $conditionName = $subject->getConfigData('condition_name');
            $request->setConditionName($conditionName ? $conditionName : $this->_defaultConditionName);
        }


        // Package weight and qty free shipping
        $oldWeight = $request->getPackageWeight();
        $oldQty = $request->getPackageQty();


        // ADD YOUR CUSTOM CODE HERE //

        if ($request->getFreeMethodWeight() == 1) {
            $request->setPackageWeight(50);
        } elseif ($request->getFreeMethodWeight() > 1 && $request->getFreeMethodWeight() <= 2) {
            $request->setPackageWeight(40);
        } else {
            $request->setPackageWeight(40);
        }

        // $request->setPackageWeight($request->getFreeMethodWeight());
        $request->setPackageQty($oldQty - $freeQty);

        /** @var \Magento\Shipping\Model\Rate\Result $result */
        $result = $this->_rateResultFactory->create();
        $rate = $subject->getRate($request);

        $request->setPackageWeight($oldWeight);
        $request->setPackageQty($oldQty);

        if (!empty($rate) && $rate['price'] >= 0) {
            if ($request->getPackageQty() == $freeQty) {
                $shippingPrice = 0;
            } else {
                $shippingPrice = $subject->getFinalPriceWithHandlingFee($rate['price']);
            }
            $method = $this->createShippingMethod($shippingPrice, $rate['cost'], $subject, $request);
            $result->append($method);
        } elseif ($request->getPackageQty() == $freeQty) {

            /**
             * Promotion rule was applied for the whole cart.
             *  In this case all other shipping methods could be omitted
             * Table rate shipping method with 0$ price must be shown if grand total is more than minimal value.
             * Free package weight has been already taken into account.
             */
            $request->setPackageValue($freePackageValue);
            $request->setPackageQty($freeQty);
            $rate = $subject->getRate($request);
            if (!empty($rate) && $rate['price'] >= 0) {
                $method = $this->createShippingMethod(0, 0, $subject, $request);
                $result->append($method);
            }
        } else {
            /** @var \Magento\Quote\Model\Quote\Address\RateResult\Error $error */
            $error = $this->rateErrorFactory->create(
                [
                    'data' => [
                        'carrier' => $this->_code,
                        'carrier_title' => $subject->getConfigData('title'),
                        'error_message' => $subject->getConfigData('specificerrmsg'),
                    ],
                ]
            );
            $result->append($error);
        }
        return $result;
    }

    /**
     * Get the method object based on the shipping price and cost
     *
     * @param float $shippingPrice
     * @param float $cost
     * @return \Magento\Quote\Model\Quote\Address\RateResult\Method
     */
    private function createShippingMethod($shippingPrice, $cost, $subject, $request)
    {

        /** @var  \Magento\Quote\Model\Quote\Address\RateResult\Method $method */
        $method = $this->_resultMethodFactory->create();

        $method->setCarrier('tablerate');
        $method->setCarrierTitle($subject->getConfigData('title'));

        $method->setMethod('bestway');
        $method->setMethodTitle($subject->getConfigData('name'));

        $method->setPrice($shippingPrice);
        $method->setCost($cost);
        return $method;
    }
}

您可以根据您的逻辑代码计算重量,价格将相应更新。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM