From cd80950d65bb5552d921a1c0e44be6611d89dbe6 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Sat, 23 Sep 2023 11:56:21 +0800 Subject: [PATCH 01/12] expired booking --- .../Commands/ExpiredBookingCommand.php | 95 +++++++++++++++++++ app/Console/Kernel.php | 4 + 2 files changed, 99 insertions(+) create mode 100644 app/Console/Commands/ExpiredBookingCommand.php diff --git a/app/Console/Commands/ExpiredBookingCommand.php b/app/Console/Commands/ExpiredBookingCommand.php new file mode 100644 index 00000000..2598b380 --- /dev/null +++ b/app/Console/Commands/ExpiredBookingCommand.php @@ -0,0 +1,95 @@ +updatesBookingStatus = $updatesBookingStatus; + } + + /** + * Execute the console command. + * + * @return int + */ + public function handle() + { + // Cancel booking without payment & purchase order (1 month) + $bookings = Booking::where('status', ApprovalStatus::APPROVED) + ->where('created_at', '<', now()->subDays(30)->endOfDay()) + ->where(function ($query) { + $query->whereDoesntHave('transactions') + ->orWhereDoesntHave('transactions', function($transaction) { + return $transaction->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); + }); + })->get(); + + foreach ($bookings as $booking) { + $this->updatesBookingStatus->execute($booking, ApprovalStatus::EXPIRED); + Log::info("Expired Booking without payment & purchase order, booking id: " . $booking->id); + $transactions = $booking->transactions; + + foreach ($transactions as $transaction) { + $transaction->status = ApprovalStatus::EXPIRED; + $transaction->save(); + Log::info("Expired Transaction id: {$transaction->id} from Booking id: {$booking->id}"); + } + } + + // Cancel booking without payment but with purchase order (2 month) + $bookings = Booking::where('status', ApprovalStatus::APPROVED) + ->where('created_at', '<', now()->subDays(60)->endOfDay()) + ->where(function ($query) { + $query->whereDoesntHave('transactions', function($transaction) { + return $transaction->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); + })->whereHas('transactions', function($transaction) { + return $transaction->where('type', TransactionType::PURCHASE_ORDER); + }); + })->get(); + + foreach ($bookings as $booking) { + $this->updatesBookingStatus->execute($booking, ApprovalStatus::EXPIRED); + Log::info("Expired Booking without payment but with purchase order, booking id: " . $booking->id); + $transactions = $booking->transactions; + + foreach ($transactions as $transaction) { + $transaction->status = ApprovalStatus::EXPIRED; + $transaction->save(); + Log::info("Expired Transaction id: {$transaction->id} from Booking id: {$booking->id}"); + } + } + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index cb9cf060..0355aea1 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -43,6 +43,10 @@ class Kernel extends ConsoleKernel ->everyMinute() ->appendOutputTo(storage_path().'/logs/regenerateInvoice.log') ->withoutOverlapping(); + + $schedule->command('booking:expired') + ->dailyAt('02:00') + ->withoutOverlapping(); } /** From 32602cab31318eb8813696fdd238a17181cfd38b Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Sat, 23 Sep 2023 13:00:04 +0800 Subject: [PATCH 02/12] auto fill purchase order command --- .../Commands/AutoFillPurchaseOrderCommand.php | 112 ++++++++++++++++++ .../Commands/ExpiredBookingCommand.php | 4 +- 2 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 app/Console/Commands/AutoFillPurchaseOrderCommand.php diff --git a/app/Console/Commands/AutoFillPurchaseOrderCommand.php b/app/Console/Commands/AutoFillPurchaseOrderCommand.php new file mode 100644 index 00000000..059232d2 --- /dev/null +++ b/app/Console/Commands/AutoFillPurchaseOrderCommand.php @@ -0,0 +1,112 @@ +generatesPurchaseOrderProducts = $generatesPurchaseOrderProducts; + $this->generatesTransactionBillNumber = $generatesTransactionBillNumber; + $this->createPurchaseOrderTransactionProcessor = $createPurchaseOrderTransactionProcessor; + } + + /** + * Execute the console command. + * + * @return int + */ + public function handle() + { + $bookings = Booking::where('status', ApprovalStatus::APPROVED) + ->where('created_at', '<', now()->subDays(60)->endOfDay()) + ->whereHas('transactions', function($transaction) { + return $transaction->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); + }) + ->whereDoesntHave('transactions', function($transaction){ + $transaction->where('type', TransactionType::PURCHASE_ORDER); + $transaction->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED]); + })->get(); + + foreach ($bookings as $booking) { + $po = Transaction::where('type', TransactionType::PURCHASE_ORDER) + ->where('status', ApprovalStatus::APPROVED)->where('issuer', $booking->company_id) + ->select('*', DB::raw('abs(amount - ' . $booking->fix_amount . ') as nearest_price'))->orderBy('nearest_price')->first(); + + + if (!$po) { + $po = Transaction::where('type', TransactionType::PURCHASE_ORDER) + ->where('status', ApprovalStatus::APPROVED)->select('*', DB::raw('abs(amount - ' . $booking->fix_amount . ') as nearest_price'))->orderBy('nearest_price')->first(); + } + + $products = $this->generatesPurchaseOrderProducts->execute($po, $booking->fix_amount); + + $deference = $booking->fix_amount - $products->sum('total'); + + if($deference > -150 && $deference < 150 && $deference != 0) { + + $products->push([ + 'description' => $deference < 0 ? 'Discount':'Shipping Fee', + 'quantity' => 1, + 'stockCode' => '', + 'total' => $deference, + 'unit_price' => $deference + ]); + } + + $billNumber = $this->generatesTransactionBillNumber->execute('XPO-'); + + $total = $products->sum('total'); + + $object = new TransactionObject($billNumber, TransactionType::PURCHASE_ORDER, $booking->company->id, 1, + 1, PaymentMethodType::CASH, + $total, $total, $booking->fix_currency_id, $booking->fix_currency_id, + 1, 0, 0, null, ApprovalStatus::PENDING_SUBMISSION, $products->toArray()); + + $this->createPurchaseOrderTransactionProcessor->execute($booking, $object); + } + } +} diff --git a/app/Console/Commands/ExpiredBookingCommand.php b/app/Console/Commands/ExpiredBookingCommand.php index 2598b380..37fe8612 100644 --- a/app/Console/Commands/ExpiredBookingCommand.php +++ b/app/Console/Commands/ExpiredBookingCommand.php @@ -55,7 +55,7 @@ class ExpiredBookingCommand extends Command ->orWhereDoesntHave('transactions', function($transaction) { return $transaction->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); }); - })->get(); + })->get(); foreach ($bookings as $booking) { $this->updatesBookingStatus->execute($booking, ApprovalStatus::EXPIRED); @@ -78,7 +78,7 @@ class ExpiredBookingCommand extends Command })->whereHas('transactions', function($transaction) { return $transaction->where('type', TransactionType::PURCHASE_ORDER); }); - })->get(); + })->get(); foreach ($bookings as $booking) { $this->updatesBookingStatus->execute($booking, ApprovalStatus::EXPIRED); From f1c23d46dde54f6cbcd768df15370d4972624b54 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Tue, 26 Sep 2023 21:30:51 +0800 Subject: [PATCH 03/12] update --- app/Console/Commands/AutoFillPurchaseOrderCommand.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Console/Commands/AutoFillPurchaseOrderCommand.php b/app/Console/Commands/AutoFillPurchaseOrderCommand.php index 059232d2..65a6fa93 100644 --- a/app/Console/Commands/AutoFillPurchaseOrderCommand.php +++ b/app/Console/Commands/AutoFillPurchaseOrderCommand.php @@ -16,7 +16,7 @@ use App\Classes\ValueObjects\Constants\PaymentMethodType; use App\Models\Transaction; use Illuminate\Support\Facades\DB; -class ExpiredBookingCommand extends Command +class AutoFillPurchaseOrderCommand extends Command { /** * The name and signature of the console command. @@ -61,6 +61,7 @@ class ExpiredBookingCommand extends Command */ public function handle() { + // 5. If purchase order not fill up in 2 month, auto fill up it $bookings = Booking::where('status', ApprovalStatus::APPROVED) ->where('created_at', '<', now()->subDays(60)->endOfDay()) ->whereHas('transactions', function($transaction) { From 75f44fae74126045ebf5ac58108e374596b7045e Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Tue, 26 Sep 2023 21:31:09 +0800 Subject: [PATCH 04/12] update --- app/Console/Commands/ExpiredBookingCommand.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Console/Commands/ExpiredBookingCommand.php b/app/Console/Commands/ExpiredBookingCommand.php index 37fe8612..c5b4081c 100644 --- a/app/Console/Commands/ExpiredBookingCommand.php +++ b/app/Console/Commands/ExpiredBookingCommand.php @@ -47,7 +47,7 @@ class ExpiredBookingCommand extends Command */ public function handle() { - // Cancel booking without payment & purchase order (1 month) + // 1. Cancel booking without payment & purchase order (1 month) $bookings = Booking::where('status', ApprovalStatus::APPROVED) ->where('created_at', '<', now()->subDays(30)->endOfDay()) ->where(function ($query) { @@ -69,7 +69,7 @@ class ExpiredBookingCommand extends Command } } - // Cancel booking without payment but with purchase order (2 month) + // 2. Cancel booking without payment but with purchase order (2 month) $bookings = Booking::where('status', ApprovalStatus::APPROVED) ->where('created_at', '<', now()->subDays(60)->endOfDay()) ->where(function ($query) { From 4be3b11a505c663a78f6f6abc42223f5fe0e1bc5 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Tue, 26 Sep 2023 21:32:20 +0800 Subject: [PATCH 05/12] add auto fill purchase order job inside kernel --- app/Console/Kernel.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 0355aea1..46e77f3a 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -47,6 +47,10 @@ class Kernel extends ConsoleKernel $schedule->command('booking:expired') ->dailyAt('02:00') ->withoutOverlapping(); + + $schedule->command('purchaseOrder:autoFill') + ->dailyAt('03:00') + ->withoutOverlapping(); } /** From a84cbdde6a09d0fecc4342f1014e868fae868f36 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Wed, 27 Sep 2023 14:12:32 +0800 Subject: [PATCH 06/12] add cancel booking for refunded payment --- .../Commands/ExpiredBookingCommand.php | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/app/Console/Commands/ExpiredBookingCommand.php b/app/Console/Commands/ExpiredBookingCommand.php index c5b4081c..d79b7b9c 100644 --- a/app/Console/Commands/ExpiredBookingCommand.php +++ b/app/Console/Commands/ExpiredBookingCommand.php @@ -9,6 +9,7 @@ use Illuminate\Console\Command; use Carbon\Carbon; use Illuminate\Support\Facades\Log; use App\Classes\Modules\Bookings\Services\UpdatesBookingStatus; +use App\Models\Transaction; class ExpiredBookingCommand extends Command { @@ -91,5 +92,62 @@ class ExpiredBookingCommand extends Command Log::info("Expired Transaction id: {$transaction->id} from Booking id: {$booking->id}"); } } + + // 3. Cancel fully refunded payment & cancel booking + $transactions = Transaction::where('type', TransactionType::CREDIT_NOTE)->get(); + + foreach ($transactions as $transaction) { + // get the booking marking + $marking = substr($transaction->payment_reference, -5); + + // for a special payment reference on transaction id: 152013 + if (!is_numeric($marking)) { + $payment_reference = explode(" ", trim($transaction->payment_reference)); + if (count($payment_reference) > 1) { + $marking = $payment_reference[count($payment_reference) - 2]; + } + } + + if (is_numeric($marking)) { + $booking = Booking::where('marking', $marking)->first(); + + if ($booking) { + if ($booking->status === ApprovalStatus::APPROVED) { + $bookingPayment = $booking->transactions()->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->first(); + if (!$bookingPayment) { + $bookingPayment = $booking->transactions()->payments()->count(); + Log::info("Credit note transaction id: {$transaction->id}, there are {$bookingPayment} payment for the booking."); + $bookingPayment = $booking->transactions()->payments()->whereIn('status', [ApprovalStatus::EXPIRED, ApprovalStatus::REJECTED])->first(); + $status = ApprovalStatus::APPROVAL_STATUS_ID[$bookingPayment->status]; + Log::info("Credit note transaction id: {$transaction->id}, the payment for the booking is in status {$status}"); + } + $bookingPaymentAmount = $bookingPayment->amount; + // check if the booking is fully refund + $amountDifference = bcsub($transaction->amount, $bookingPaymentAmount); + + if (abs($amountDifference) < 0.01) { + // rejecting booking payment transaction + $bookingPayment->status = ApprovalStatus::REJECTED; + $bookingPayment->save(); + + //expired booking + $this->updatesBookingStatus->execute($booking, ApprovalStatus::EXPIRED); + Log::info("Credit note transaction id: {$transaction->id} is fully refunded, the refunded amount was {$transaction->amount} the payment reference is: {$transaction->payment_reference}"); + Log::info("Credit note transaction id: {$transaction->id}, Rejected Booking Transaction Payment id: {$bookingPayment->id}, the payment amount was {$bookingPayment->amount}"); + Log::info("Credit note transaction id: {$transaction->id}, Expired Booking id: {$booking->id}"); + } else { + Log::info("Credit note transaction id: {$transaction->id} is not fully refunded, the refunded amount was {$transaction->amount}, the payment amount was {$bookingPayment->amount}, the payment reference is: {$transaction->payment_reference}"); + } + } else { + $status = ApprovalStatus::APPROVAL_STATUS_ID[$booking->status]; + Log::info("Credit note transaction id: {$transaction->id}, booking status is {$status}"); + } + } else { + Log::info("Credit note transaction id: {$transaction->id}, booking marking not found, the payment reference is: {$transaction->payment_reference}"); + } + } else { + Log::info("Credit note transaction id: {$transaction->id} does not have booking marking, the payment reference is: {$transaction->payment_reference}"); + } + } } } From 946ee7b6f978305c69f8099aed9f8a9e33d4781c Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Fri, 29 Sep 2023 15:42:15 +0800 Subject: [PATCH 07/12] refund booking --- .../CreateBookingRefundLogic.php | 20 ++++++++++--------- .../UpdateRefundTransactionStatusLogic.php | 4 +++- .../elements/PaymentHistoryComponent.vue | 6 +++--- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php index d31ee2ce..398312c9 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php @@ -19,6 +19,7 @@ use App\Classes\Modules\Bookings\Services\CalculatesBookingRefundAmount; use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject; use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber; use App\Classes\Modules\Transactions\DataTransferObjects\TransactionRefundCalculationObject; +use App\Classes\ValueObjects\Constants\PaymentMethodType; class CreateBookingRefundLogic extends AbstractControllerLogic { @@ -84,21 +85,22 @@ class CreateBookingRefundLogic extends AbstractControllerLogic $billNumber = $this->generatesTransactionBillNumber->execute('RFD-'); - $refund = $transaction->transactions()->refunds()->sum('amount'); + $refund = $transaction->transactions()->refunds()->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED])->sum('original_amount'); if($refund + $request->input('amount') > $transaction->original_amount) throw new MalformedRequestException('Your refund must not be greater than '. $transaction->original_amount .'.'); - $amount = $transaction->booking->fix_currency_id == 1 ? $request->input('amount') : $request->input('amount') / $transaction->currency_rate; + // $transactionRefundCalculationObject = new TransactionRefundCalculationObject($booking, $transaction, $request->input('amount')); + // $transactionRefundCalculationObject->init(); - - $transactionRefundCalculationObject = new TransactionRefundCalculationObject($booking, $transaction, $amount); - $transactionRefundCalculationObject->init(); + $refundAmount = bcdiv($request->input('amount'), $transaction->currency_rate, 7); + // refund service charges if is fully refund + $refundTotal = ($refund + $request->input('amount')) == $transaction->original_amount ? $refundAmount + $transaction->service_charge + $transaction->tax : $refundAmount; $object = new TransactionObject($billNumber, TransactionType::REFUND, 1, $booking->company->id, - 1, $transactionRefundCalculationObject->getConversionObject()->getPaymentMethod(), - $transactionRefundCalculationObject->getRefundTotalAmount(), $transactionRefundCalculationObject->getAmount(), 1, - $transactionRefundCalculationObject->getConversionObject()->getCurrencyId(), $transactionRefundCalculationObject->getTransaction()->currency_rate, - $transactionRefundCalculationObject->getRefundTax(), $transactionRefundCalculationObject->getRefundServiceCharge(), null, ApprovalStatus::PENDING_VERIFICATION, [], $transaction->bill_no); + 1, PaymentMethodType::CASH, + $refundTotal, $request->input('amount'), 1, + $transaction->original_currency_id, $transaction->currency_rate, + $transaction->tax, $transaction->service_charge, null, ApprovalStatus::PENDING_VERIFICATION, [], $transaction->bill_no); $transaction = $this->createsTransaction->execute($transaction, $object); diff --git a/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php index b86e4878..bf704359 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php @@ -73,7 +73,9 @@ class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic $booking = $transaction->owner->owner; - $reference = 'Credit Voucher for Overpaid for Ref. '.$booking->marking; + $paymentTransaction = $transaction->owner; + + $reference = $transaction->amount == $paymentTransaction->amount ? 'Fully Refund for Ref. ' . $booking->marking : 'Partially Refund for Ref. ' . $booking->marking; if ($transaction->status == ApprovalStatus::APPROVED) { $this->creditWalletProcessor->execute($booking->company, $transaction->type, $transaction->amount, $reference); diff --git a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue index ce4ba5a7..63cb4687 100644 --- a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue +++ b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue @@ -133,7 +133,7 @@
Requested Refund Amount
-
{{item.currency.short_code}} {{(Math.round((totalRequestedRefund + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
+
{{item.original_currency.short_code}} {{(Math.round((totalRequestedRefund + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
@@ -271,9 +271,9 @@
-
+
- + From 8a05620edf98b8508cf3e4786d44099ebac7e252 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Mon, 8 Jan 2024 22:41:59 +0800 Subject: [PATCH 08/12] update --- .../Bookings/ControllersLogic/CreateBookingRefundLogic.php | 4 ++++ .../components/bookings/elements/PaymentHistoryComponent.vue | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php index 398312c9..b87f4331 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php @@ -81,6 +81,10 @@ class CreateBookingRefundLogic extends AbstractControllerLogic $transaction = $this->fetchesTransaction->execute(['id' => $request->route('payment_id')]); + if ($transaction->transactions()->bills()->first()) { + throw new MalformedRequestException('Booking under white form cannot request for refund'); + } + $booking = $transaction->owner; $billNumber = $this->generatesTransactionBillNumber->execute('RFD-'); diff --git a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue index 63cb4687..0512f768 100644 --- a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue +++ b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue @@ -272,7 +272,7 @@
-
+
From aa57a79ab75c4e344ef037b0d7e407c3f3f529a1 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Thu, 11 Jan 2024 11:22:46 +0800 Subject: [PATCH 09/12] fix ExportsInvoiceTransactions - $row is inside an array --- .../Modules/Exports/Services/ExportsInvoiceTransactions.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/Classes/Modules/Exports/Services/ExportsInvoiceTransactions.php b/app/Classes/Modules/Exports/Services/ExportsInvoiceTransactions.php index 836efd34..85df0be8 100644 --- a/app/Classes/Modules/Exports/Services/ExportsInvoiceTransactions.php +++ b/app/Classes/Modules/Exports/Services/ExportsInvoiceTransactions.php @@ -125,6 +125,8 @@ class ExportsInvoiceTransactions implements FromQuery, WithHeadings, WithHeading $textToAppend = Carbon::now()->format('[Y-m-d H:i:s]') . ' Shipping Portal Respnose ' . json_encode($row) . PHP_EOL; file_put_contents($errorFilePath, $textToAppend, FILE_APPEND); + $row = $row[0]; + return [ '<>', Carbon::parse($row['created_at'])->format('m/d/Y H:m'), From e5a96e179c0f828ea667863557a7375f2f7e2730 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Sat, 13 Jan 2024 13:27:24 +0800 Subject: [PATCH 10/12] add refund transaction under booking payment history, update on admin currency order dashboard to show the correct amount after refunded --- .../CreateSupplierTransactionLogic.php | 25 +++++- .../CreateSupplierTransactionProcessor.php | 10 ++- .../elements/PaymentHistoryComponent.vue | 85 +++++++++++++++++-- .../SupplierPendingOrderComponent.vue | 23 ++++- .../forms/SupplierPlaceOrderFormComponent.vue | 7 +- 5 files changed, 137 insertions(+), 13 deletions(-) diff --git a/app/Classes/Modules/Transactions/ControllersLogic/CreateSupplierTransactionLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/CreateSupplierTransactionLogic.php index 2dcbd0f7..fb324267 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/CreateSupplierTransactionLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/CreateSupplierTransactionLogic.php @@ -3,6 +3,7 @@ namespace App\Classes\Modules\Transactions\ControllersLogic; +use App\Classes\Exceptions\MalformedRequestException; use App\Classes\Modules\Transactions\Processors\CreateSupplierTransactionProcessor; use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber; use App\Models\Document; @@ -18,6 +19,7 @@ use App\Classes\General\Abstracts\AbstractControllerLogic; use App\Classes\Modules\Companies\Services\FetchesCompany; use App\Classes\Modules\Documents\Services\CreatesDocument; use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject; +use App\Classes\Modules\Transactions\Services\FetchesTransaction; class CreateSupplierTransactionLogic extends AbstractControllerLogic { @@ -48,6 +50,9 @@ class CreateSupplierTransactionLogic extends AbstractControllerLogic /** @var GeneratesTransactionBillNumber */ private $generatesTransactionBillNumber; + /** @var FetchesTransaction */ + private $fetchesTransaction; + /** * CreateSupplierTransactionLogic constructor. @@ -56,14 +61,16 @@ class CreateSupplierTransactionLogic extends AbstractControllerLogic * @param CreatesDocument $createsDocument * @param CreatesFiles $createsFile * @param GeneratesTransactionBillNumber $generatesTransactionBillNumber + * @param FetchesTransaction $fetchesTransaction */ - public function __construct(FetchesCompany $fetchesCompany, CreateSupplierTransactionProcessor $createSupplierTransactionProcessor, CreatesDocument $createsDocument, CreatesFiles $createsFile, GeneratesTransactionBillNumber $generatesTransactionBillNumber) + public function __construct(FetchesCompany $fetchesCompany, CreateSupplierTransactionProcessor $createSupplierTransactionProcessor, CreatesDocument $createsDocument, CreatesFiles $createsFile, GeneratesTransactionBillNumber $generatesTransactionBillNumber, FetchesTransaction $fetchesTransaction) { $this->fetchesCompany = $fetchesCompany; $this->createSupplierTransactionProcessor = $createSupplierTransactionProcessor; $this->createsDocument = $createsDocument; $this->createsFile = $createsFile; $this->generatesTransactionBillNumber = $generatesTransactionBillNumber; + $this->fetchesTransaction = $fetchesTransaction; } public function logic(Request $request) : JsonResponse @@ -75,6 +82,22 @@ class CreateSupplierTransactionLogic extends AbstractControllerLogic $payments = $request->input('payments'); + foreach($payments as $payment){ + $payment = $this->fetchesTransaction->execute(['id' => $payment['id']]); + + $pendingRefundRequest = $payment->transactions()->refunds()->where('status', ApprovalStatus::PENDING_VERIFICATION)->first(); + + if ($pendingRefundRequest) { + throw new MalformedRequestException('Unable to create supplier order for pending refund request payment'); + } + + $totalRefund = $payment->transactions()->refunds()->where('status', ApprovalStatus::APPROVED)->sum('original_amount'); + + if ($payment->original_amount - $totalRefund <= 0) { + throw new MalformedRequestException('Unable to create supplier order for fully refunded payment'); + } + } + $this->createSupplierTransactionProcessor->execute($supplier, $rate, $payments); if(!count($this->createSupplierTransactionProcessor->getBills())) return $this->response([]); diff --git a/app/Classes/Modules/Transactions/Processors/CreateSupplierTransactionProcessor.php b/app/Classes/Modules/Transactions/Processors/CreateSupplierTransactionProcessor.php index 9b944a5b..b514b404 100644 --- a/app/Classes/Modules/Transactions/Processors/CreateSupplierTransactionProcessor.php +++ b/app/Classes/Modules/Transactions/Processors/CreateSupplierTransactionProcessor.php @@ -81,15 +81,19 @@ class CreateSupplierTransactionProcessor if($payment->status !== ApprovalStatus::APPROVED) continue; + $totalRefund = $payment->transactions()->refunds()->where('status', ApprovalStatus::APPROVED)->sum('original_amount'); + + $original_amount_after_refund = $payment->original_amount - $totalRefund; + $this->updatesTransactionStatus->execute($payment, ApprovalStatus::COMPLETED); $billNumber = $this->generatesTransactionBillNumber->execute('SPLR-'); $constant = SegmentConstant::where('reference', SegmentConstants::SERVICE_CHARGE)->where('detail->id', $supplier->id)->first(); - $serviceCharge = $this->calculatesTransactionServiceCharge->execute($payment->original_amount, $rate, $constant); + $serviceCharge = $this->calculatesTransactionServiceCharge->execute($original_amount_after_refund, $rate, $constant); $object = new TransactionObject($billNumber, TransactionType::BILL, $supplier->id, 1, $supplier->banks()->where('default', true)->first()->id, PaymentMethodType::CASH, - $payment->original_amount * (1 / $rate), $payment->original_amount, 1, $payment->original_currency_id, + $original_amount_after_refund * (1 / $rate), $original_amount_after_refund, 1, $payment->original_currency_id, $rate, 0, $serviceCharge, null, ApprovalStatus::PENDING_SUBMISSION); /** @var Transaction $billTransaction */ @@ -101,7 +105,7 @@ class CreateSupplierTransactionProcessor $transferFee = $this->calculatesTransactionTransferFee->execute($billTransaction->original_amount, $constant); $object = new TransactionObject($transferFeeNumber, TransactionType::TRANSFER_FEE, 1, $supplier->id, $supplier->banks()->where('default', true)->first()->id, PaymentMethodType::CASH, - $payment->original_amount, $payment->original_amount, $payment->original_currency_id, $payment->original_currency_id, + $original_amount_after_refund, $original_amount_after_refund, $payment->original_currency_id, $payment->original_currency_id, 1, 0, $transferFee, null, ApprovalStatus::PENDING_VERIFICATION); $this->pushTransferFee($this->createsTransaction->execute($billTransaction, $object)); diff --git a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue index 0512f768..2649edcf 100644 --- a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue +++ b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue @@ -24,7 +24,7 @@
Refunded Amount
- {{item.original_currency.short_code}} {{(Math.round((totalRefunds + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}} + {{item.currency.short_code}} {{(Math.round((totalConvertRefunds + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
@@ -136,6 +136,12 @@
{{item.original_currency.short_code}} {{(Math.round((totalRequestedRefund + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
+
+
+
+
{{item.currency.short_code}} {{(Math.round((totalRequestedConvertRefund + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
+
+
Refunded Amount
@@ -144,6 +150,12 @@
{{item.original_currency.short_code}} {{(Math.round((totalRefunds + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
+
+
+
+
{{item.currency.short_code}} {{(Math.round((totalConvertRefunds + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
+
+
Rate
@@ -187,6 +199,14 @@
MYR {{(Math.round((item.amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
+
+
+
Your Payment After Refund
+
+
+
MYR {{(Math.round((item.amount - totalConvertRefunds + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
+
+
Your Payment Proof
@@ -279,6 +299,47 @@
+
+
+ +
+
+
+ +
+
+
+
+
+
{{ index + 1 }}. Refund updated on
+
+
+
{{ refund.updated_at }}
+
+
+
+
+
    Refund status
+
+
+
{{ refund.status === 1 ? 'Pending Verification' : refund.status === 2 ? 'Approved' : 'Rejected'}}
+
+
+
+
+
    Requested Refund Amount
+
+
+
{{refund.original_currency.short_code}} {{(Math.round((refund.original_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
+
+
+
+
+
+
{{refund.currency.short_code}} {{(Math.round((refund.amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
+
+
+
@@ -291,6 +352,7 @@ data(){ return { expandPaymentDetails: false, + expandRefundTransactions: false, amount: (Math.round(1000 * 100) / 100).toFixed(2), parameters: { amount: (Math.round(1000 * 100) / 100).toFixed(2), @@ -313,12 +375,12 @@ let vm = this; var TotalRequestedRefund = 0; this.data.transaction_refunds.forEach(function(refunds) { - TotalRequestedRefund += refunds.status === 1 ? refunds.original_amount : 0; + TotalRequestedRefund += refunds.status === 1 ? refunds.amount : 0; }); - if (vm.data.booking.fixed_currency.id != 1 && this.data.transaction_refunds[0]) { - TotalRequestedRefund = (TotalRequestedRefund * this.data.transaction_refunds[0].currency_rate); - } - return ((Math.round((TotalRequestedRefund + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")); + // if (vm.data.booking.fixed_currency.id != 1 && this.data.transaction_refunds[0]) { + // TotalRequestedRefund = (TotalRequestedRefund * this.data.transaction_refunds[0].currency_rate); + // } + return TotalRequestedRefund; }, totalRefunds() { var TotalRequestedRefund = 0; @@ -326,11 +388,22 @@ TotalRequestedRefund += refunds.status === 2 ? refunds.original_amount : 0; }); return TotalRequestedRefund; + }, + totalConvertRefunds() { + var TotalRequestedRefund = 0; + this.data.transaction_refunds.forEach(function(refunds) { + TotalRequestedRefund += refunds.status === 2 ? refunds.amount : 0; + }); + return TotalRequestedRefund; } }, methods: { clickExpand(){ this.expandPaymentDetails = !this.expandPaymentDetails; + this.expandRefundTransactions = false; + }, + clickExpandRefundTransactions(){ + this.expandRefundTransactions = !this.expandRefundTransactions; }, }, mixins: [componentHandler] diff --git a/resources/assets/vue/components/bookings/elements/SupplierPendingOrderComponent.vue b/resources/assets/vue/components/bookings/elements/SupplierPendingOrderComponent.vue index e4877e96..309f2b9b 100644 --- a/resources/assets/vue/components/bookings/elements/SupplierPendingOrderComponent.vue +++ b/resources/assets/vue/components/bookings/elements/SupplierPendingOrderComponent.vue @@ -56,6 +56,16 @@ {{item.original_currency.short_code}} +
+
+
+
Refunded Amount
+
+ {{(Math.round((totalRefunds + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}} +
+
+
+
@@ -95,7 +105,7 @@
Amount
- {{(Math.round((item.original_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}} + {{(Math.round((item.original_amount - totalRefunds + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
@@ -124,11 +134,20 @@ active: false, } }, + computed: { + totalRefunds() { + var TotalRequestedRefund = 0; + this.data.transaction_refunds.forEach(function(refunds) { + TotalRequestedRefund += refunds.status === 2 ? refunds.original_amount : 0; + }); + return TotalRequestedRefund; + } + }, methods: { activate(){ this.active = !this.active; this.$emit('input', this.item) - } + }, }, mixins: [componentHandler] } diff --git a/resources/assets/vue/components/bookings/forms/SupplierPlaceOrderFormComponent.vue b/resources/assets/vue/components/bookings/forms/SupplierPlaceOrderFormComponent.vue index 4ec71edd..0f27eb95 100644 --- a/resources/assets/vue/components/bookings/forms/SupplierPlaceOrderFormComponent.vue +++ b/resources/assets/vue/components/bookings/forms/SupplierPlaceOrderFormComponent.vue @@ -115,7 +115,12 @@ computed: { total(){ return this.payments.reduce(function (total, currentValue) { - return total + currentValue.original_amount; + return total + currentValue.original_amount - currentValue.transaction_refunds.reduce(function (totalRefund, refundTransaction) { + if (refundTransaction.status === 2) { + return totalRefund + refundTransaction.original_amount; + } + return totalRefund; + }, 0); }, 0); }, From ef43e1616d5f4281c560c45d6159d49d7cd4308c Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Sun, 14 Jan 2024 12:20:28 +0800 Subject: [PATCH 11/12] update --- .../CreateBookingRefundLogic.php | 2 +- .../Commands/ExpiredBookingCommand.php | 61 +------ .../ExpiredRefundedBookingCommand.php | 156 ++++++++++++++++++ 3 files changed, 160 insertions(+), 59 deletions(-) create mode 100644 app/Console/Commands/ExpiredRefundedBookingCommand.php diff --git a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php index b87f4331..7455e689 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php @@ -104,7 +104,7 @@ class CreateBookingRefundLogic extends AbstractControllerLogic 1, PaymentMethodType::CASH, $refundTotal, $request->input('amount'), 1, $transaction->original_currency_id, $transaction->currency_rate, - $transaction->tax, $transaction->service_charge, null, ApprovalStatus::PENDING_VERIFICATION, [], $transaction->bill_no); + 0, 0, null, ApprovalStatus::PENDING_VERIFICATION, [], $transaction->bill_no); $transaction = $this->createsTransaction->execute($transaction, $object); diff --git a/app/Console/Commands/ExpiredBookingCommand.php b/app/Console/Commands/ExpiredBookingCommand.php index d79b7b9c..ca690c67 100644 --- a/app/Console/Commands/ExpiredBookingCommand.php +++ b/app/Console/Commands/ExpiredBookingCommand.php @@ -54,7 +54,9 @@ class ExpiredBookingCommand extends Command ->where(function ($query) { $query->whereDoesntHave('transactions') ->orWhereDoesntHave('transactions', function($transaction) { - return $transaction->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); + return $transaction->where('type', TransactionType::PURCHASE_ORDER)->orWhere(function ($q) { + $q->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); + }); }); })->get(); @@ -92,62 +94,5 @@ class ExpiredBookingCommand extends Command Log::info("Expired Transaction id: {$transaction->id} from Booking id: {$booking->id}"); } } - - // 3. Cancel fully refunded payment & cancel booking - $transactions = Transaction::where('type', TransactionType::CREDIT_NOTE)->get(); - - foreach ($transactions as $transaction) { - // get the booking marking - $marking = substr($transaction->payment_reference, -5); - - // for a special payment reference on transaction id: 152013 - if (!is_numeric($marking)) { - $payment_reference = explode(" ", trim($transaction->payment_reference)); - if (count($payment_reference) > 1) { - $marking = $payment_reference[count($payment_reference) - 2]; - } - } - - if (is_numeric($marking)) { - $booking = Booking::where('marking', $marking)->first(); - - if ($booking) { - if ($booking->status === ApprovalStatus::APPROVED) { - $bookingPayment = $booking->transactions()->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->first(); - if (!$bookingPayment) { - $bookingPayment = $booking->transactions()->payments()->count(); - Log::info("Credit note transaction id: {$transaction->id}, there are {$bookingPayment} payment for the booking."); - $bookingPayment = $booking->transactions()->payments()->whereIn('status', [ApprovalStatus::EXPIRED, ApprovalStatus::REJECTED])->first(); - $status = ApprovalStatus::APPROVAL_STATUS_ID[$bookingPayment->status]; - Log::info("Credit note transaction id: {$transaction->id}, the payment for the booking is in status {$status}"); - } - $bookingPaymentAmount = $bookingPayment->amount; - // check if the booking is fully refund - $amountDifference = bcsub($transaction->amount, $bookingPaymentAmount); - - if (abs($amountDifference) < 0.01) { - // rejecting booking payment transaction - $bookingPayment->status = ApprovalStatus::REJECTED; - $bookingPayment->save(); - - //expired booking - $this->updatesBookingStatus->execute($booking, ApprovalStatus::EXPIRED); - Log::info("Credit note transaction id: {$transaction->id} is fully refunded, the refunded amount was {$transaction->amount} the payment reference is: {$transaction->payment_reference}"); - Log::info("Credit note transaction id: {$transaction->id}, Rejected Booking Transaction Payment id: {$bookingPayment->id}, the payment amount was {$bookingPayment->amount}"); - Log::info("Credit note transaction id: {$transaction->id}, Expired Booking id: {$booking->id}"); - } else { - Log::info("Credit note transaction id: {$transaction->id} is not fully refunded, the refunded amount was {$transaction->amount}, the payment amount was {$bookingPayment->amount}, the payment reference is: {$transaction->payment_reference}"); - } - } else { - $status = ApprovalStatus::APPROVAL_STATUS_ID[$booking->status]; - Log::info("Credit note transaction id: {$transaction->id}, booking status is {$status}"); - } - } else { - Log::info("Credit note transaction id: {$transaction->id}, booking marking not found, the payment reference is: {$transaction->payment_reference}"); - } - } else { - Log::info("Credit note transaction id: {$transaction->id} does not have booking marking, the payment reference is: {$transaction->payment_reference}"); - } - } } } diff --git a/app/Console/Commands/ExpiredRefundedBookingCommand.php b/app/Console/Commands/ExpiredRefundedBookingCommand.php new file mode 100644 index 00000000..4d49cb36 --- /dev/null +++ b/app/Console/Commands/ExpiredRefundedBookingCommand.php @@ -0,0 +1,156 @@ +updatesBookingStatus = $updatesBookingStatus; + $this->generatesTransactionBillNumber = $generatesTransactionBillNumber; + $this->createsTransaction = $createsTransaction; + } + + /** + * Execute the console command. + * + * @return int + */ + public function handle() + { + // 3. Cancel fully refunded payment & cancel booking + $transactions = Transaction::where('type', TransactionType::CREDIT_NOTE)->where('payment_reference', 'LIKE', "%refund%")->get(); + + foreach ($transactions as $transaction) { + // get the booking marking + $payment_reference = explode(" ", trim($transaction->payment_reference)); + // $marking = substr($transaction->payment_reference, -5); + $marking = trim(end($payment_reference)); + + if (!preg_match('/^[0-9]+$/', $marking)) { + $payment_reference = explode(".", trim($transaction->payment_reference)); + $marking = trim(end($payment_reference)); + } + + // for a special payment reference on transaction id: 140231 + if (!preg_match('/^[0-9]+$/', $marking)) { + $payment_reference = explode("No", trim($transaction->payment_reference)); + $marking = end($payment_reference); + } + + // for a special payment reference on transaction id: 152013 + if (!preg_match('/^[0-9]+$/', $marking)) { + $payment_reference = explode(" ", trim($transaction->payment_reference)); + $marking = end($payment_reference); + $marking = prev($payment_reference); + } + + if (preg_match('/^[0-9]+$/', $marking)) { + $booking = Booking::where('marking', $marking)->first(); + + if ($booking) { + $bookingPayment = $booking->transactions()->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->first(); + if (!$bookingPayment) { + $bookingPaymentCount = $booking->transactions()->payments()->count(); + if ($bookingPaymentCount > 1) { + Log::info("Credit note transaction id: {$transaction->id}, there are {$bookingPaymentCount} payment for the booking."); + foreach ($booking->transactions()->payments()->get() as $bp) { + if ($transaction->amount - $bp->amount < 0.01) { + $bookingPayment = $bp; + break; + } + } + } + + if (!$bookingPayment) { + $bookingPayment = $booking->transactions()->payments()->whereIn('status', [ApprovalStatus::SUSPENDED, ApprovalStatus::EXPIRED, ApprovalStatus::REJECTED])->orderBy('id', 'DESC')->first(); + } + $status = ApprovalStatus::APPROVAL_STATUS_ID[$bookingPayment->status]; + Log::info("Credit note transaction id: {$transaction->id}, the payment for the booking is in status {$status}"); + } + $bookingPaymentAmount = $bookingPayment->amount; + // check if the booking is fully refund + $amountDifference = bcsub($transaction->amount, $bookingPaymentAmount, 7); + + if (abs($amountDifference) < 0.01) { + // rejecting booking payment transaction + // $bookingPayment->status = ApprovalStatus::REJECTED; + // $bookingPayment->save(); + + //expired booking + // $this->updatesBookingStatus->execute($booking, ApprovalStatus::EXPIRED); + Log::info("Credit note transaction id: {$transaction->id} is fully refunded, the refunded amount was {$transaction->amount} the payment reference is: {$transaction->payment_reference}"); + Log::info("Credit note transaction id: {$transaction->id}, Rejected Booking Transaction Payment id: {$bookingPayment->id}, the payment amount was {$bookingPayment->amount}"); + Log::info("Credit note transaction id: {$transaction->id}, Expired Booking id: {$booking->id}"); + } else { + Log::info("Credit note transaction id: {$transaction->id} is not fully refunded, the refunded amount was {$transaction->amount}, the payment amount was {$bookingPayment->amount}, the payment reference is: {$transaction->payment_reference}"); + } + + $refund = $bookingPayment->transactions()->refunds()->where('amount', $transaction->amount)->where('status', ApprovalStatus::APPROVED)->first(); + + if ($refund) { + Log::info("Credit note transaction id: {$transaction->id}, already created same amount of refund transaction for same booking payment transaction"); + } + + if (!$refund) { + $billNumber = $this->generatesTransactionBillNumber->execute('RFD-'); + + $object = new TransactionObject($billNumber, TransactionType::REFUND, 1, $booking->company->id, + 1, PaymentMethodType::CASH, + $transaction->amount, $transaction->amount * $bookingPayment->currency_rate, 1, + $bookingPayment->original_currency_id, $bookingPayment->currency_rate, + 0, 0, null, ApprovalStatus::APPROVED, [], $bookingPayment->bill_no); + + $transaction = $this->createsTransaction->execute($bookingPayment, $object); + } + } else { + Log::info("Credit note transaction id: {$transaction->id}, booking marking not found, the payment reference is: {$transaction->payment_reference}"); + } + } else { + Log::info("Credit note transaction id: {$transaction->id} does not have booking marking, the payment reference is: {$transaction->payment_reference}"); + } + } + } +} From c8cabee97b82e78c363e13dc96a1e60f86fb7f14 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Mon, 15 Jan 2024 23:41:12 +0800 Subject: [PATCH 12/12] update --- .../Eloquent/Filters/IsNotFullyRefunded.php | 24 +++++++++++++++++++ .../ExpiredRefundedBookingCommand.php | 12 +++++++--- .../elements/PaymentHistoryComponent.vue | 4 ++-- .../SupplierPendingOrdersSectionComponent.vue | 4 ++-- 4 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 app/Classes/General/Eloquent/Filters/IsNotFullyRefunded.php diff --git a/app/Classes/General/Eloquent/Filters/IsNotFullyRefunded.php b/app/Classes/General/Eloquent/Filters/IsNotFullyRefunded.php new file mode 100644 index 00000000..fdbb2994 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/IsNotFullyRefunded.php @@ -0,0 +1,24 @@ +withSum(['transactions as total_refund_amount' => function($q) { + $q->refunds()->where('status', ApprovalStatus::APPROVED); + }], 'original_amount') + ->having('total_refund_amount', '<', DB::raw('original_amount')); + } +} diff --git a/app/Console/Commands/ExpiredRefundedBookingCommand.php b/app/Console/Commands/ExpiredRefundedBookingCommand.php index 4d49cb36..db7e00a7 100644 --- a/app/Console/Commands/ExpiredRefundedBookingCommand.php +++ b/app/Console/Commands/ExpiredRefundedBookingCommand.php @@ -122,19 +122,25 @@ class ExpiredRefundedBookingCommand extends Command //expired booking // $this->updatesBookingStatus->execute($booking, ApprovalStatus::EXPIRED); Log::info("Credit note transaction id: {$transaction->id} is fully refunded, the refunded amount was {$transaction->amount} the payment reference is: {$transaction->payment_reference}"); - Log::info("Credit note transaction id: {$transaction->id}, Rejected Booking Transaction Payment id: {$bookingPayment->id}, the payment amount was {$bookingPayment->amount}"); - Log::info("Credit note transaction id: {$transaction->id}, Expired Booking id: {$booking->id}"); + // Log::info("Credit note transaction id: {$transaction->id}, Rejected Booking Transaction Payment id: {$bookingPayment->id}, the payment amount was {$bookingPayment->amount}"); + // Log::info("Credit note transaction id: {$transaction->id}, Expired Booking id: {$booking->id}"); } else { Log::info("Credit note transaction id: {$transaction->id} is not fully refunded, the refunded amount was {$transaction->amount}, the payment amount was {$bookingPayment->amount}, the payment reference is: {$transaction->payment_reference}"); } $refund = $bookingPayment->transactions()->refunds()->where('amount', $transaction->amount)->where('status', ApprovalStatus::APPROVED)->first(); + $bookingInWhiteForm = $bookingPayment->transactions()->bills()->first(); + if ($refund) { Log::info("Credit note transaction id: {$transaction->id}, already created same amount of refund transaction for same booking payment transaction"); } - if (!$refund) { + if ($bookingInWhiteForm) { + Log::info("Credit note transaction id: {$transaction->id}, booking is in white form"); + } + + if (!$refund && !$bookingInWhiteForm) { $billNumber = $this->generatesTransactionBillNumber->execute('RFD-'); $object = new TransactionObject($billNumber, TransactionType::REFUND, 1, $booking->company->id, diff --git a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue index 2649edcf..43e2e96d 100644 --- a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue +++ b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue @@ -299,14 +299,14 @@
-
+
-
+
diff --git a/resources/assets/vue/components/bookings/sections/SupplierPendingOrdersSectionComponent.vue b/resources/assets/vue/components/bookings/sections/SupplierPendingOrdersSectionComponent.vue index 7df9c125..c7382629 100644 --- a/resources/assets/vue/components/bookings/sections/SupplierPendingOrdersSectionComponent.vue +++ b/resources/assets/vue/components/bookings/sections/SupplierPendingOrdersSectionComponent.vue @@ -117,7 +117,7 @@
- + @@ -195,7 +195,7 @@ }, updateList(){ - this.$refs.pendingOrdersList.updateFilters({per_page: 10000, status: 2, type: 1, original_currency_id_in: [this.selectedCurrency.id], transaction_service_id: this.selectedService.id}); + this.$refs.pendingOrdersList.updateFilters({per_page: 10000, status: 2, type: 1, is_not_fully_refunded: true, original_currency_id_in: [this.selectedCurrency.id], transaction_service_id: this.selectedService.id}); this.selectedSupplier.status = false; this.currencyDropdownLaunch.status = false;