42 lines
3.2 KiB
PHP
42 lines
3.2 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace Esun\Reward\Controller\Product;
|
|
|
|
use Esun\Reward\Model\BalanceManager;
|
|
use Esun\Reward\Model\ReservationManager;
|
|
use Magento\Catalog\Api\ProductRepositoryInterface;
|
|
use Magento\Checkout\Model\Cart;
|
|
use Magento\Customer\Model\Session;
|
|
use Magento\Framework\App\Action\HttpPostActionInterface;
|
|
use Magento\Framework\App\RequestInterface;
|
|
use Magento\Framework\Controller\Result\RedirectFactory;
|
|
use Magento\Framework\Data\Form\FormKey\Validator;
|
|
use Magento\Framework\DataObject;
|
|
use Magento\Framework\Exception\LocalizedException;
|
|
use Magento\Framework\Serialize\Serializer\Json;
|
|
use Magento\Framework\Message\ManagerInterface;
|
|
|
|
class Redeem implements HttpPostActionInterface
|
|
{
|
|
public function __construct(private readonly RequestInterface $request,private readonly Validator $formKey,private readonly RedirectFactory $redirects,private readonly Session $session,private readonly ProductRepositoryInterface $products,private readonly Cart $cart,private readonly BalanceManager $balances,private readonly ReservationManager $reservations,private readonly Json $json,private readonly ManagerInterface $messages) {}
|
|
public function execute()
|
|
{
|
|
$redirect=$this->redirects->create()->setPath('reward/product/index');
|
|
try {
|
|
if(!$this->formKey->validate($this->request)||!$this->session->isLoggedIn()){throw new LocalizedException(__('Please sign in to redeem products.'));}
|
|
$product=$this->products->getById((int)$this->request->getParam('product_id'));$cost=(int)$product->getData('reward_points_cost');
|
|
if(!(bool)$product->getData('reward_redeemable')||$cost<=0||$product->getTypeId()!=='simple'){throw new LocalizedException(__('This product is not available for points redemption.'));}
|
|
$quote=$this->cart->getQuote();$customerId=(int)$this->session->getCustomerId();$existing=(int)$quote->getData('reward_product_points');$cash=(int)$quote->getData('reward_points_used');
|
|
if((int)$this->balances->getAccount($customerId,(int)$quote->getStore()->getWebsiteId())['balance']<$existing+$cash+$cost){throw new LocalizedException(__('You do not have enough points for this product.'));}
|
|
$product->addCustomOption('reward_redemption', '1');
|
|
$item=$this->cart->addProduct($product,new DataObject(['qty'=>1,'reward_redemption'=>1]));if(is_string($item)){throw new LocalizedException(__($item));}
|
|
$item->setCustomPrice(0)->setOriginalCustomPrice(0)->setData('reward_redemption',1)->setData('reward_points_cost',$cost);$item->getProduct()->setIsSuperMode(true);
|
|
$item->addOption(['code'=>'additional_options','value'=>$this->json->serialize([['label'=>(string)__('Points Redemption'),'value'=>(string)__('%1 points',$cost)]])]);
|
|
$quote->setData('reward_product_points',$existing+$cost);$this->reservations->reserve($customerId,(int)$quote->getStore()->getWebsiteId(),(int)$quote->getId(),$cash+$existing+$cost);$this->cart->save();
|
|
$this->messages->addSuccessMessage(__('The redemption product was added to your cart.'));
|
|
} catch(\Throwable $e){$this->messages->addErrorMessage($e->getMessage());return $redirect;}
|
|
return $redirect->setPath('checkout/cart');
|
|
}
|
|
}
|