Update business logic when a white form (group transaction is deleted, check for pending refund and auto reject them

This commit is contained in:
Dillon Ngo
2025-12-09 13:38:04 +08:00
parent 3d14f07e16
commit 002418dcac
3 changed files with 155 additions and 108 deletions
@@ -6,6 +6,7 @@ use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Transactions\Services\FetchesGroup;
use App\Classes\Modules\Transactions\Services\DeletesTransaction;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\Modules\Transactions\Processors\UpdateRefundTransactionStatusProcessor;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Http\Resources\GroupResource;
@@ -35,17 +36,22 @@ class DeleteGroupLogic extends AbstractControllerLogic
/** @var DeletesTransaction */
private $deletesTransaction;
/** @var UpdateRefundTransactionStatusProcessor */
private $updateRefundTransactionStatusProcessor;
/**
* DeleteGroupLogic constructor.
* @param updatesTransactionStatus $updatesTransactionStatus
* @param FetchesGroup $fetchesGroup
* @param DeletesTransaction $deletesTransaction
* @param UpdateRefundTransactionStatusProcessor $updateRefundTransactionStatusProcessor
*/
public function __construct(updatesTransactionStatus $updatesTransactionStatus, FetchesGroup $fetchesGroup, DeletesTransaction $deletesTransaction)
public function __construct(updatesTransactionStatus $updatesTransactionStatus, FetchesGroup $fetchesGroup, DeletesTransaction $deletesTransaction, UpdateRefundTransactionStatusProcessor $updateRefundTransactionStatusProcessor)
{
$this->updatesTransactionStatus = $updatesTransactionStatus;
$this->fetchesGroup = $fetchesGroup;
$this->deletesTransaction = $deletesTransaction;
$this->updateRefundTransactionStatusProcessor = $updateRefundTransactionStatusProcessor;
}
/**
@@ -69,6 +75,7 @@ class DeleteGroupLogic extends AbstractControllerLogic
$this->updatesTransactionStatus->execute($payment, ApprovalStatus::APPROVED);
}
$this->deletesTransaction->execute($bill);
$this->checkForRefund($payment);
}
$group->delete();
@@ -76,4 +83,11 @@ class DeleteGroupLogic extends AbstractControllerLogic
return $this->resourceResponse(new GroupResource($group));
}
//Check for refund if it is still pending, auto reject immediately
private function checkForRefund($payment){
$refunds = $payment->transactions()->refunds()->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION])->get();
foreach($refunds as $refund) {
$this->updateRefundTransactionStatusProcessor->execute($refund->id, ApprovalStatus::REJECTED);
}
}
}
@@ -2,22 +2,11 @@
namespace App\Classes\Modules\Transactions\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Bookings\ControllersLogic\UpdateBookingAmountLogic;
use App\Classes\Modules\Companies\Services\FetchesCompany;
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\Modules\Documents\Services\DeletesDocument;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Classes\Modules\Wallets\Processors\CreditWalletProcessor;
use App\Classes\Modules\Bookings\Services\CalculatesBookingPayableAmount;
use App\Classes\Modules\Bookings\Services\CalculatesBookingRefundAmount;
use App\Classes\Modules\Transactions\Standards\Rules\CanUpdateRefundTransactionStatus;
use App\Classes\ValueObjects\Constants\RemarkRefundReason;
use App\Classes\ValueObjects\Constants\TransactionType;
use Illuminate\Support\Facades\Log;
use App\Classes\Modules\Transactions\Processors\UpdateRefundTransactionStatusProcessor;
class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic
{
@@ -27,61 +16,21 @@ class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic
*/
protected function notification():array {
return [
'title' => 'Updated Transaction',
'message' => 'You have successfully updated a transaction'
'title' => 'Updated Refund Transaction',
'message' => 'You have successfully updated a refund transaction'
];
}
/** @var FetchesCompany */
private $fetchesCompany;
/** @var FetchesTransaction */
private $fetchesTransaction;
/** @var UpdatesTransactionStatus */
private $updatesTransactionStatus;
/** @var DeletesDocument */
private $deletesDocument;
/** @var CreditWalletProcessor */
private $creditWalletProcessor;
/** @var CalculatesBookingPayableAmount */
private $calculatesBookingPayableAmount;
/** @var CalculatesBookingRefundAmount */
private $calculatesBookingRefundAmount;
/** @var UpdateBookingAmountLogic */
private $updateBookingAmountLogic;
/** @var CanUpdateRefundTransactionStatus */
private $canUpdateRefundTransactionStatus;
/** @var UpdateRefundTransactionStatusProcessor */
private $updateRefundTransactionStatusProcessor;
/**
* CreatePaymentVerificationDocumentLogic constructor.
* @param FetchesCompany $fetchesCompany
* @param FetchesTransaction $fetchesTransaction
* @param UpdatesTransactionStatus $updatesTransactionStatus
* @param DeletesDocument $deletesDocument
* @param CreditWalletProcessor $creditWalletProcessor
* @param CalculatesBookingPayableAmount $calculatesBookingPayableAmount
* @param CalculatesBookingRefundAmount $calculatesBookingRefundAmount
* @param UpdateBookingAmountLogic $updateBookingAmountLogic
* @param CanUpdateRefundTransactionStatus $canUpdateRefundTransactionStatus
* UpdateRefundTransactionStatusLogic constructor.
* @param UpdateRefundTransactionStatusProcessor $updateRefundTransactionStatusProcessor
*/
public function __construct(FetchesCompany $fetchesCompany, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, DeletesDocument $deletesDocument, CreditWalletProcessor $creditWalletProcessor, CalculatesBookingPayableAmount $calculatesBookingPayableAmount, CalculatesBookingRefundAmount $calculatesBookingRefundAmount, UpdateBookingAmountLogic $updateBookingAmountLogic, CanUpdateRefundTransactionStatus $canUpdateRefundTransactionStatus)
public function __construct(UpdateRefundTransactionStatusProcessor $updateRefundTransactionStatusProcessor)
{
$this->fetchesCompany = $fetchesCompany;
$this->fetchesTransaction = $fetchesTransaction;
$this->updatesTransactionStatus = $updatesTransactionStatus;
$this->deletesDocument = $deletesDocument;
$this->creditWalletProcessor = $creditWalletProcessor;
$this->calculatesBookingPayableAmount = $calculatesBookingPayableAmount;
$this->calculatesBookingRefundAmount = $calculatesBookingRefundAmount;
$this->updateBookingAmountLogic = $updateBookingAmountLogic;
$this->canUpdateRefundTransactionStatus = $canUpdateRefundTransactionStatus;
$this->updateRefundTransactionStatusProcessor = $updateRefundTransactionStatusProcessor;
}
/**
@@ -93,52 +42,7 @@ class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic
{
// $this->canUpdateRefundTransactionStatus->passes();
$refundTransaction = $this->fetchesTransaction->execute(['id' => $request->route('id')]);
$refundTransaction = $this->updatesTransactionStatus->execute($refundTransaction, $request->route('status'));
$paymentTransaction = $refundTransaction->owner;
$supplierRefundTransaction = $paymentTransaction->transactions()->supplierRefunds()->where('status', [ApprovalStatus::PENDING_VERIFICATION])->first();
$booking = $paymentTransaction->owner;
// $reference = $paymentTransaction->amount - $refundTransaction->amount < 0.01 ? 'Fully Refund for Ref. ' . $booking->marking : 'Partially Refund for Ref. ' . $booking->marking;
if ($paymentTransaction->amount - $refundTransaction->amount < 0.01) {
$reference = 'Return Inward for Ref. ' . $booking->marking;
} else {
$refundRemark = $refundTransaction->remarks && $refundTransaction->remarks->first() ? $refundTransaction->remarks->first()->content : $request->input('refundRemark') ;
$remarkGroup = RemarkRefundReason::REFUND_REASONS[$refundRemark] ?? null;
$reference = $remarkGroup ? $remarkGroup . ' for Ref. ' . $booking->marking : $refundRemark . ' for Ref. ' . $booking->marking;
}
$refundAmount = $this->calculatesBookingRefundAmount->calculateRefundAmount($paymentTransaction, $booking->fix_currency_id);
$paidAmount = $paymentTransaction->original_amount - $refundAmount;
if ($refundTransaction->status == ApprovalStatus::APPROVED) {
$this->creditWalletProcessor->execute($booking->company, $refundTransaction->type, $refundTransaction->amount, $reference, $refundTransaction);
$po_transaction = $booking->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first();
if ($po_transaction) {
$this->updatesTransactionStatus->execute($po_transaction, (float) number_format($po_transaction->amount, 2, '.', '') === (float) number_format((float)$booking->fix_amount - $refundTransaction->original_amount, 2, '.', '') ? ApprovalStatus::PENDING_VERIFICATION : ApprovalStatus::PENDING_SUBMISSION);
}
// cief todo: 90 - REVERTED STARTS (commented before revert)
// $request['fix_amount'] = $booking->fix_amount - $refundTransaction->original_amount;
// $request->route()->setParameter('id', $booking->id);
// $this->updateBookingAmountLogic->execute($request);
// cief todo: 90 - REVERTED ENDS (commented before revert)
}
if ($supplierRefundTransaction) {
$this->updatesTransactionStatus->execute($supplierRefundTransaction, $request->route('status'));
}
if (!$paidAmount > 0) {
$this->updatesTransactionStatus->execute($paymentTransaction, ApprovalStatus::REFUNDED);
}
$this->updateRefundTransactionStatusProcessor->execute($request->route('id'), $request->route('status'), $request->input('refundRemark') ?? "");
return $this->response([]);
}
@@ -0,0 +1,129 @@
<?php
namespace App\Classes\Modules\Transactions\Processors;
use App\Classes\Modules\Bookings\ControllersLogic\UpdateBookingAmountLogic;
use App\Classes\Modules\Companies\Services\FetchesCompany;
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\Modules\Documents\Services\DeletesDocument;
use App\Classes\Modules\Wallets\Processors\CreditWalletProcessor;
use App\Classes\Modules\Bookings\Services\CalculatesBookingPayableAmount;
use App\Classes\Modules\Bookings\Services\CalculatesBookingRefundAmount;
use App\Classes\Modules\Transactions\Standards\Rules\CanUpdateRefundTransactionStatus;
use App\Classes\ValueObjects\Constants\RemarkRefundReason;
use App\Classes\ValueObjects\Constants\TransactionType;
use Illuminate\Support\Facades\Log;
class UpdateRefundTransactionStatusProcessor
{
/** @var FetchesCompany */
private $fetchesCompany;
/** @var FetchesTransaction */
private $fetchesTransaction;
/** @var UpdatesTransactionStatus */
private $updatesTransactionStatus;
/** @var DeletesDocument */
private $deletesDocument;
/** @var CreditWalletProcessor */
private $creditWalletProcessor;
/** @var CalculatesBookingPayableAmount */
private $calculatesBookingPayableAmount;
/** @var CalculatesBookingRefundAmount */
private $calculatesBookingRefundAmount;
/** @var UpdateBookingAmountLogic */
private $updateBookingAmountLogic;
/** @var CanUpdateRefundTransactionStatus */
private $canUpdateRefundTransactionStatus;
/**
* UpdateRefundTransactionStatusProcessor constructor.
* @param FetchesCompany $fetchesCompany
* @param FetchesTransaction $fetchesTransaction
* @param UpdatesTransactionStatus $updatesTransactionStatus
* @param DeletesDocument $deletesDocument
* @param CreditWalletProcessor $creditWalletProcessor
* @param CalculatesBookingPayableAmount $calculatesBookingPayableAmount
* @param CalculatesBookingRefundAmount $calculatesBookingRefundAmount
* @param UpdateBookingAmountLogic $updateBookingAmountLogic
* @param CanUpdateRefundTransactionStatus $canUpdateRefundTransactionStatus
*/
public function __construct(FetchesCompany $fetchesCompany, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, DeletesDocument $deletesDocument, CreditWalletProcessor $creditWalletProcessor, CalculatesBookingPayableAmount $calculatesBookingPayableAmount, CalculatesBookingRefundAmount $calculatesBookingRefundAmount, UpdateBookingAmountLogic $updateBookingAmountLogic, CanUpdateRefundTransactionStatus $canUpdateRefundTransactionStatus)
{
$this->fetchesCompany = $fetchesCompany;
$this->fetchesTransaction = $fetchesTransaction;
$this->updatesTransactionStatus = $updatesTransactionStatus;
$this->deletesDocument = $deletesDocument;
$this->creditWalletProcessor = $creditWalletProcessor;
$this->calculatesBookingPayableAmount = $calculatesBookingPayableAmount;
$this->calculatesBookingRefundAmount = $calculatesBookingRefundAmount;
$this->updateBookingAmountLogic = $updateBookingAmountLogic;
$this->canUpdateRefundTransactionStatus = $canUpdateRefundTransactionStatus;
}
/**
* @param Booking $booking
* @return void
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(int $transactionId, int $transactionStatus, string $refundRemark = "")
{
$refundTransaction = $this->fetchesTransaction->execute(['id' => $transactionId]);
$refundTransaction = $this->updatesTransactionStatus->execute($refundTransaction, $transactionStatus);
$paymentTransaction = $refundTransaction->owner;
$supplierRefundTransaction = $paymentTransaction->transactions()->supplierRefunds()->where('status', [ApprovalStatus::PENDING_VERIFICATION])->first();
$booking = $paymentTransaction->owner;
// $reference = $paymentTransaction->amount - $refundTransaction->amount < 0.01 ? 'Fully Refund for Ref. ' . $booking->marking : 'Partially Refund for Ref. ' . $booking->marking;
if ($paymentTransaction->amount - $refundTransaction->amount < 0.01) {
$reference = 'Return Inward for Ref. ' . $booking->marking;
} else {
$refundRemark = $refundTransaction->remarks && $refundTransaction->remarks->first() ? $refundTransaction->remarks->first()->content : $refundRemark;
$remarkGroup = RemarkRefundReason::REFUND_REASONS[$refundRemark] ?? null;
$reference = $remarkGroup ? $remarkGroup . ' for Ref. ' . $booking->marking : $refundRemark . ' for Ref. ' . $booking->marking;
}
$refundAmount = $this->calculatesBookingRefundAmount->calculateRefundAmount($paymentTransaction, $booking->fix_currency_id);
$paidAmount = $paymentTransaction->original_amount - $refundAmount;
if ($refundTransaction->status == ApprovalStatus::APPROVED) {
$this->creditWalletProcessor->execute($booking->company, $refundTransaction->type, $refundTransaction->amount, $reference, $refundTransaction);
$po_transaction = $booking->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first();
if ($po_transaction) {
$this->updatesTransactionStatus->execute($po_transaction, (float) number_format($po_transaction->amount, 2, '.', '') === (float) number_format((float)$booking->fix_amount - $refundTransaction->original_amount, 2, '.', '') ? ApprovalStatus::PENDING_VERIFICATION : ApprovalStatus::PENDING_SUBMISSION);
}
// cief todo: 90 - REVERTED STARTS (commented before revert)
// $request['fix_amount'] = $booking->fix_amount - $refundTransaction->original_amount;
// $request->route()->setParameter('id', $booking->id);
// $this->updateBookingAmountLogic->execute($request);
// cief todo: 90 - REVERTED ENDS (commented before revert)
}
if ($supplierRefundTransaction) {
$this->updatesTransactionStatus->execute($supplierRefundTransaction, $transactionStatus);
}
if (!$paidAmount > 0) {
$this->updatesTransactionStatus->execute($paymentTransaction, ApprovalStatus::REFUNDED);
}
}
}