From cc1037d6116b1a4e14d2fcd4c004af98ba68360c Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Tue, 26 Aug 2025 07:49:14 +0800 Subject: [PATCH 1/2] E-Invoice - Automapping Issues, Exchange Wallet Top Up - AR Deposit Entry Report (Export) --- .../ExportsWalletTopUpDepositEntryReport.php | 81 +++++++++++++++++++ .../Controllers/Exports/ExportController.php | 7 ++ .../elements/DownloadUploadComponent.vue | 2 + routes/export.php | 1 + 4 files changed, 91 insertions(+) create mode 100644 app/Classes/Modules/Exports/Services/ExportsWalletTopUpDepositEntryReport.php diff --git a/app/Classes/Modules/Exports/Services/ExportsWalletTopUpDepositEntryReport.php b/app/Classes/Modules/Exports/Services/ExportsWalletTopUpDepositEntryReport.php new file mode 100644 index 00000000..a244de73 --- /dev/null +++ b/app/Classes/Modules/Exports/Services/ExportsWalletTopUpDepositEntryReport.php @@ -0,0 +1,81 @@ +startDate = $startDate ? Carbon::parse($startDate)->startOfDay() : Carbon::now()->subMonths(1); + $this->endDate = $endDate ? Carbon::parse($endDate)->endOfDay() : Carbon::now(); + } + + public function headings(): array + { + return [ + 'DocNo', + 'DebtorCode', + 'DocDate', + 'Description', + 'DeptNo', + 'DepositPaymentMethod', + 'CurrencyCode', + 'PaymentMethod', + 'PaymentAmt', + ]; + } + + /** + * @return \Illuminate\Support\Collection|mixed + */ + public function query() + { + $type = TransactionType::TOP_UP; + $query = Transaction::query(); + $query->where('owner_type', Wallet::class); + $query->where('type', $type); + $query->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); + $query->whereBetween('created_at', [$this->startDate, $this->endDate]); + + return $query; + } + + /** + * @param Transaction $transaction + * @return array + */ + public function map($transaction): array + { + $formattedDocumentDate = Carbon::parse($transaction->created_at)->format('m/d/Y'); + $owner = $transaction->owner; + $company = $owner->owner; + return [ + '<>', //DocNo + $company ? $company->debtor : '', //DebtorCode + $formattedDocumentDate, //DocDate + 'Wallet Deposit', //Description + 'C', //DeptNo + 'WALLET DEPOSIT - EXC', //DepositPaymentMethod + 'MYR', //CurrencyCode + 'MBB', //PaymentMethod + number_format($transaction->amount, 2), //PaymentAmt + ]; + } +} diff --git a/app/Http/Controllers/Exports/ExportController.php b/app/Http/Controllers/Exports/ExportController.php index 3e482509..89d67322 100644 --- a/app/Http/Controllers/Exports/ExportController.php +++ b/app/Http/Controllers/Exports/ExportController.php @@ -12,6 +12,7 @@ use App\Classes\Modules\Exports\Services\ExportsARCreditNoteReport; use App\Classes\Modules\Exports\Services\ExportsCompanies; use App\Classes\Modules\Exports\Services\ExportsReceivePaymentDepositEntryReport; use App\Classes\Modules\Exports\Services\ExportsReceivePaymentForBookingReport; +use App\Classes\Modules\Exports\Services\ExportsWalletTopUpDepositEntryReport; use Carbon\Carbon; class ExportController @@ -46,6 +47,12 @@ class ExportController return $this->handleExport($exporter, '01R- RECEIVE PAYMENT (FULL PAYMENT) [AR RECEIVE PAYMENT].xls'); } + public function walletTopUpDepositEntry(Request $request){ + [$startDate, $endDate] = $this->getValidatedDates($request); + $exporter = new ExportsWalletTopUpDepositEntryReport($startDate, $endDate); + return $this->handleExport($exporter, 'Exchange Wallet Top Up - AR Deposit Entry.xls'); + } + private function getValidatedDates(Request $request): array { $validated = $request->validate([ diff --git a/resources/assets/vue/components/bookings/elements/DownloadUploadComponent.vue b/resources/assets/vue/components/bookings/elements/DownloadUploadComponent.vue index c43d73dc..32e62f4d 100644 --- a/resources/assets/vue/components/bookings/elements/DownloadUploadComponent.vue +++ b/resources/assets/vue/components/bookings/elements/DownloadUploadComponent.vue @@ -142,6 +142,7 @@ export default { '01D - RECEIVE PAYMENT (FULL PAYMENT) [AR DEPOSIT ENTRY]', '01R - RECEIVE PAYMENT (FULL PAYMENT) [AR RECEIVE PAYMENT]', 'Credit Note Report', + 'Wallet Top Up Report', ]; }, handleExportClick(){ @@ -156,6 +157,7 @@ export default { '01D - RECEIVE PAYMENT (FULL PAYMENT) [AR DEPOSIT ENTRY]': route('api.export.transactions.receive_payment_deposit_entry'), '01R - RECEIVE PAYMENT (FULL PAYMENT) [AR RECEIVE PAYMENT]': route('api.export.transactions.receive_payment_for_booking'), 'Credit Note Report': route('api.export.transactions.ar_credit_note'), + 'Wallet Top Up Report': route('api.export.transactions.wallet_top_up_deposit_entry'), }; let url = `${routesMap[reportType]}?startDate=${this.parameters.startDate}&endDate=${this.parameters.endDate}`; diff --git a/routes/export.php b/routes/export.php index 4b1c2576..c9068ccb 100644 --- a/routes/export.php +++ b/routes/export.php @@ -16,6 +16,7 @@ Route::group(['prefix' => 'export', 'as' => 'export.', 'namespace' => 'Exports'] Route::get('/ar-credit-note', [ExportController::class, 'arCreditNote'])->name('ar_credit_note'); Route::get('/receive-payment-deposit-entry', [ExportController::class, 'receivePaymentDepositEntry'])->name('receive_payment_deposit_entry'); Route::get('/receive-payment-for-booking', [ExportController::class, 'receivePaymentDepositForBooking'])->name('receive_payment_for_booking'); + Route::get('/wallet-top-up-deposit-entry', [ExportController::class, 'walletTopUpDepositEntry'])->name('wallet_top_up_deposit_entry'); }); }); From 8fb9a19e41ee716476d170d8f835c7656caea294 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Mon, 8 Sep 2025 17:06:28 +0800 Subject: [PATCH 2/2] E-Invoice - PM request for E-Invoice to use amended document date when import with autocount data --- .../ProcessSalesInvoiceReportV2CommandJob.php | 13 +++++++- .../CreateInvoiceDocumentProcessor.php | 13 +++++--- .../ValueObjects/Constants/DocumentType.php | 2 +- app/Classes/ValueObjects/Constants/KVPKey.php | 2 ++ .../BookingDetailsSectionComponent.vue | 13 ++++++-- .../views/pages/pdfs/e_invoice.blade.php | 31 ++++++++++--------- 6 files changed, 49 insertions(+), 25 deletions(-) diff --git a/app/Classes/Jobs/Commands/V2/ProcessSalesInvoiceReportV2CommandJob.php b/app/Classes/Jobs/Commands/V2/ProcessSalesInvoiceReportV2CommandJob.php index d96fa761..66a4d457 100644 --- a/app/Classes/Jobs/Commands/V2/ProcessSalesInvoiceReportV2CommandJob.php +++ b/app/Classes/Jobs/Commands/V2/ProcessSalesInvoiceReportV2CommandJob.php @@ -15,7 +15,7 @@ use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; use App\Models\Booking; use Illuminate\Support\Facades\Log; - +use PhpOffice\PhpSpreadsheet\Shared\Date; class ProcessSalesInvoiceReportV2CommandJob implements ShouldQueue { @@ -81,6 +81,9 @@ class ProcessSalesInvoiceReportV2CommandJob implements ShouldQueue if($eInvoiceValidationLink){ $this->updateOrCreateKeyValuePair($booking, KVPKey::AUTOCOUNT_EINVOICE_VALIDATION_LINK, $eInvoiceValidationLink); } + if($docDate){ + $this->updateOrCreateKeyValuePair($booking, KVPKey::AUTOCOUNT_DOCDATE_INVOICE, is_numeric($docDate) ? $this->convertDocDateToString($docDate) : $docDate); + } } $end = new Carbon(); @@ -100,4 +103,12 @@ class ProcessSalesInvoiceReportV2CommandJob implements ShouldQueue (App()->make(CreatesKeyValuePair::class))->execute($booking, $keyValuePairObject); } } + + private function convertDocDateToString($value, $format = 'm/d/Y') { + if (is_numeric($value)) { + return Carbon::instance(Date::excelToDateTimeObject($value))->format($format); + } + + return Carbon::parse($value)->format($format); + } } diff --git a/app/Classes/Modules/Transactions/Processors/CreateInvoiceDocumentProcessor.php b/app/Classes/Modules/Transactions/Processors/CreateInvoiceDocumentProcessor.php index 96e64155..6e746415 100644 --- a/app/Classes/Modules/Transactions/Processors/CreateInvoiceDocumentProcessor.php +++ b/app/Classes/Modules/Transactions/Processors/CreateInvoiceDocumentProcessor.php @@ -63,9 +63,6 @@ class CreateInvoiceDocumentProcessor if ($bookingCreatedDate->isAfter($eInvoiceStartDate)) { $lastPaymentTransaction = $booking->transactions()->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::COMPLETED, ApprovalStatus::APPROVED])->latest()->first(); $documentDate = $lastPaymentTransaction->created_at; - // if(Carbon::parse($booking->updated_at)->isAfter($lastPaymentTransaction->created_at)){ //cief todo: 90 - Batch generate E-Invoice date incorrect - // $documentDate = $booking->updated_at; - // } } if($document_type === DocumentType::EINVOICE){ @@ -77,8 +74,14 @@ class CreateInvoiceDocumentProcessor if($metadata){ $autoCountEInvoiceValidationLink = $metadata->value; } - $lastDayOfMonth = $documentDate->copy()->endOfMonth(); - $documentDate = $lastDayOfMonth; + $metadata = $booking->attributesKVP()->where('key', KVPKey::AUTOCOUNT_DOCDATE_INVOICE)->first(); + if($metadata){ + $documentDate = Carbon::parse($metadata->value); + } + else{ + $lastDayOfMonth = $documentDate->copy()->endOfMonth(); + $documentDate = $lastDayOfMonth; + } } $payment = $booking->transactions()->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::COMPLETED, ApprovalStatus::APPROVED])->first(); $refundAmount = $payment->transactions()->refunds()->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED])->sum('amount'); diff --git a/app/Classes/ValueObjects/Constants/DocumentType.php b/app/Classes/ValueObjects/Constants/DocumentType.php index b11b6874..91ff84bb 100644 --- a/app/Classes/ValueObjects/Constants/DocumentType.php +++ b/app/Classes/ValueObjects/Constants/DocumentType.php @@ -29,5 +29,5 @@ final class DocumentType { public const BILL_GROUP_PAYMENT_PROOF = 'BILL_GROUP_PAYMENT_PROOF'; public const RECEIPT_VOUCHER = 'RECEIPT_VOUCHER'; - public const EINVOICE = 'E_INVOICE'; //cief todo: 90 - why is there no E-CREDITNOTE + public const EINVOICE = 'E_INVOICE'; } diff --git a/app/Classes/ValueObjects/Constants/KVPKey.php b/app/Classes/ValueObjects/Constants/KVPKey.php index 7a8b42ae..a5f2cf64 100644 --- a/app/Classes/ValueObjects/Constants/KVPKey.php +++ b/app/Classes/ValueObjects/Constants/KVPKey.php @@ -10,6 +10,8 @@ class KVPKey public const AUTOCOUNT_DOCNO_OFFICIAL_RECEIPT = 'AUTOCOUNT_DOCNO_OR'; + public const AUTOCOUNT_DOCDATE_INVOICE = 'AUTOCOUNT_DOCDATE_I'; + public const AUTOCOUNT_EINVOICE_VALIDATION_LINK = 'AUTOCOUNT_EINVOICE_VALIDATION_LINK'; public const CREDIT_NOTE_APPROVAL_DATE = 'CREDIT_NOTE_APPROVAL_DATE'; diff --git a/resources/assets/vue/components/bookings/sections/BookingDetailsSectionComponent.vue b/resources/assets/vue/components/bookings/sections/BookingDetailsSectionComponent.vue index c7717536..271826ff 100644 --- a/resources/assets/vue/components/bookings/sections/BookingDetailsSectionComponent.vue +++ b/resources/assets/vue/components/bookings/sections/BookingDetailsSectionComponent.vue @@ -46,7 +46,7 @@ -
+
+
+
+ +
+

E-Invoice (Pending)

+
@@ -626,8 +635,6 @@ display: inline-block; text-align: center; } - - /* cief todo: 90 - to be continue */ .disabled-block { opacity: 0.5; pointer-events: none; diff --git a/resources/views/pages/pdfs/e_invoice.blade.php b/resources/views/pages/pdfs/e_invoice.blade.php index e5ddcb49..9c7dce39 100644 --- a/resources/views/pages/pdfs/e_invoice.blade.php +++ b/resources/views/pages/pdfs/e_invoice.blade.php @@ -92,21 +92,22 @@ - - - - - - - - - - -
- -
-

{{ $autocountEInvoiceValidationLink }}

-
+ +
+ + + +
+ {{ $autocountEInvoiceValidationLink }} +
+