Skip to content

Commit

Permalink
Add hookActionOrderSlipAdd
Browse files Browse the repository at this point in the history
  • Loading branch information
Matt75 committed Mar 4, 2024
1 parent 04f1d10 commit 4310bfc
Show file tree
Hide file tree
Showing 6 changed files with 202 additions and 8 deletions.
1 change: 1 addition & 0 deletions config/common.yml
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,7 @@ services:
public: true
arguments:
- "@ps_checkout.repository.pscheckoutcart"
- "@ps_checkout.order.state.service.order_state_mapper"

ps_checkout.query.handler.order.get_order_for_payment_reversed:
class: 'PrestaShop\Module\PrestashopCheckout\Order\QueryHandler\GetOrderForPaymentReversedQueryHandler'
Expand Down
131 changes: 131 additions & 0 deletions ps_checkout.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class Ps_checkout extends PaymentModule
'actionObjectOrderPaymentUpdateAfter',
'displayPaymentReturn',
'displayOrderDetail',
'actionOrderSlipAdd',
];

/**
Expand Down Expand Up @@ -1671,4 +1672,134 @@ public function hookDisplayOrderDetail(array $params)

return $this->display(__FILE__, 'views/templates/hook/displayOrderDetail.tpl');
}

/**
* Refund based on OrderSlip
*
* @param array{cookie: Cookie, cart: Cart, altern: int, order: Order} $params
*
* @return void
*/
public function hookActionOrderSlipAdd(array $params)
{
try {
/** @var Order $order */
$order = $params['order'];

if (!Validate::isLoadedObject($order)) {
return;
}

/** @var OrderSlip[]|bool $orderSlipCollection */
$orderSlipCollection = $order->getOrderSlipsCollection()->getResults();

if (!$orderSlipCollection) {
return;
}

/** @var OrderSlip $orderSlip */
$orderSlip = end($orderSlipCollection);

if (!Validate::isLoadedObject($orderSlip)) {
return;
}

$customer = new Customer((int) $order->id_customer);
$useTax = Group::getPriceDisplayMethod((int) $customer->id_default_group);

if ($useTax) {
$amount = $orderSlip->total_products_tax_excl;
} else {
$amount = $orderSlip->total_products_tax_incl;
}

if ($orderSlip->shipping_cost) {
if ($useTax) {
$amount += $orderSlip->total_shipping_tax_excl;
} else {
$amount += $orderSlip->total_shipping_tax_incl;
}
}

$cartRuleTotal = 0;

// Refund based on product prices, but do not refund the voucher amount
if ($orderSlip->order_slip_type == 1 && is_array($cartRules = $order->getCartRules())) {
foreach ($cartRules as $cartRule) {
if ($useTax) {
$cartRuleTotal -= $cartRule['value_tax_excl'];
} else {
$cartRuleTotal -= $cartRule['value'];
}
}
}

$amount += $cartRuleTotal;

if ($amount <= 0) {
return;
}

$psCheckoutCartCollection = new PrestaShopCollection('PsCheckoutCart');
$psCheckoutCartCollection->where('id_cart', '=', (int) $order->id_cart);
$psCheckoutCartCollection->where('paypal_status', 'in', [PsCheckoutCart::STATUS_COMPLETED, PsCheckoutCart::STATUS_PARTIALLY_COMPLETED]);
$psCheckoutCartCollection->orderBy('date_upd', 'ASC');

if (!$psCheckoutCartCollection->count()) {
return;
}

/** @var PsCheckoutCart|bool $psCheckoutCart */
$psCheckoutCart = $psCheckoutCartCollection->getFirst();

if (!$psCheckoutCart) {
return;
}

/** @var \PrestaShop\Module\PrestashopCheckout\PayPal\PayPalOrderProvider $paypalOrderProvider */
$paypalOrderProvider = $this->getService('ps_checkout.paypal.provider.order');

try {
$paypalOrder = $paypalOrderProvider->getById($psCheckoutCart->paypal_order);
} catch (Exception $exception) {
return;
}

if (!isset($paypalOrder['purchase_units'][0]['payments']['captures'][0])) {
return;
}

$capture = $paypalOrder['purchase_units'][0]['payments']['captures'][0];

$totalCaptured = (float) $capture['amount']['value'];

$totalAlreadyRefund = 0;

if (isset($paypalOrder['purchase_units'][0]['payments']['refunds'])) {
$totalAlreadyRefund = array_reduce($paypalOrder['purchase_units'][0]['payments']['refunds'], function ($totalRefunded, $refund) {
return $totalRefunded + (float) $refund['amount']['value'];
});
}

if ($totalCaptured < $amount + $totalAlreadyRefund) {
throw new \PrestaShop\Module\PrestashopCheckout\Exception\PsCheckoutException(sprintf('Refund amount %s is greater than captured amount %s', $totalCaptured, $amount));
}

$currency = new Currency($params['order']->id_currency);

/** @var \PrestaShop\Module\PrestashopCheckout\CommandBus\CommandBusInterface $commandBus */
$commandBus = $this->getService('ps_checkout.bus.command');
$commandBus->handle(new \PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Refund\Command\RefundPayPalCaptureCommand(
$psCheckoutCart->getPaypalOrderId(),
$capture['id'],
$currency->iso_code,
sprintf('%01.2F', $amount)
));
} catch (Exception $exception) {
// Do not break the Admin process if an exception is thrown
$this->getLogger()->error(__FUNCTION__, [
'exception' => $exception,
]);
}
}
}
18 changes: 17 additions & 1 deletion src/Order/Query/GetOrderForPaymentRefundedQueryResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ class GetOrderForPaymentRefundedQueryResult
*/
private $currencyId;

/**
* @var int[]
*/
private $orderStateIdHistory;

/**
* @param int $orderId
* @param int $currentStateId
Expand All @@ -70,6 +75,7 @@ class GetOrderForPaymentRefundedQueryResult
* @param string $totalAmount
* @param string $totalRefund
* @param int $currencyId
* @param int[] $orderStateIdHistory
*
* @throws OrderException
* @throws OrderStateException
Expand All @@ -81,7 +87,8 @@ public function __construct(
$hasBeenTotallyRefund,
$totalAmount,
$totalRefund,
$currencyId
$currencyId,
array $orderStateIdHistory = []
) {
$this->orderId = new OrderId($orderId);
$this->currentStateId = new OrderStateId($currentStateId);
Expand All @@ -90,6 +97,7 @@ public function __construct(
$this->totalAmount = $totalAmount;
$this->totalRefund = $totalRefund;
$this->currencyId = $currencyId;
$this->orderStateIdHistory = $orderStateIdHistory;
}

/**
Expand Down Expand Up @@ -147,4 +155,12 @@ public function getCurrencyId()
{
return $this->currencyId;
}

/**
* @return int[]
*/
public function getOrderStateIdHistory()
{
return $this->orderStateIdHistory;
}
}
49 changes: 47 additions & 2 deletions src/Order/QueryHandler/GetOrderForPaymentRefundedQueryHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
use PrestaShop\Module\PrestashopCheckout\Order\Exception\OrderNotFoundException;
use PrestaShop\Module\PrestashopCheckout\Order\Query\GetOrderForPaymentRefundedQuery;
use PrestaShop\Module\PrestashopCheckout\Order\Query\GetOrderForPaymentRefundedQueryResult;
use PrestaShop\Module\PrestashopCheckout\Order\State\Exception\OrderStateException;
use PrestaShop\Module\PrestashopCheckout\Order\State\OrderStateConfigurationKeys;
use PrestaShop\Module\PrestashopCheckout\Order\State\Service\OrderStateMapper;
use PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository;
use PrestaShopCollection;
use PrestaShopDatabaseException;
Expand All @@ -42,9 +45,15 @@ class GetOrderForPaymentRefundedQueryHandler
*/
private $psCheckoutCartRepository;

public function __construct(PsCheckoutCartRepository $psCheckoutCartRepository)
/**
* @var OrderStateMapper
*/
private $orderStateMapper;

public function __construct(PsCheckoutCartRepository $psCheckoutCartRepository, OrderStateMapper $orderStateMapper)
{
$this->psCheckoutCartRepository = $psCheckoutCartRepository;
$this->orderStateMapper = $orderStateMapper;
}

/**
Expand Down Expand Up @@ -88,7 +97,8 @@ public function handle(GetOrderForPaymentRefundedQuery $query)
$this->hasBeenTotallyRefunded($totalRefund, $order),
(string) $order->getTotalPaid(),
(string) $totalRefund,
(int) $order->id_currency
(int) $order->id_currency,
$this->getOrderStateHistory($order)
);
}

Expand All @@ -109,4 +119,39 @@ private function getTotalRefund(Order $order)

return $refundAmount;
}

/**
* @param Order $order
*
* @return int[]
*/
private function getOrderStateHistory(Order $order)
{
$orderHistory = $order->getHistory($order->id_lang);

if (!$orderHistory) {
return [];
}

try {
$orderStateRefundedId = $this->orderStateMapper->getIdByKey(OrderStateConfigurationKeys::PS_CHECKOUT_STATE_REFUNDED);
$orderStatePartiallyRefundedId = $this->orderStateMapper->getIdByKey(OrderStateConfigurationKeys::PS_CHECKOUT_STATE_PARTIALLY_REFUNDED);
} catch (OrderStateException $exception) {
return [];
}

$orderStateIdHistory = [];

foreach ($orderHistory as $historyItem) {
$orderStateId = (int) $historyItem['id_order_state'];

if ($orderStateId !== $orderStateRefundedId && $orderStateId !== $orderStatePartiallyRefundedId) {
continue;
}

$orderStateIdHistory[] = $orderStateId;
}

return $orderStateIdHistory;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,6 @@ public function setPaymentRefundedOrderStatus(PayPalCaptureRefundedEvent $event)
$this->orderPayPalCache->delete($event->getPayPalOrderId()->getValue());
}

if (!$order->hasBeenPaid() || $order->hasBeenTotallyRefund()) {
return;
}

$orderPayPal = $this->orderProvider->getById($event->getPayPalOrderId()->getValue());

if (empty($orderPayPal['purchase_units'][0]['payments']['refunds'])) {
Expand All @@ -129,11 +125,16 @@ public function setPaymentRefundedOrderStatus(PayPalCaptureRefundedEvent $event)
});

$orderFullyRefunded = (float) $order->getTotalAmount() <= (float) $totalRefunded;
$newOrderStateId = $this->orderStateMapper->getIdByKey($orderFullyRefunded ? OrderStateConfigurationKeys::PS_CHECKOUT_STATE_REFUNDED : OrderStateConfigurationKeys::PS_CHECKOUT_STATE_PARTIALLY_REFUNDED);

if (in_array($newOrderStateId, $order->getOrderStateIdHistory())) {
return;
}

$this->commandBus->handle(
new UpdateOrderStatusCommand(
$order->getOrderId()->getValue(),
$this->orderStateMapper->getIdByKey($orderFullyRefunded ? OrderStateConfigurationKeys::PS_CHECKOUT_STATE_REFUNDED : OrderStateConfigurationKeys::PS_CHECKOUT_STATE_PARTIALLY_REFUNDED)
$newOrderStateId
)
);
}
Expand Down
Empty file.

0 comments on commit 4310bfc

Please sign in to comment.