Files
2026-09-15 10:35:56 +08:00

51 lines
2.3 KiB
PHP

<?php
declare(strict_types=1);
namespace Esun\Reward\Model\Total\Quote;
use Esun\Reward\Model\Config;
use Magento\Quote\Api\Data\ShippingAssignmentInterface;
use Magento\Quote\Model\Quote;
use Magento\Quote\Model\Quote\Address\Total;
use Magento\Quote\Model\Quote\Address\Total\AbstractTotal;
class RewardDiscount extends AbstractTotal
{
protected $_code = 'reward_discount';
public function __construct(private readonly Config $config) {}
public function collect(Quote $quote, ShippingAssignmentInterface $shippingAssignment, Total $total): self
{
parent::collect($quote, $shippingAssignment, $total);
// A physical quote is collected once for shipping and again for its
// empty billing assignment. Do not let the empty pass erase the
// reward amount calculated for the shipping address.
if (!$shippingAssignment->getItems()) {
return $this;
}
$points = (int)$quote->getData('reward_points_used');
if ($points <= 0 || !$quote->getCustomerId() || !$this->config->isEnabled((int)$quote->getStoreId())) {
$quote->setData('reward_discount_amount', 0)->setData('base_reward_discount_amount', 0); return $this;
}
$baseRequested = $points / $this->config->redemptionRate((int)$quote->getStoreId());
$baseMaximum = max(0.0, array_sum($total->getAllBaseTotalAmounts()));
$baseDiscount = min($baseRequested, $baseMaximum);
$discount = (float)$quote->getStore()->getBaseCurrency()->convert($baseDiscount, $quote->getStore()->getCurrentCurrency());
$total->setBaseTotalAmount($this->getCode(), -$baseDiscount); $total->setTotalAmount($this->getCode(), -$discount);
$quote->setData('base_reward_discount_amount', $baseDiscount)->setData('reward_discount_amount', $discount);
return $this;
}
public function fetch(Quote $quote, Total $total): array
{
$amount = (float)$quote->getData('reward_discount_amount');
$points = (int)$quote->getData('reward_points_used');
return $amount > 0 ? [
'code' => $this->getCode(),
'title' => __('Points Discount (%1 points)', $points),
'value' => -$amount
] : [];
}
public function getLabel(): string { return (string)__('Points Discount'); }
}