From 6ebc7163500ddea1bb1d45f1625388a5987b48e4 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Wed, 29 Apr 2026 11:03:03 +0800 Subject: [PATCH] Update invoice generate and regenerate business logic --- .../ApprovePurchaseOrderLogic.php | 7 +- ...eatePurchaseOrderFor1688OrderProcessor.php | 2 +- .../RegenerateInvoiceBookingV2Processor.php | 29 +- .../Services/UpdatesBookingInvoiceStatus.php | 2 +- .../CreatePaymentProofDocumentLogic.php | 2 +- .../CreateInvoiceDocumentProcessor.php | 7 + .../CreateInvoiceTransactionV2Processor.php | 423 ++++++++++-------- database/seeds/DummyDataSeeder.php | 2 +- .../BookingDetailsSectionComponent.vue | 6 +- 9 files changed, 262 insertions(+), 218 deletions(-) diff --git a/app/Classes/Modules/Bookings/ControllersLogic/ApprovePurchaseOrderLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/ApprovePurchaseOrderLogic.php index 254779fa..f3063b83 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/ApprovePurchaseOrderLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/ApprovePurchaseOrderLogic.php @@ -67,12 +67,7 @@ class ApprovePurchaseOrderLogic extends AbstractControllerLogic $this->updatesTransactionStatus->execute($purchaseOrder, ApprovalStatus::APPROVED); - if($booking->invoice_status === ApprovalStatus::APPROVED){ - $bookingOriginalStatus = ApprovalStatus::COMPLETED; - } - else{ - $bookingOriginalStatus = $booking->status; - } + $bookingOriginalStatus = $booking->status; $this->createInvoiceTransactionProcessor->execute($booking, "", null, [ 'generateEInvoice' => false, diff --git a/app/Classes/Modules/Bookings/Processors/CreatePurchaseOrderFor1688OrderProcessor.php b/app/Classes/Modules/Bookings/Processors/CreatePurchaseOrderFor1688OrderProcessor.php index 83b25386..96a8bb7f 100644 --- a/app/Classes/Modules/Bookings/Processors/CreatePurchaseOrderFor1688OrderProcessor.php +++ b/app/Classes/Modules/Bookings/Processors/CreatePurchaseOrderFor1688OrderProcessor.php @@ -92,7 +92,7 @@ class CreatePurchaseOrderFor1688OrderProcessor 'generateEInvoice' => false, 'generateEInvoiceWithNormalInvoiceTemplate' => false, 'generateEInvoiceRefund' => false, - 'bookingOriginalStatus' => ApprovalStatus::COMPLETED + 'bookingOriginalStatus' => ApprovalStatus::COMPLETED //cief todo: 151 ] ); } diff --git a/app/Classes/Modules/Bookings/Processors/RegenerateInvoiceBookingV2Processor.php b/app/Classes/Modules/Bookings/Processors/RegenerateInvoiceBookingV2Processor.php index 08f189ef..e5246f32 100644 --- a/app/Classes/Modules/Bookings/Processors/RegenerateInvoiceBookingV2Processor.php +++ b/app/Classes/Modules/Bookings/Processors/RegenerateInvoiceBookingV2Processor.php @@ -52,15 +52,24 @@ class RegenerateInvoiceBookingV2Processor public function execute(Booking $booking, bool $eInvoiceWithNormalInvoiceTemplate = false, - bool $eInvoiceWithRefund = false, bool $eInvoiceTry = false) + bool $eInvoiceWithRefund = false, + bool $eInvoiceTry = false ////cief todo: 151 - getting ready to get rid of eInvoiceTry as a parameter + ) { $bookingOriginalStatus = $booking->status; - if($eInvoiceTry){ - if($booking->invoice_status === ApprovalStatus::APPROVED){ - $bookingOriginalStatus = ApprovalStatus::COMPLETED; - } - } + // Log::info('E-invoice flags', [ + // 'eInvoiceWithNormalInvoiceTemplate' => $eInvoiceWithNormalInvoiceTemplate, + // 'eInvoiceWithRefund' => $eInvoiceWithRefund, + // 'eInvoiceTry' => $eInvoiceTry, + // ]); + + // if($eInvoiceTry){ + // if($booking->invoice_status === ApprovalStatus::APPROVED){ + // // cief todo: must make sure TransactionType::BILL has status Approved (2) + // $bookingOriginalStatus = ApprovalStatus::COMPLETED; + // } + // } if(!$eInvoiceWithRefund){ $this->updatesBookingStatus->execute($booking, ApprovalStatus::APPROVED); @@ -116,9 +125,11 @@ class RegenerateInvoiceBookingV2Processor $this->deletesTransaction->execute($row); } - $kvpCopies = $latestInvoice->attributesKVP->map(function ($kvp) { - return $kvp->replicate(); - }); + if($latestInvoice){ + $kvpCopies = $latestInvoice->attributesKVP->map(function ($kvp) { + return $kvp->replicate(); + }); + } } //for E-INVOICE else { diff --git a/app/Classes/Modules/Bookings/Services/UpdatesBookingInvoiceStatus.php b/app/Classes/Modules/Bookings/Services/UpdatesBookingInvoiceStatus.php index 97342170..01022040 100644 --- a/app/Classes/Modules/Bookings/Services/UpdatesBookingInvoiceStatus.php +++ b/app/Classes/Modules/Bookings/Services/UpdatesBookingInvoiceStatus.php @@ -17,7 +17,7 @@ class UpdatesBookingInvoiceStatus extends AbstractUpdateRecord */ public function execute(Booking $model, UpdateBookingInvoiceStatusObject $object) { - $model->invoice_status = $object->getInvoiceStatus(); + $model->invoice_status = $object->getInvoiceStatus(); //invoice_status first used on Export Sales Invoice Report return $this->handler($model); } } diff --git a/app/Classes/Modules/Transactions/ControllersLogic/CreatePaymentProofDocumentLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/CreatePaymentProofDocumentLogic.php index 99287195..0f729dd2 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/CreatePaymentProofDocumentLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/CreatePaymentProofDocumentLogic.php @@ -95,7 +95,7 @@ class CreatePaymentProofDocumentLogic extends AbstractControllerLogic 'generateEInvoice' => false, 'generateEInvoiceWithNormalInvoiceTemplate' => false, 'generateEInvoiceRefund' => false, - 'bookingOriginalStatus' => ApprovalStatus::COMPLETED + 'bookingOriginalStatus' => ApprovalStatus::COMPLETED //cief todo: 151 ] ); diff --git a/app/Classes/Modules/Transactions/Processors/CreateInvoiceDocumentProcessor.php b/app/Classes/Modules/Transactions/Processors/CreateInvoiceDocumentProcessor.php index 0e6bb95f..fdd9735d 100644 --- a/app/Classes/Modules/Transactions/Processors/CreateInvoiceDocumentProcessor.php +++ b/app/Classes/Modules/Transactions/Processors/CreateInvoiceDocumentProcessor.php @@ -67,6 +67,10 @@ class CreateInvoiceDocumentProcessor } else{ $lastPaymentTransaction = $booking->transactions()->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::COMPLETED, ApprovalStatus::APPROVED])->latest()->first(); + + if(!$lastPaymentTransaction){ + $lastPaymentTransaction = $booking->transactions()->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::REFUNDED])->latest()->first(); + } } $documentDate = $lastPaymentTransaction->created_at; @@ -115,6 +119,9 @@ class CreateInvoiceDocumentProcessor } else{ $payment = $booking->transactions()->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::COMPLETED, ApprovalStatus::APPROVED])->first(); + if(!$payment){ + $payment = $booking->transactions()->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::REFUNDED])->first(); + } } $refundAmount = $payment->transactions()->refunds()->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED])->sum('amount'); diff --git a/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionV2Processor.php b/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionV2Processor.php index c4bf3615..17f32bb8 100644 --- a/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionV2Processor.php +++ b/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionV2Processor.php @@ -14,7 +14,9 @@ use App\Classes\Modules\Bookings\Services\CalculatesBookingPaidAmount; use App\Classes\Modules\Bookings\Services\CalculatesBookingCurrencyAverageRate; use App\Classes\Modules\Companies\Services\FetchesCompany; use App\Classes\Modules\Bookings\Services\UpdatesBookingStatus; +use App\Classes\Modules\Bookings\Services\UpdatesBookingInvoiceStatus; use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject; +use App\Classes\Modules\Bookings\DataTransferObjects\UpdateBookingInvoiceStatusObject; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\SegmentConstants; use App\Classes\ValueObjects\Constants\TransactionType; @@ -53,6 +55,9 @@ class CreateInvoiceTransactionV2Processor /** @var UpdatesBookingStatus */ private $updatesBookingStatus; + /** @var UpdatesBookingInvoiceStatus */ + private $updatesBookingInvoiceStatus; + /** @var CreateInvoiceDocumentProcessor */ private $invoiceDocumentProcessor; @@ -74,8 +79,9 @@ class CreateInvoiceTransactionV2Processor * @param UpdatesBookingStatus $updatesBookingStatus * @param CreateInvoiceDocumentProcessor $invoiceDocumentProcessor * @param CalculatesBookingRefundAmount $calculatesBookingRefundAmount + * @param UpdatesBookingInvoiceStatus $updatesBookingInvoiceStatus */ - public function __construct(ListsTransactions $listsTransactions, CreatesTransaction $createsTransaction, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CalculatesBookingPaidAmount $calculatesBookingPaidAmount, CalculatesBookingPayableAmount $calculatesBookingPayableAmount, CalculatesBookingTransferredAmount $calculatesBookingTransferredAmount, FetchesServiceConfigurations $fetchesServiceConfigurations, CalculatesBookingCurrencyAverageRate $calculatesBookingCurrencyAverageRate, FetchesCompany $fetchesCompany, UpdatesBookingStatus $updatesBookingStatus, CreateInvoiceDocumentProcessor $invoiceDocumentProcessor, CalculatesBookingRefundAmount $calculatesBookingRefundAmount) + public function __construct(ListsTransactions $listsTransactions, CreatesTransaction $createsTransaction, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CalculatesBookingPaidAmount $calculatesBookingPaidAmount, CalculatesBookingPayableAmount $calculatesBookingPayableAmount, CalculatesBookingTransferredAmount $calculatesBookingTransferredAmount, FetchesServiceConfigurations $fetchesServiceConfigurations, CalculatesBookingCurrencyAverageRate $calculatesBookingCurrencyAverageRate, FetchesCompany $fetchesCompany, UpdatesBookingStatus $updatesBookingStatus, CreateInvoiceDocumentProcessor $invoiceDocumentProcessor, CalculatesBookingRefundAmount $calculatesBookingRefundAmount, UpdatesBookingInvoiceStatus $updatesBookingInvoiceStatus) { $this->createsTransaction = $createsTransaction; $this->generatesTransactionBillNumber = $generatesTransactionBillNumber; @@ -87,6 +93,7 @@ class CreateInvoiceTransactionV2Processor $this->updatesBookingStatus = $updatesBookingStatus; $this->invoiceDocumentProcessor = $invoiceDocumentProcessor; $this->calculatesBookingRefundAmount = $calculatesBookingRefundAmount; + $this->updatesBookingInvoiceStatus = $updatesBookingInvoiceStatus; } @@ -106,11 +113,15 @@ class CreateInvoiceTransactionV2Processor $generateEInvoiceRefund = $options['generateEInvoiceRefund'] ?? false; $bookingOriginalStatus = $options['bookingOriginalStatus'] ?? null; + $bookingOriginalStatus = null; //cief todo: 151 - getting ready to get rid of bookingOriginalStatus as an options parameter + // Log::info('CreateInvoiceTransactionV2Processor generateEInvoice:' . json_encode($generateEInvoice)); // Log::info('CreateInvoiceTransactionV2Processor generateEInvoiceWithNormalInvoiceTemplate: ' . json_encode($generateEInvoiceWithNormalInvoiceTemplate)); // Log::info('CreateInvoiceTransactionV2Processor generateEInvoiceRefund: ' . json_encode($generateEInvoiceRefund)); // Log::info('CreateInvoiceTransactionV2Processor bookingOriginalStatus: ' . json_encode($bookingOriginalStatus)); + $proceed = true; + if ($booking->status === ApprovalStatus::COMPLETED && !$generateEInvoiceRefund) { Log::info('CreateInvoiceTransactionV2Processor Check 1 Bypass New Business Logic Update for booking ' . $booking->id); // return; @@ -121,11 +132,14 @@ class CreateInvoiceTransactionV2Processor $booking_amount = $booking->fix_amount; if ((float) $booking_amount === (float) $refund_amount && !$generateEInvoiceRefund) { - return; + Log::info('CreateInvoiceTransactionV2Processor Check 3 Bypass New Business Logic Update for booking ' . $booking->id); + //return; } // confirm that booking amount has been fully paid if ((float) $booking_amount > (float) $payable_amount) { + Log::info('CreateInvoiceTransactionV2Processor return 1'); + $proceed = false; return; } // confirm that all payments has been transferred @@ -134,218 +148,235 @@ class CreateInvoiceTransactionV2Processor // return; } - $purchaseOrder = $booking->transactions() + $completedPurchaseOrder = $booking->transactions() ->where('type', TransactionType::PURCHASE_ORDER) ->complete() ->first(); + $purchaseOrder = $completedPurchaseOrder; - if(!$purchaseOrder && $generateEInvoiceRefund){ - $purchaseOrder = $booking->transactions() - ->where('type', TransactionType::PURCHASE_ORDER) - ->where('status', ApprovalStatus::PENDING_SUBMISSION) - ->first(); - } - - $constants = SegmentConstant::where('reference', SegmentConstants::SERVICE_TYPE)->where('detail->id', $booking->service->id)->first(); - // if ($constants->detail->is_billable && !$purchaseOrder && !$generateEInvoiceRefund) { - // return; - // } - - $transaction = $booking->transactions() - ->where('type', TransactionType::PAYMENT) - ->latest()->get()[0]; - $supplier = $this->fetchesCompany->execute(['id' => $transaction->receiver]); - - // Check if eInvoice implementation has started and company opted in for eInvoice - $eInvoice = false; - $eInvoiceStartDate = Carbon::parse(env('E_INVOICE_START_DATE', '2025-07-01 00:00:00')); - $bookingCreatedDate = Carbon::parse($booking->created_at); - $eInvoiceRequestedDate = Carbon::parse($supplier->e_invoice_requested_at); - - if ($bookingCreatedDate->isAfter($eInvoiceStartDate) && ($bookingCreatedDate->isAfter($eInvoiceRequestedDate) || $bookingCreatedDate->diffInMinutes($eInvoiceRequestedDate) <= 60) && $supplier->e_invoice === 1) { - $eInvoice = true; - } - $kvp = $booking->attributesKVP()->where('key', KVPKey::BOOKING_EINVOICE_ELIGIBLE)->first(); - if($kvp){ - $eInvoice = true; - } - - if($generateEInvoiceWithNormalInvoiceTemplate){ - $invoiceNo = ""; //July 2025 workaround generate normal invoice instead of E-Invoice - } - - if($invoiceNo){ - $billNumber = $invoiceNo; + if($this->calculatesBookingTransferredAmount->execute($booking) === $this->calculatesBookingPaidAmount->execute($booking) && $completedPurchaseOrder) { + $bookingOriginalStatus = ApprovalStatus::COMPLETED; } else{ - $billNUmberPrefix = $eInvoice ? 'EINV-' : 'INV-'; + $bookingOriginalStatus = ApprovalStatus::APPROVED; + } + + if($proceed){ + if(!$purchaseOrder && $generateEInvoiceRefund){ + $purchaseOrder = $booking->transactions() + ->where('type', TransactionType::PURCHASE_ORDER) + ->where('status', ApprovalStatus::PENDING_SUBMISSION) + ->first(); + } + + $constants = SegmentConstant::where('reference', SegmentConstants::SERVICE_TYPE)->where('detail->id', $booking->service->id)->first(); + // if ($constants->detail->is_billable && !$purchaseOrder && !$generateEInvoiceRefund) { + // return; + // } + + $transaction = $booking->transactions() + ->where('type', TransactionType::PAYMENT) + ->latest()->get()[0]; + $supplier = $this->fetchesCompany->execute(['id' => $transaction->receiver]); + + // Check if eInvoice implementation has started and company opted in for eInvoice + $eInvoice = false; + $eInvoiceStartDate = Carbon::parse(env('E_INVOICE_START_DATE', '2025-07-01 00:00:00')); + $bookingCreatedDate = Carbon::parse($booking->created_at); + $eInvoiceRequestedDate = Carbon::parse($supplier->e_invoice_requested_at); + + if ($bookingCreatedDate->isAfter($eInvoiceStartDate) && ($bookingCreatedDate->isAfter($eInvoiceRequestedDate) || $bookingCreatedDate->diffInMinutes($eInvoiceRequestedDate) <= 60) && $supplier->e_invoice === 1) { + $eInvoice = true; + } + $kvp = $booking->attributesKVP()->where('key', KVPKey::BOOKING_EINVOICE_ELIGIBLE)->first(); + if($kvp){ + $eInvoice = true; + } + if($generateEInvoiceWithNormalInvoiceTemplate){ - $billNUmberPrefix = 'INV-'; //July 2025 workaround generate normal invoice instead of E-Invoice + $invoiceNo = ""; //July 2025 workaround generate normal invoice instead of E-Invoice } - $billNumber = $this->generatesTransactionBillNumber->execute($billNUmberPrefix); - } - $booking_currency_average_rate = $this->calculatesBookingCurrencyAverageRate->execute($booking, TransactionType::PAYMENT, $generateEInvoiceRefund); - - if($generateEInvoiceRefund){ - $total_service_charge = $booking->transactions() - ->where('type', TransactionType::PAYMENT) - ->whereIn('status', [ApprovalStatus::REFUNDED]) - ->sum('service_charge'); - - $total_tax = $booking->transactions() - ->where('type', TransactionType::PAYMENT) - ->whereIn('status', [ApprovalStatus::REFUNDED]) - ->sum('tax'); - } - else{ - $total_service_charge = $booking->transactions() - ->where('type', TransactionType::PAYMENT) - ->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]) - ->sum('service_charge'); - - $total_tax = $booking->transactions() - ->where('type', TransactionType::PAYMENT) - ->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]) - ->sum('tax'); - } - - $invoice_transaction = null; - if($booking->status === ApprovalStatus::APPROVED){ - //NEW INVOICE for non-einvoice user applicable only when booking is completed - $invoice_transaction = $booking->transactions() - ->where('type', TransactionType::INVOICE) - ->complete() - ->latest() - ->first(); - } - - if(!$invoice_transaction) { - $transaction_object = new TransactionObject( - $billNumber, - TransactionType::INVOICE, - $transaction->issuer, - $transaction->receiver, - $transaction->recipient_bank_account_id, - $transaction->payment_method, - $payable_amount, - $booking_amount, - $transaction->currency_id, - $transaction->original_currency_id, - $booking_currency_average_rate, - $total_tax, - $total_service_charge, - null, - ApprovalStatus::APPROVED - ); - $invoice_transaction = $this->createsTransaction->execute($purchaseOrder->booking ?? $booking, $transaction_object); - } - - //Update booking table, used on Export Sales Invoice Report - $booking->invoice_status = ApprovalStatus::APPROVED; - $booking->save(); - - if ($kvpCopies) { - foreach ($kvpCopies as $kvp) { - $invoice_transaction->attributesKVP()->save($kvp); - } - } - - $voucherRedemption = $transaction->voucherRedemption; - - if($generateEInvoiceRefund){ - $metadata = $booking->attributesKVP()->where('key', KVPKey::AUTOCOUNT_DOCNO_INVOICE)->first(); - if($metadata){ - $generateEInvoice = true; + if($invoiceNo){ + $billNumber = $invoiceNo; } else{ - $metadata = $transaction->attributesKVP()->where('key', KVPKey::AUTOCOUNT_DOCNO_INVOICE)->first(); + $billNUmberPrefix = $eInvoice ? 'EINV-' : 'INV-'; + if($generateEInvoiceWithNormalInvoiceTemplate){ + $billNUmberPrefix = 'INV-'; //July 2025 workaround generate normal invoice instead of E-Invoice + } + $billNumber = $this->generatesTransactionBillNumber->execute($billNUmberPrefix); + } + + $booking_currency_average_rate = $this->calculatesBookingCurrencyAverageRate->execute($booking, TransactionType::PAYMENT, $generateEInvoiceRefund); + + if($generateEInvoiceRefund){ + $total_service_charge = $booking->transactions() + ->where('type', TransactionType::PAYMENT) + ->whereIn('status', [ApprovalStatus::REFUNDED]) + ->sum('service_charge'); + + $total_tax = $booking->transactions() + ->where('type', TransactionType::PAYMENT) + ->whereIn('status', [ApprovalStatus::REFUNDED]) + ->sum('tax'); + } + else{ + $total_service_charge = $booking->transactions() + ->where('type', TransactionType::PAYMENT) + ->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]) + ->sum('service_charge'); + + $total_tax = $booking->transactions() + ->where('type', TransactionType::PAYMENT) + ->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]) + ->sum('tax'); + } + + $invoice_transaction = null; + if($booking->status === ApprovalStatus::APPROVED){ + //NEW INVOICE for non-einvoice user applicable only when booking is completed + $invoice_transaction = $booking->transactions() + ->where('type', TransactionType::INVOICE) + ->complete() + ->latest() + ->first(); + } + + if(!$invoice_transaction) { + $transaction_object = new TransactionObject( + $billNumber, + TransactionType::INVOICE, + $transaction->issuer, + $transaction->receiver, + $transaction->recipient_bank_account_id, + $transaction->payment_method, + $payable_amount, + $booking_amount, + $transaction->currency_id, + $transaction->original_currency_id, + $booking_currency_average_rate, + $total_tax, + $total_service_charge, + null, + ApprovalStatus::APPROVED + ); + $invoice_transaction = $this->createsTransaction->execute($purchaseOrder->booking ?? $booking, $transaction_object); + } + + if ($kvpCopies) { + foreach ($kvpCopies as $kvp) { + $invoice_transaction->attributesKVP()->save($kvp); + } + } + + $voucherRedemption = $transaction->voucherRedemption; + + if($generateEInvoiceRefund){ + $metadata = $booking->attributesKVP()->where('key', KVPKey::AUTOCOUNT_DOCNO_INVOICE)->first(); if($metadata){ - $generateEInvoice = true; + $generateEInvoice = true; + } + else{ + $metadata = $transaction->attributesKVP()->where('key', KVPKey::AUTOCOUNT_DOCNO_INVOICE)->first(); + if($metadata){ + $generateEInvoice = true; + } + } + } + + if($purchaseOrder){ + // purchase order + if(!$generateEInvoiceRefund){ + $this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::PURCHASE_ORDER, $voucherRedemption, $generateEInvoiceWithNormalInvoiceTemplate); + } + + // deliver order + if(!$generateEInvoiceRefund){ + $this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::DELIVER_ORDER, $voucherRedemption, $generateEInvoiceWithNormalInvoiceTemplate); + } + + // e-invoice + if ($eInvoice) + { + if($generateEInvoice){ + $this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::EINVOICE, $voucherRedemption, $generateEInvoiceWithNormalInvoiceTemplate, $generateEInvoiceRefund); + } + } + // invoice + else + { + $this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::INVOICE, $voucherRedemption, $generateEInvoiceWithNormalInvoiceTemplate, $generateEInvoiceRefund); + } + + if(!$generateEInvoiceRefund){ + $billNumber = $this->generatesTransactionBillNumber->execute('SPDO-'); + + $booking_currency_average_rate = $this->calculatesBookingCurrencyAverageRate->execute($booking, TransactionType::BILL, $generateEInvoiceRefund); + + $paymentTransaction = $booking->transactions()->payments()->where('status', ApprovalStatus::COMPLETED)->first(); + + $transactionTypeBill= null; + if($paymentTransaction){ + $transactionTypeBill = $paymentTransaction->transactions()->where('type', TransactionType::BILL)->first(); + } + else{ // Special handling for refund cases (When a refund is deleted via DeleteRefundTransactionLogic, a booking payment transaction is set to ApprovalStatus::APPROVED) + $paymentTransactionTemp = $booking->transactions()->payments()->where('status', ApprovalStatus::APPROVED)->first(); + + // Lets check if there is a full refund case + if(!$paymentTransactionTemp){ + $paymentTransactionTemp = $booking->transactions()->payments()->where('status', ApprovalStatus::REFUNDED)->first(); + Log::info('CreateInvoiceTransactionV2Processor full refund: ' . json_encode($paymentTransactionTemp)); + } + + // Lets check if there is a partial refund case + $refund = $paymentTransactionTemp->transactions()->refunds()->where('status', ApprovalStatus::APPROVED)->first(); + if($refund){ + Log::info('CreateInvoiceTransactionV2Processor partial refund: ' . json_encode($refund)); + $transactionTypeBill = $paymentTransactionTemp->transactions()->where('type', TransactionType::BILL)->first(); + } + else{ + Log::info("CreateInvoiceTransactionV2Processor NO completed payment transaction nor refund transaction found for booking '$booking->id'."); + } + } + + if($transactionTypeBill){ + $transaction_object = new TransactionObject( + $billNumber, + TransactionType::SUPPLIER_DELIVER, + $transactionTypeBill->issuer, + $transactionTypeBill->receiver, + $transactionTypeBill->recipient_bank_account_id, + $transactionTypeBill->payment_method, + $payable_amount, + $booking_amount, + $transactionTypeBill->currency_id, + $transactionTypeBill->original_currency_id, + $booking_currency_average_rate, + $total_tax, + $total_service_charge, + null, + ApprovalStatus::APPROVED + ); + $supplier_deliver_order_transaction = $this->createsTransaction->execute($purchaseOrder->booking, $transaction_object); + + // supply deliver order + $this->invoiceDocumentProcessor->execute($supplier_deliver_order_transaction, $purchaseOrder, $supplier, DocumentType::SUPPLIER_DELIVER_ORDER, null); + } } } } - if($purchaseOrder){ - // purchase order - if(!$generateEInvoiceRefund){ - $this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::PURCHASE_ORDER, $voucherRedemption, $generateEInvoiceWithNormalInvoiceTemplate); - } + $this->updateStatuses($booking, $bookingOriginalStatus ?? 0); + } - // deliver order - if(!$generateEInvoiceRefund){ - $this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::DELIVER_ORDER, $voucherRedemption, $generateEInvoiceWithNormalInvoiceTemplate); - } + //Update booking overall status and invoice status + public function updateStatuses(Booking $booking, int $bookingStatus){ + $updateBookingInvoiceStatusObject = new UpdateBookingInvoiceStatusObject($booking->id, ApprovalStatus::APPROVED); + $this->updatesBookingInvoiceStatus->execute($booking, $updateBookingInvoiceStatusObject); - // e-invoice - if ($eInvoice) - { - if($generateEInvoice){ - $this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::EINVOICE, $voucherRedemption, $generateEInvoiceWithNormalInvoiceTemplate, $generateEInvoiceRefund); - } - } - // invoice - else - { - $this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::INVOICE, $voucherRedemption, $generateEInvoiceWithNormalInvoiceTemplate, $generateEInvoiceRefund); - } - - if(!$generateEInvoiceRefund){ - $billNumber = $this->generatesTransactionBillNumber->execute('SPDO-'); - - $booking_currency_average_rate = $this->calculatesBookingCurrencyAverageRate->execute($booking, TransactionType::BILL, $generateEInvoiceRefund); - - $paymentTransaction = $booking->transactions()->payments()->where('status', ApprovalStatus::COMPLETED)->first(); - - $transactionTypeBill= null; - if($paymentTransaction){ - $transactionTypeBill = $paymentTransaction->transactions()->where('type', TransactionType::BILL)->first(); - } - else{ // Special handling for refund cases (When a refund is deleted via DeleteRefundTransactionLogic, a booking payment transaction is set to ApprovalStatus::APPROVED) - $paymentTransactionTemp = $booking->transactions()->payments()->where('status', ApprovalStatus::APPROVED)->first(); - // Lets check if there is a refund case - $refund = $paymentTransactionTemp->transactions()->refunds()->where('status', ApprovalStatus::APPROVED)->first(); - if($refund){ - $transactionTypeBill = $paymentTransactionTemp->transactions()->where('type', TransactionType::BILL)->first(); - } - else{ - Log::info("CreateInvoiceTransactionV2Processor NO completed payment transaction nor refund transaction found for booking '$booking->id'."); - } - } - - if($transactionTypeBill){ - $transaction_object = new TransactionObject( - $billNumber, - TransactionType::SUPPLIER_DELIVER, - $transactionTypeBill->issuer, - $transactionTypeBill->receiver, - $transactionTypeBill->recipient_bank_account_id, - $transactionTypeBill->payment_method, - $payable_amount, - $booking_amount, - $transactionTypeBill->currency_id, - $transactionTypeBill->original_currency_id, - $booking_currency_average_rate, - $total_tax, - $total_service_charge, - null, - ApprovalStatus::APPROVED - ); - $supplier_deliver_order_transaction = $this->createsTransaction->execute($purchaseOrder->booking, $transaction_object); - - // supply deliver order - $this->invoiceDocumentProcessor->execute($supplier_deliver_order_transaction, $purchaseOrder, $supplier, DocumentType::SUPPLIER_DELIVER_ORDER, null); - } - } - - // update perfex crm - // if(config('perfexcrm.is_enabled') == 'true'){ - // CreatePerfexCRMInvoice::dispatch($invoice_transaction, $purchaseOrder, $supplier); - // } - } - - if($bookingOriginalStatus){ - $this->updatesBookingStatus->execute($booking, $bookingOriginalStatus); + if($bookingStatus){ + $this->updatesBookingStatus->execute($booking, $bookingStatus); } } } diff --git a/database/seeds/DummyDataSeeder.php b/database/seeds/DummyDataSeeder.php index 328dcc15..9270f25c 100644 --- a/database/seeds/DummyDataSeeder.php +++ b/database/seeds/DummyDataSeeder.php @@ -683,7 +683,7 @@ class DummyDataSeeder extends Seeder 'generateEInvoice' => false, 'generateEInvoiceWithNormalInvoiceTemplate' => false, 'generateEInvoiceRefund' => false, - 'bookingOriginalStatus' => ApprovalStatus::COMPLETED + 'bookingOriginalStatus' => ApprovalStatus::COMPLETED //cief todo: 151 ] ); } diff --git a/resources/assets/vue/components/bookings/sections/BookingDetailsSectionComponent.vue b/resources/assets/vue/components/bookings/sections/BookingDetailsSectionComponent.vue index 39b90359..d392a7fe 100644 --- a/resources/assets/vue/components/bookings/sections/BookingDetailsSectionComponent.vue +++ b/resources/assets/vue/components/bookings/sections/BookingDetailsSectionComponent.vue @@ -413,7 +413,7 @@
-
Regenerate E-Invoice
(Refund)
+
Regen Norm Inv/E-Inv
(Refund)
@@ -427,14 +427,14 @@
-
+
Regenerate Normal Inv