File: D:/HostingSpaces/SBogers10/csb.komma.pro/app/Listeners/TransactionChanged.php
<?php
namespace App\Listeners;
use App\Invoicing\CreditInvoiceService;
use App\Orders\CreditInvoiceNumberSequence;
use App\Orders\Kms\OrderMailServiceInterface;
use App\Orders\Kms\OrderService;
use App\Orders\Models\Order;
use App\Orders\OrderStatus;
use App\Payment\Events\TransactionChanged as TransactionChangedEvent;
use App\Payment\PaymentServiceInterface;
use App\Payment\TransactionStatus;
use App\Users\Models\SiteUser;
/**
* Class TransactionChanged
*
* Triggered when a transaction changed because a psp said so.
*
* The purpose of this class is to delegate with a capital D to
* other services in response of a transaction change. To, for example,
* update an order, send out mails, make invoices etc.
*
* @package App\Listeners
*/
class TransactionChanged
{
/** @var OrderMailServiceInterface $orderMailService */
private $orderMailService;
/** @var OrderService $orderService */
private $orderService;
/**
* @var PaymentServiceInterface
*/
private $paymentService;
/**
* @var CreditInvoiceService
*/
private $creditInvoiceService;
/**
* @var CreditInvoiceNumberSequence
*/
private $creditInvoiceGenerator;
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
$this->orderService = new OrderService();
$this->orderMailService = app(OrderMailServiceInterface::class);
$this->paymentService = app(PaymentServiceInterface::class);
$this->creditInvoiceService = new CreditInvoiceService();
$this->creditInvoiceGenerator = new CreditInvoiceNumberSequence();
}
/**
* Handle the event.
*
* @param TransactionChangedEvent $event
* @return void
*/
public function handle(TransactionChangedEvent $event) {
/** @var Order $order */
$order = $event->transaction->order()->first();
/** @var SiteUser $customer */
$customer = $order->customer()->first();
//Change the order status depending on the transaction status. And notify customer and staff if needed
switch ($event->transaction->status)
{
case TransactionStatus::CANCELED_CUSTOMER:
$order->status = OrderStatus::CANCELED;
if(!$order->isDirty()) break; //Don't mail about non changed order
\Log::debug('TransactionChange listener: Mailing the customer that his payment was canceled. (transaction canceled by customer. Transaction Id: '.$event->transaction->id.', Order Id: '.$order->id.').');
$this->orderMailService->mailCustomerAboutCurrentOrderStatus($order);
break;
case TransactionStatus::CANCELED:
$order->status = OrderStatus::CANCELED;
if(!$order->isDirty()) break; //Don't mail about non changed order
\Log::debug('TransactionChange listener: Mailing the customer that his order was canceled (transaction canceled by shop. Transaction Id: '.$event->transaction->id.', Order Id: '.$order->id.').');
$this->orderMailService->mailCustomerAboutCurrentOrderStatus($order);
break;
case TransactionStatus::CHARGEDBACK:
$order->status = OrderStatus::DISPUTED;
\Log::debug('TransactionChange listener: Mailing staff that an order was disputed (Transaction chargeback. Transaction Id: '.$event->transaction->id.', Order Id: '.$order->id.').');
$this->orderMailService->mailStaffAboutCurrentOrderStatus($order);
$this->orderMailService->mailCustomerAboutCurrentOrderStatus($order);
break;
case TransactionStatus::REFUNDED:
$order->status = OrderStatus::REFUNDED;
if(!$order->isDirty()) break; //Don't mail about non changed order
\Log::debug('TransactionChange listener: Mailing customer that an order was refunded (Transaction refunded. Transaction Id: '.$event->transaction->id.', Order Id: '.$order->id.').');
$this->orderMailService->mailCustomerAboutCurrentOrderStatus($order);
break;
case TransactionStatus::CHARGEBACK_PENDING:
\Log::debug('TransactionChange listener: Mailing staff that an order is about to be charged back (Transaction chargeback pending. Transaction Id: '.$event->transaction->id.', Order Id: '.$order->id.').');
$this->orderMailService->mailStaffAboutCurrentOrderStatus($order);
break;
case TransactionStatus::AUTHORISATION_REJECTED:
case TransactionStatus::REDIRECTED_USER_TO_PSP:
case TransactionStatus::REFUND_PENDING:
case TransactionStatus::CANCEL_PENDING:
case TransactionStatus::AUTHORISATION_PENDING:
case TransactionStatus::PAYMENT_PENDING:
break;
case TransactionStatus::AUTHORIZED:
case TransactionStatus::AUTHORISATION_UNKNOWN:
case TransactionStatus::PAYMENT_UNKNOWN:
\Log::debug('TransactionChange listener: A transactions payment state changed to '.$event->transaction->status.' an requires human intervention (Transaction Id: '.$event->transaction->id.', Order Id: '.$order->id.').');
$this->orderMailService->mailStaffAboutManualActionOnOrder($order);
break;
case TransactionStatus::EXPIRED:
if(!$order->hasBeenPaid()) $order->status = OrderStatus::CANCELED;
if(!$order->isDirty()) break; //Don't mail about non changed order
\Log::debug('TransactionChange listener: Order canceled since it has not been paid and a transaction had expire (Transaction expired. Transaction Id: '.$event->transaction->id.', Order Id: '.$order->id.').');
break;
case TransactionStatus::OPEN:
\Log::debug('TransactionChange listener: Order put on pending since the payment process was started (Transaction open. Transaction Id: '.$event->transaction->id.', Order Id: '.$order->id.').');
$order->status = OrderStatus::PENDING;
if($order->transactions->count() == 1) $this->orderMailService->mailCustomerAboutCurrentOrderStatus($order); //Only mail the user when it is the first time that a transaction was "Open".
break;
case TransactionStatus::PAYMENT_PAID:
\Log::debug('TransactionChange listener: Order waiting for fulfillment since transaction was completed / paid. Notifying customer ('.$customer->email.'). (Transaction Id: '.$event->transaction->id.', Order Id: '.$order->id.').');
$order->status = OrderStatus::AWAITING_FULFILLMENT;
if(!$order->isDirty()) break; //Don't mail about non changed order
$this->orderMailService->mailCustomerAboutCurrentOrderStatus($order);
$this->orderMailService->mailStaffAboutCurrentOrderStatus($order);
break;
}
//And finally save the order
$order->save();
}
}