magento-packagingweight/Plugin/MatrixRatePlugin.php
2025-05-24 15:26:42 +00:00

151 lines
5.3 KiB
PHP

<?php
/**
* Copyright James Oakley 2025. https://git.oakleys.org/
*
* This file is part of Jro_PackagingWeight.
*
* Jro_PackagingWeight is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
* Jro_PackagingWeight is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
* You should have received a copy of the GNU General Public License along with
* Jro_PackagingWeight. If not, see https://www.gnu.org/licenses/.
*/
namespace Jro\PackagingWeight\Plugin;
use Magento\Quote\Model\Quote\Address\RateRequest;
use WebShopApps\MatrixRate\Model\Carrier\Matrixrate;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Store\Model\ScopeInterface;
use Magento\Shipping\Model\Rate\Result as RateResult;
use Magento\Quote\Model\Quote\Address\RateResult\Method as RateMethod;
class MatrixRatePlugin
{
private const XML_PATH_1_5 = 'carriers/matrixrate/packaging_weight_1_5';
private const XML_PATH_6_10 = 'carriers/matrixrate/packaging_weight_6_10';
private const XML_PATH_11_PLUS = 'carriers/matrixrate/packaging_weight_11_plus';
private const XML_PATH_PRICE_ADJ_1_5 = 'carriers/matrixrate/packaging_cost_1_5';
private const XML_PATH_PRICE_ADJ_6_10 = 'carriers/matrixrate/packaging_cost_6_10';
private const XML_PATH_PRICE_ADJ_11_PLUS = 'carriers/matrixrate/packaging_cost_11_plus';
/**
* @var \Magento\Framework\App\Config\ScopeConfigInterface
*/
private $scopeConfig;
/**
* @var \Magento\Quote\Model\Quote\Address\RateRequest
*/
private ?RateRequest $rateRequest = null;
/**
* Constructor, using DI.
*
* @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
*/
public function __construct(ScopeConfigInterface $scopeConfig)
{
$this->scopeConfig = $scopeConfig;
}
/**
* Plugin for before collectRates method.
*
* @param \WebShopApps\MatrixRate\Model\Carrier\Matrixrate $subject
* @param \Magento\Quote\Model\Quote\Address\RateRequest $request
*/
public function beforeCollectRates(Matrixrate $subject, RateRequest $request)
{
// Store the RateRequest, so we can use it in afterCollectRates.
$this->rateRequest = $request;
$itemQty = (int) $request->getPackageQty();
if ($itemQty <= 0) {
return [$request];
}
$weightToAdd = 0;
if ($itemQty >= 1 && $itemQty <= 5) {
$weightToAdd = (float) $this->scopeConfig->getValue(self::XML_PATH_1_5, ScopeInterface::SCOPE_STORE);
} elseif ($itemQty >= 6 && $itemQty <= 10) {
$weightToAdd = (float) $this->scopeConfig->getValue(self::XML_PATH_6_10, ScopeInterface::SCOPE_STORE);
} elseif ($itemQty > 10) {
$weightToAdd = (float) $this->scopeConfig->getValue(self::XML_PATH_11_PLUS, ScopeInterface::SCOPE_STORE);
}
if ($weightToAdd <= 0) {
return [$request];
}
$originalWeight = $request->getPackageWeight();
$adjustedWeight = $originalWeight + $weightToAdd;
$request->setPackageWeight($adjustedWeight);
$request->setData('package_weight', $adjustedWeight);
$request->setFreeMethodWeight($adjustedWeight);
$request->setData('weight', $adjustedWeight);
if (method_exists($request, 'setWeight')) {
$request->setWeight($adjustedWeight);
}
return [$request];
}
/**
* Plugin for after collectRates method.
*
* @param \WebShopApps\MatrixRate\Model\Carrier\Matrixrate $subject
* @param \Magento\Shipping\Model\Rate\Result $result
*/
public function afterCollectRates(Matrixrate $subject, $result)
{
if (!$result instanceof \Magento\Shipping\Model\Rate\Result) {
return $result;
}
if (!$this->rateRequest instanceof RateRequest) {
return $result;
}
$itemCount = (int) $this->rateRequest->getPackageQty();
if ($itemCount <= 0) {
return $result;
}
// Determine correct per-item adjustment based on quantity
if ($itemCount >= 1 && $itemCount <= 5) {
$adjustment = (float) $this->scopeConfig
->getValue(self::XML_PATH_PRICE_ADJ_1_5, ScopeInterface::SCOPE_STORE);
} elseif ($itemCount >= 6 && $itemCount <= 10) {
$adjustment = (float) $this->scopeConfig
->getValue(self::XML_PATH_PRICE_ADJ_6_10, ScopeInterface::SCOPE_STORE);
} else {
$adjustment = (float) $this->scopeConfig
->getValue(self::XML_PATH_PRICE_ADJ_11_PLUS, ScopeInterface::SCOPE_STORE);
}
if ($adjustment <= 0) {
return $result;
}
foreach ($result->getAllRates() as $method) {
$originalPrice = $method->getPrice();
$originalCost = $method->getCost();
$method->setPrice($originalPrice + $adjustment);
$method->setCost($originalCost + $adjustment);
}
return $result;
}
}