51 lines
2.3 KiB
PHP
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'); }
|
|
}
|