How to add shipping price for all individual product
-
06-04-2021 - |
Domanda
I want shipping price for individual product, not depending country, state or anything. For example one product's shipping price is $5 but another one product's shipping price is $8. How to give shipping price for individual product?
Soluzione
You can create a product attribute named base_individual_shipping_price
and one simple plugin for the Magento\OfflineShipping\Model\Carrier\Tablerate
(or other method, or for all methods) where we can read this additional individual price of each product and add it to the Rate.
Here is that plugin code:
app/code/MageWorx/ShippingPricePerProduct/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">
<type name="Magento\OfflineShipping\Model\Carrier\Tablerate">
<plugin name="mageworx_individual_product_shipping_price"
type="MageWorx\ShippingPricePerProduct\Plugin\ChangeShippingMethodPrice"
sortOrder="10"
disabled="false"/>
</type>
</config>
app/code/MageWorx/ShippingPricePerProduct/Plugin/ChangeShippingMethodPrice.php
<?php
namespace MageWorx\ShippingPricePerProduct\Plugin;
use Magento\Quote\Model\Quote\Address\RateRequest;
use Magento\Shipping\Model\Carrier\AbstractCarrierInterface;
/**
* Class ChangeShippingMethodPrice
*/
class ChangeShippingMethodPrice
{
/**
* Set individual shipping price per product to each shipping rate
*
* @param AbstractCarrierInterface $subject
* @param $result
* @param RateRequest $request
* @return mixed
*/
public function afterCollectRates(
AbstractCarrierInterface $subject,
$result,
RateRequest $request
) {
if (!$result instanceof \Magento\Shipping\Model\Rate\Result) {
return $result;
}
$priceSurcharge = 0;
$items = $request->getAllItems();
foreach ($items as $item) {
$product = $item->getProduct();
if (!$product) {
continue;
}
$priceSurcharge += (float)$product->getData('base_individual_shipping_price');
}
foreach ($result->getAllRates() as $rate) {
if (!$rate->getData('individual_price_applied')) {
$individualPrice = $rate->getPrice() + $priceSurcharge;
$rate->setPrice($individualPrice);
$rate->setData('individual_price_applied', true);
}
}
return $result;
}
}
Or you can download full example module on GitHub with attribute installation.
Here is how it looks inside this plugin (using xDebug):
Here is individual price set to the product (in admin side):
As you can see the individual price 5.0 was added to the base rate of 15.0 so result price will be 20.0
So here is result on frontend:
Note: 22.0 is price with tax.