From eb9fcbdb238d3e7f7abdc16a8e88d80e70e6c570 Mon Sep 17 00:00:00 2001 From: Edmond Lang Date: Fri, 25 Jul 2025 19:14:03 +0800 Subject: [PATCH 1/3] add route preview-unfinished-payment-orders --- app/Http/Controllers/Reports/UnfinishedPaymentOrders.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Controllers/Reports/UnfinishedPaymentOrders.php b/app/Http/Controllers/Reports/UnfinishedPaymentOrders.php index c3bda14a..515f13a4 100644 --- a/app/Http/Controllers/Reports/UnfinishedPaymentOrders.php +++ b/app/Http/Controllers/Reports/UnfinishedPaymentOrders.php @@ -13,7 +13,7 @@ class UnfinishedPaymentOrders extends Controller public function execute(Request $request) { $page = (int) $request->input('page', 1); - $perPage = 5000; + $perPage = 2500; $offset = ($page - 1) * $perPage; $cutOffDate = $request->cut_off_date ? Carbon::parse($request->cut_off_date) : null; From d2787964aa4b2df25a71e83c076292a832ac9db1 Mon Sep 17 00:00:00 2001 From: Edmond Lang Date: Fri, 25 Jul 2025 19:22:19 +0800 Subject: [PATCH 2/3] add route preview-unfinished-payment-orders --- app/Http/Controllers/Reports/UnfinishedPaymentOrders.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/Reports/UnfinishedPaymentOrders.php b/app/Http/Controllers/Reports/UnfinishedPaymentOrders.php index 515f13a4..6266b4a1 100644 --- a/app/Http/Controllers/Reports/UnfinishedPaymentOrders.php +++ b/app/Http/Controllers/Reports/UnfinishedPaymentOrders.php @@ -126,9 +126,9 @@ function runNextBatch() { const row = document.createElement('tr'); row.innerHTML = ` \${item.order_ref} - RM \${item.booking_amount} - RM \${item.paid_amount} - RM \${item.outstanding_amount} + \${item.booking_amount} + \${item.paid_amount} + \${item.outstanding_amount} \${item.customer ?? '-'} \${item.created_at} `; From 0e51f4a2361417b2584a01da326d3a34da2d47df Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Mon, 4 Aug 2025 23:58:57 +0800 Subject: [PATCH 3/3] E-Invoice - One time processing to generate normal invoice for July 2025 --- ...eTimeBatchProcessEInvoicesV2CommandJob.php | 44 +++++++++++ .../RegenerateInvoiceBookingProcessor.php | 9 ++- .../CreateInvoiceDocumentProcessor.php | 8 +- .../CreateInvoiceTransactionProcessor.php | 12 ++- .../OneTimeBatchProcessEInvoicesV2Command.php | 78 +++++++++++++++++++ 5 files changed, 145 insertions(+), 6 deletions(-) create mode 100644 app/Classes/Jobs/Commands/V2/OneTimeBatchProcessEInvoicesV2CommandJob.php create mode 100644 app/Console/Commands/V2/OneTimeBatchProcessEInvoicesV2Command.php diff --git a/app/Classes/Jobs/Commands/V2/OneTimeBatchProcessEInvoicesV2CommandJob.php b/app/Classes/Jobs/Commands/V2/OneTimeBatchProcessEInvoicesV2CommandJob.php new file mode 100644 index 00000000..26783cbe --- /dev/null +++ b/app/Classes/Jobs/Commands/V2/OneTimeBatchProcessEInvoicesV2CommandJob.php @@ -0,0 +1,44 @@ +booking = $booking; + } + + public function handle() + { + Log::info(Carbon::now() . ': Start job - Processing single booking for E-Invoices for July 2025.'); + $start = new Carbon(); + + $isAllowNormalInvoice = true; + (App()->make(RegenerateInvoiceBookingProcessor::class))->execute($this->booking, $isAllowNormalInvoice); + + $end = new Carbon(); + $elapsedTime = $start->diff($end)->format('%H:%I:%S'); + Log::info(Carbon::now() . ': End job - Processing single booking for E-Invoices for July 2025. ElapsedTime: ' . $elapsedTime . '.'); + } +} diff --git a/app/Classes/Modules/Bookings/Processors/RegenerateInvoiceBookingProcessor.php b/app/Classes/Modules/Bookings/Processors/RegenerateInvoiceBookingProcessor.php index 38d89f08..7b392d08 100644 --- a/app/Classes/Modules/Bookings/Processors/RegenerateInvoiceBookingProcessor.php +++ b/app/Classes/Modules/Bookings/Processors/RegenerateInvoiceBookingProcessor.php @@ -14,6 +14,7 @@ use App\Classes\ValueObjects\Constants\TransactionType; use App\Models\Booking; use App\Models\Transaction; use Illuminate\Support\Carbon; +use Illuminate\Support\Facades\Log; class RegenerateInvoiceBookingProcessor { @@ -48,7 +49,7 @@ class RegenerateInvoiceBookingProcessor $this->createInvoiceTransactionProcessor = $createInvoiceTransactionProcessor; } - public function execute(Booking $booking) + public function execute(Booking $booking, bool $isAllowNormalInvoice = false) { $this->updatesBookingStatus->execute($booking, ApprovalStatus::APPROVED); @@ -58,6 +59,8 @@ class RegenerateInvoiceBookingProcessor ->orderBy('created_at', 'asc') ->first(); + Log::info('RegenerateInvoiceBookingProcessor booking: ' . json_encode($booking->marking)); + // get the first bill_no if($firstInvoice){ $firstBillNo = $firstInvoice->bill_no; @@ -90,10 +93,10 @@ class RegenerateInvoiceBookingProcessor $this->deletesDocument->execute($row); } - $this->createInvoiceTransactionProcessor->execute($booking, $firstBillNo, true); + $this->createInvoiceTransactionProcessor->execute($booking, $firstBillNo, true, $isAllowNormalInvoice); } else { - $this->createInvoiceTransactionProcessor->execute($booking); + $this->createInvoiceTransactionProcessor->execute($booking, "", false, $isAllowNormalInvoice); } } } diff --git a/app/Classes/Modules/Transactions/Processors/CreateInvoiceDocumentProcessor.php b/app/Classes/Modules/Transactions/Processors/CreateInvoiceDocumentProcessor.php index 80f963ca..daf8acce 100644 --- a/app/Classes/Modules/Transactions/Processors/CreateInvoiceDocumentProcessor.php +++ b/app/Classes/Modules/Transactions/Processors/CreateInvoiceDocumentProcessor.php @@ -43,7 +43,7 @@ class CreateInvoiceDocumentProcessor * @return void * @throws \App\Classes\Exceptions\MalformedRequestException */ - public function execute($transaction, $purchaseOrder, $supplier, $document_type, $voucherRedemption = null) + public function execute($transaction, $purchaseOrder, $supplier, $document_type, $voucherRedemption = null, $isAllowNormalInvoice = false) { // calculate current Paid Amount $booking = $transaction->owner_type == Booking::class ? $transaction->owner : null; @@ -87,6 +87,12 @@ class CreateInvoiceDocumentProcessor $lowercaseDocumentType = strtolower($document_type); + if($document_type === DocumentType::EINVOICE){ //July 2025 workaround generate normal invoice instead of E-Invoice + if($isAllowNormalInvoice){ + $lowercaseDocumentType = strtolower(DocumentType::INVOICE); + } + } + $order_pdf = LaravelMpdf::loadView('pages.pdfs.' . $lowercaseDocumentType, [ 'transaction' => $transaction, diff --git a/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessor.php b/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessor.php index e8c7ff21..44f0dbbf 100644 --- a/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessor.php +++ b/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessor.php @@ -21,6 +21,7 @@ use App\Classes\ValueObjects\Constants\DocumentType; use App\Models\Booking; use App\Models\SegmentConstant; use Carbon\Carbon; +use Illuminate\Support\Facades\Log; class CreateInvoiceTransactionProcessor { @@ -89,7 +90,7 @@ class CreateInvoiceTransactionProcessor * @return void * @throws MalformedRequestException */ - public function execute(Booking $booking, String $invoiceNo= "", bool $isAllowEInvoice = false) + public function execute(Booking $booking, String $invoiceNo= "", bool $isAllowEInvoice = false, bool $isAllowNormalInvoice = false) { if ($booking->status === ApprovalStatus::COMPLETED) { @@ -137,11 +138,18 @@ class CreateInvoiceTransactionProcessor } // $eInvoice = true; //cief todo: 90 - for testing + if($isAllowNormalInvoice){ + $invoiceNo = ""; //July 2025 workaround generate normal invoice instead of E-Invoice + } + if($invoiceNo){ $billNumber = $invoiceNo; } else{ $billNUmberPrefix = $eInvoice ? 'EINV-' : 'INV-'; + if($isAllowNormalInvoice){ + $billNUmberPrefix = 'INV-'; //July 2025 workaround generate normal invoice instead of E-Invoice + } $billNumber = $this->generatesTransactionBillNumber->execute($billNUmberPrefix); } @@ -189,7 +197,7 @@ class CreateInvoiceTransactionProcessor if ($eInvoice) { if($isAllowEInvoice){ - $this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::EINVOICE, $voucherRedemption); + $this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::EINVOICE, $voucherRedemption, $isAllowNormalInvoice); } } // invoice diff --git a/app/Console/Commands/V2/OneTimeBatchProcessEInvoicesV2Command.php b/app/Console/Commands/V2/OneTimeBatchProcessEInvoicesV2Command.php new file mode 100644 index 00000000..12c24ea7 --- /dev/null +++ b/app/Console/Commands/V2/OneTimeBatchProcessEInvoicesV2Command.php @@ -0,0 +1,78 @@ +startOfDay(); + $endDate = Carbon::create(2025, 7, 31)->endOfDay(); + + $bookings = Booking::where('status', ApprovalStatus::COMPLETED) + ->whereBetween('created_at', [$startDate, $endDate]) + ->get(); + + $count = 0; + foreach ($bookings as $booking) { + $firstInvoice = $booking->transactions() + ->whereIn('type', [TransactionType::INVOICE]) + ->withTrashed() + ->whereBetween('created_at', [$startDate, $endDate]) + ->orderBy('created_at', 'asc') + ->first(); + + $normalInvoice = $booking->documents()->where('document_type', DocumentType::INVOICE)->first(); + $eInvoice = $booking->documents()->where('document_type', DocumentType::EINVOICE)->first(); + + if($firstInvoice && !$normalInvoice && !$eInvoice){ + OneTimeBatchProcessEInvoicesV2CommandJob::dispatch($booking); + $count++; + Log::info('Processed: ' . $count); + Log::info('Booking ID: ' . $booking->marking . ' | created_at: ' . $booking->created_at); + } + } + } +}