41 lines
2.5 KiB
PHP
41 lines
2.5 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace Esun\Reward\Observer;
|
|
|
|
use Esun\Reward\Model\BalanceManager;
|
|
use Esun\Reward\Model\Config;
|
|
use Esun\Reward\Model\TierResolver;
|
|
use Magento\Framework\Event\Observer;
|
|
use Magento\Framework\Event\ObserverInterface;
|
|
use Magento\Sales\Model\Order\Invoice;
|
|
|
|
class AwardInvoicePoints implements ObserverInterface
|
|
{
|
|
public function __construct(private readonly BalanceManager $balanceManager, private readonly Config $config, private readonly TierResolver $tierResolver) {}
|
|
|
|
public function execute(Observer $observer): void
|
|
{
|
|
/** @var Invoice|null $invoice */ $invoice = $observer->getEvent()->getInvoice();
|
|
$order = $invoice?->getOrder(); $customerId = (int)($order?->getCustomerId() ?? 0);
|
|
if (!$invoice || !$order || !$this->config->isEnabled((int)$order->getStoreId()) || $customerId <= 0) { return; }
|
|
$websiteId = (int)$order->getStore()->getWebsiteId();
|
|
$account = $this->balanceManager->getAccount($customerId, $websiteId);
|
|
$tier = $this->tierResolver->resolveEffective((string)$account['tier_code'], (float)$account['lifetime_spend_base'], (int)$order->getStoreId());
|
|
$rewardShare = (float)$order->getBaseSubtotal() > 0
|
|
? (float)$order->getData('base_reward_discount_amount') * (float)$invoice->getBaseSubtotal() / (float)$order->getBaseSubtotal()
|
|
: 0.0;
|
|
$eligible = max(0.0, (float)$invoice->getBaseSubtotal() + (float)$invoice->getBaseDiscountAmount() - $rewardShare);
|
|
$rule = $this->config->earningRule('order_earned', (int)$order->getStoreId());
|
|
$points = (int)floor($eligible * (float)$rule['points'] * (float)$tier['multiplier']);
|
|
if ($points > 0 && $this->balanceManager->change($customerId, $websiteId, $points, 'order_earned', 'invoice_earned:' . (int)$invoice->getId(), [
|
|
'reference_type' => 'order', 'reference_id' => (int)$order->getId(), 'reason' => (string)__($rule['reason'], $order->getIncrementId()),
|
|
'metadata' => ['invoice_id' => (int)$invoice->getId(), 'eligible_amount' => $eligible, 'tier' => $tier['code'], 'multiplier' => $tier['multiplier']]
|
|
])) {
|
|
$order->setData('reward_points_earned', (int)$order->getData('reward_points_earned') + $points);
|
|
$order->setData('reward_tier_code', $tier['code']); $order->setData('reward_multiplier', $tier['multiplier']); $order->save();
|
|
$this->balanceManager->addLifetimeSpend($customerId, $websiteId, $eligible, (int)$order->getStoreId());
|
|
}
|
|
}
|
|
}
|