From d215e5558d13d017db25fe2eec6d2befacfde2e9 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Fri, 12 Sep 2025 12:59:34 +0800 Subject: [PATCH] E-Invoice - Enhancement to allow EInvoice to be generated for cases with refund --- .../RegenerateInvoiceBookingLogic.php | 23 +- .../RegenerateInvoiceBookingV2Processor.php | 118 +++++++ .../CalculatesBookingCurrencyAverageRate.php | 17 +- .../CalculatesBookingPayableAmount.php | 11 +- .../CreateInvoiceDocumentProcessor.php | 23 +- .../CreateInvoiceTransactionV2Processor.php | 303 ++++++++++++++++++ .../RegenerateEInvoiceRefundComponent.vue | 43 +++ .../BookingDetailsSectionComponent.vue | 62 +++- .../views/pages/pdfs/e_invoice.blade.php | 2 +- .../pages/pdfs/purchase_order_table.blade.php | 75 +++-- 10 files changed, 630 insertions(+), 47 deletions(-) create mode 100644 app/Classes/Modules/Bookings/Processors/RegenerateInvoiceBookingV2Processor.php create mode 100644 app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionV2Processor.php create mode 100644 resources/assets/vue/components/bookings/forms/RegenerateEInvoiceRefundComponent.vue diff --git a/app/Classes/Modules/Bookings/ControllersLogic/RegenerateInvoiceBookingLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/RegenerateInvoiceBookingLogic.php index bf88251f..486912a5 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/RegenerateInvoiceBookingLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/RegenerateInvoiceBookingLogic.php @@ -6,10 +6,12 @@ use App\Classes\General\Abstracts\AbstractControllerLogic; use App\Classes\Modules\Bookings\Services\FetchesBooking; use App\Classes\Modules\Bookings\Standards\Rules\CanFetchBooking; use App\Classes\Modules\Bookings\Processors\RegenerateInvoiceBookingProcessor; +use App\Classes\Modules\Bookings\Processors\RegenerateInvoiceBookingV2Processor; use App\Http\Resources\BookingResource; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use App\Classes\ValueObjects\Constants\ApprovalStatus; +use Illuminate\Support\Facades\Log; class RegenerateInvoiceBookingLogic extends AbstractControllerLogic { @@ -34,20 +36,26 @@ class RegenerateInvoiceBookingLogic extends AbstractControllerLogic /** @var RegenerateInvoiceBookingProcessor */ private $regenerateInvoiceBookingProcessor; + /** @var RegenerateInvoiceBookingV2Processor */ + private $regenerateInvoiceBookingV2Processor; + /** * RegenerateInvoiceBookingLogic constructor. * @param CanFetchBooking $canFetchBooking * @param FetchesBooking $fetchesBooking * @param RegenerateInvoiceBookingProcessor $regenerateInvoiceBookingProcessor + * @param RegenerateInvoiceBookingV2Processor $regenerateInvoiceBookingV2Processor */ public function __construct( CanFetchBooking $canFetchBooking, FetchesBooking $fetchesBooking, - RegenerateInvoiceBookingProcessor $regenerateInvoiceBookingProcessor + RegenerateInvoiceBookingProcessor $regenerateInvoiceBookingProcessor, + RegenerateInvoiceBookingV2Processor $regenerateInvoiceBookingV2Processor ) { $this->canFetchBooking = $canFetchBooking; $this->fetchesBooking = $fetchesBooking; $this->regenerateInvoiceBookingProcessor = $regenerateInvoiceBookingProcessor; + $this->regenerateInvoiceBookingV2Processor = $regenerateInvoiceBookingV2Processor; } @@ -65,13 +73,20 @@ class RegenerateInvoiceBookingLogic extends AbstractControllerLogic $booking = $this->fetchesBooking->execute( [ 'id' => $request->route('id'), - 'status' => ApprovalStatus::COMPLETED, + // 'status' => ApprovalStatus::COMPLETED, //cief todo: 90 - must have completed to avoid generate invoice inaccurately 'with_transactions' => true ] ); - $normalInvoice = $request->input('normal_invoice', false); - $this->regenerateInvoiceBookingProcessor->execute($booking, $normalInvoice); + $eInvoiceWithNormalInvoiceTemplate = $request->input('normal_invoice', false); + $eInvoiceRefund = $request->input('e_invoice_refund', false); + + // if($eInvoiceRefund){ + $this->regenerateInvoiceBookingV2Processor->execute($booking, $eInvoiceWithNormalInvoiceTemplate, $eInvoiceRefund); + // } + // else{ + // $this->regenerateInvoiceBookingProcessor->execute($booking, $eInvoiceWithNormalInvoiceTemplate); + // } return $this->resourceResponse(new BookingResource($booking)); } diff --git a/app/Classes/Modules/Bookings/Processors/RegenerateInvoiceBookingV2Processor.php b/app/Classes/Modules/Bookings/Processors/RegenerateInvoiceBookingV2Processor.php new file mode 100644 index 00000000..bbec8757 --- /dev/null +++ b/app/Classes/Modules/Bookings/Processors/RegenerateInvoiceBookingV2Processor.php @@ -0,0 +1,118 @@ +deletesTransaction = $deletesTransaction; + $this->updatesBookingStatus = $updatesBookingStatus; + $this->deletesDocument = $deletesDocument; + $this->createInvoiceTransactionProcessor = $createInvoiceTransactionProcessor; + } + + public function execute(Booking $booking, + bool $eInvoiceWithNormalInvoiceTemplate = false, + bool $eInvoiceWithRefund = false) + { + $bookingOriginalStatus = $booking->status; + + if(!$eInvoiceWithRefund){ + $this->updatesBookingStatus->execute($booking, ApprovalStatus::APPROVED); + } + + $firstInvoice = $booking->transactions() + ->whereIn('type', [TransactionType::INVOICE]) + ->withTrashed() + ->orderBy('created_at', 'asc') + ->first(); + + Log::info('RegenerateInvoiceBookingV2Processor booking: ' . json_encode($booking->marking)); + + // get the first bill_no + if($firstInvoice){ + $firstBillNo = $firstInvoice->bill_no; + if (strpos($firstBillNo, '-deleted') !== false) { + $firstBillNo = substr($firstBillNo, 0, strpos($firstBillNo, '-deleted')); + } + + // update currentInvoice bill_no to '-deleted-' + $currentInvoice = $booking->transactions()->where('type', TransactionType::INVOICE)->first(); + if($currentInvoice){ + $currentInvoice->bill_no = $currentInvoice->bill_no ."-deleted-" . (string)(Carbon::now()->timestamp); + $currentInvoice->save(); + } + + $transactionWithSameBillNo = Transaction::where('bill_no', $firstBillNo)->withTrashed()->get(); + if ($transactionWithSameBillNo) { + foreach ($transactionWithSameBillNo as $transaction) { + $transaction->bill_no = $transaction->bill_no . "-deleted-" . Str::random(10); + $transaction->save(); + } + } + + $transaction = $booking->transactions()->whereIn('type', [TransactionType::INVOICE, TransactionType::SUPPLIER_DELIVER])->get(); + foreach ($transaction as $key => $row) { + $this->deletesTransaction->execute($row); + } + + $document = $booking->documents()->whereIn('document_type', [DocumentType::PURCHASE_ORDER, DocumentType::INVOICE, DocumentType::EINVOICE, DocumentType::DELIVER_ORDER, DocumentType::SUPPLIER_DELIVER_ORDER])->get(); + foreach ($document as $key => $row) { + $this->deletesDocument->execute($row); + } + + $this->createInvoiceTransactionProcessor->execute($booking, $firstBillNo, [ + 'generateEInvoice' => true, + 'generateEInvoiceWithNormalInvoiceTemplate' => $eInvoiceWithNormalInvoiceTemplate, + 'generateEInvoiceRefund' => $eInvoiceWithRefund, + 'bookingOriginalStatus' => $bookingOriginalStatus + ]); + } + else { + $this->createInvoiceTransactionProcessor->execute($booking, "", [ + 'generateEInvoice' => false, + 'generateEInvoiceWithNormalInvoiceTemplate' => $eInvoiceWithNormalInvoiceTemplate, + 'generateEInvoiceRefund' => $eInvoiceWithRefund, + 'bookingOriginalStatus' => $bookingOriginalStatus + ]); + } + } +} diff --git a/app/Classes/Modules/Bookings/Services/CalculatesBookingCurrencyAverageRate.php b/app/Classes/Modules/Bookings/Services/CalculatesBookingCurrencyAverageRate.php index 9cb7717e..aaa3e569 100644 --- a/app/Classes/Modules/Bookings/Services/CalculatesBookingCurrencyAverageRate.php +++ b/app/Classes/Modules/Bookings/Services/CalculatesBookingCurrencyAverageRate.php @@ -22,7 +22,7 @@ class CalculatesBookingCurrencyAverageRate } - public function execute(Booking $booking, $type){ + public function execute(Booking $booking, $type, bool $generateEInvoiceRefund = false){ $transaction = $booking->transactions() ->where('type', TransactionType::PAYMENT) @@ -37,9 +37,16 @@ class CalculatesBookingCurrencyAverageRate } if ($type == TransactionType::PAYMENT) { - $totalPayment = $booking->fix_currency_id === 1 ? $booking->transactions()->payments()->complete()->sum('original_amount') : - $booking->transactions()->payments()->complete()->selectRaw('sum(amount - service_charge - tax) as sub_total')->get()->sum('sub_total'); - return $this->calculatesBookingPayableAmount->execute($booking, $booking->fix_currency_id) / ($totalPayment + $discount); + if($generateEInvoiceRefund){ + $totalPayment = $booking->fix_currency_id === 1 ? $booking->transactions()->payments()->where('status', ApprovalStatus::REFUNDED)->sum('original_amount') : + $booking->transactions()->payments()->where('status', ApprovalStatus::REFUNDED)->selectRaw('sum(amount - service_charge - tax) as sub_total')->get()->sum('sub_total'); + } + else{ + $totalPayment = $booking->fix_currency_id === 1 ? $booking->transactions()->payments()->complete()->sum('original_amount') : + $booking->transactions()->payments()->complete()->selectRaw('sum(amount - service_charge - tax) as sub_total')->get()->sum('sub_total'); + } + + return $this->calculatesBookingPayableAmount->execute($booking, $booking->fix_currency_id, $generateEInvoiceRefund) / ($totalPayment + $discount); } else if ($type == TransactionType::BILL) { @@ -47,4 +54,4 @@ class CalculatesBookingCurrencyAverageRate } } -} \ No newline at end of file +} diff --git a/app/Classes/Modules/Bookings/Services/CalculatesBookingPayableAmount.php b/app/Classes/Modules/Bookings/Services/CalculatesBookingPayableAmount.php index a068cbbe..c60debdb 100644 --- a/app/Classes/Modules/Bookings/Services/CalculatesBookingPayableAmount.php +++ b/app/Classes/Modules/Bookings/Services/CalculatesBookingPayableAmount.php @@ -11,11 +11,18 @@ use Carbon\Carbon; class CalculatesBookingPayableAmount { - public function execute(Booking $booking, int $type){ + public function execute(Booking $booking, int $type, bool $generateEInvoiceRefund = false){ + + if($generateEInvoiceRefund){ + return $type === 1 ? + $booking->transactions()->payments()->where('status', ApprovalStatus::REFUNDED) + ->selectRaw('sum(amount - service_charge - tax) as sub_total')->get()->sum('sub_total') : + $booking->transactions()->payments()->where('status', ApprovalStatus::REFUNDED)->sum('original_amount'); + } return $type === 1 ? $booking->transactions()->payments()->complete() ->selectRaw('sum(amount - service_charge - tax) as sub_total')->get()->sum('sub_total') : $booking->transactions()->payments()->complete()->sum('original_amount'); } -} \ No newline at end of file +} diff --git a/app/Classes/Modules/Transactions/Processors/CreateInvoiceDocumentProcessor.php b/app/Classes/Modules/Transactions/Processors/CreateInvoiceDocumentProcessor.php index 6e746415..06f50005 100644 --- a/app/Classes/Modules/Transactions/Processors/CreateInvoiceDocumentProcessor.php +++ b/app/Classes/Modules/Transactions/Processors/CreateInvoiceDocumentProcessor.php @@ -44,7 +44,7 @@ class CreateInvoiceDocumentProcessor * @return void * @throws \App\Classes\Exceptions\MalformedRequestException */ - public function execute($transaction, $purchaseOrder, $supplier, $document_type, $voucherRedemption = null, $isAllowNormalInvoice = false) + public function execute($transaction, $purchaseOrder, $supplier, $document_type, $voucherRedemption = null, $generateEInvoiceWithNormalInvoiceTemplate = false, $generateEInvoiceRefund = false) { // calculate current Paid Amount $booking = $transaction->owner_type == Booking::class ? $transaction->owner : null; @@ -61,7 +61,13 @@ class CreateInvoiceDocumentProcessor if ($booking) { $bookingCreatedDate = Carbon::parse($booking->created_at); if ($bookingCreatedDate->isAfter($eInvoiceStartDate)) { - $lastPaymentTransaction = $booking->transactions()->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::COMPLETED, ApprovalStatus::APPROVED])->latest()->first(); + if($generateEInvoiceRefund){ + $lastPaymentTransaction = $booking->transactions()->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::REFUNDED])->latest()->first(); + } + else{ + $lastPaymentTransaction = $booking->transactions()->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::COMPLETED, ApprovalStatus::APPROVED])->latest()->first(); + } + $documentDate = $lastPaymentTransaction->created_at; } @@ -83,7 +89,14 @@ class CreateInvoiceDocumentProcessor $documentDate = $lastDayOfMonth; } } - $payment = $booking->transactions()->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::COMPLETED, ApprovalStatus::APPROVED])->first(); + + if($generateEInvoiceRefund){ + $payment = $booking->transactions()->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::REFUNDED])->first(); + } + else{ + $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'); $paymentAmount = $payment->amount; $currentPaidAmount = $paymentAmount - $refundAmount; @@ -92,7 +105,7 @@ class CreateInvoiceDocumentProcessor $lowercaseDocumentType = strtolower($document_type); if($document_type === DocumentType::EINVOICE){ //July 2025 workaround generate normal invoice instead of E-Invoice - if($isAllowNormalInvoice){ + if($generateEInvoiceWithNormalInvoiceTemplate){ $lowercaseDocumentType = strtolower(DocumentType::INVOICE); } } @@ -169,7 +182,7 @@ class CreateInvoiceDocumentProcessor $document = $this->createsDocument->execute($transaction, $document_object); } else{ - $document = $this->createsDocument->execute($purchaseOrder->booking, $document_object); + $document = $this->createsDocument->execute($purchaseOrder->booking ?? $booking, $document_object); } $this->createsFile->execute($document, $document_object); } diff --git a/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionV2Processor.php b/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionV2Processor.php new file mode 100644 index 00000000..c5f3f410 --- /dev/null +++ b/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionV2Processor.php @@ -0,0 +1,303 @@ +createsTransaction = $createsTransaction; + $this->generatesTransactionBillNumber = $generatesTransactionBillNumber; + $this->calculatesBookingPaidAmount = $calculatesBookingPaidAmount; + $this->calculatesBookingPayableAmount = $calculatesBookingPayableAmount; + $this->calculatesBookingTransferredAmount = $calculatesBookingTransferredAmount; + $this->calculatesBookingCurrencyAverageRate = $calculatesBookingCurrencyAverageRate; + $this->fetchesCompany = $fetchesCompany; + $this->updatesBookingStatus = $updatesBookingStatus; + $this->invoiceDocumentProcessor = $invoiceDocumentProcessor; + } + + + + /** + * @param Booking $booking + * @param String $invoiceNo + * @param array $options + * @return void + * @throws MalformedRequestException + */ + public function execute(Booking $booking, String $invoiceNo= "", array $options = []) + { + $generateEInvoice = $options['generateEInvoice'] ?? false; + $generateEInvoiceWithNormalInvoiceTemplate = $options['generateEInvoiceWithNormalInvoiceTemplate'] ?? false; + $generateEInvoiceRefund = $options['generateEInvoiceRefund'] ?? false; + $bookingOriginalStatus = $options['bookingOriginalStatus'] ?? ApprovalStatus::COMPLETED; + + if($generateEInvoiceRefund){ + $generateEInvoice = true; //cief todo: 90 - cannot have 2 flags doing the same thing + } + + if ($booking->status === ApprovalStatus::COMPLETED && !$generateEInvoiceRefund) { + return; + } + + $payable_amount = $this->calculatesBookingPayableAmount->execute($booking, $booking->fix_currency_id, $generateEInvoiceRefund); + $booking_amount = $booking->fix_amount; + + // confirm that booking amount has been fully paid + if ((float) $booking_amount > (float) $payable_amount) { + return; + } + // confirm that all payments has been transferred + if ($this->calculatesBookingTransferredAmount->execute($booking) !== $this->calculatesBookingPaidAmount->execute($booking)) { + return; + } + + if($generateEInvoiceRefund){ + $purchaseOrder = $booking->transactions() + ->where('type', TransactionType::PURCHASE_ORDER) + ->where('status', ApprovalStatus::PENDING_SUBMISSION) + ->first(); + } + else{ + $purchaseOrder = $booking->transactions() + ->where('type', TransactionType::PURCHASE_ORDER) + ->complete() + ->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) + // ->first(); + + $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); + if ($bookingCreatedDate->isAfter($eInvoiceStartDate) && $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; + } + else{ + $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'); + } + + + + $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); + + $voucherRedemption = $transaction->voucherRedemption; + + // 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(); + + $transaction = null; + if($paymentTransaction){ + $transaction = $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) + $temp = $booking->transactions()->payments()->where('status', ApprovalStatus::APPROVED)->first(); + // Lets check if there is a refund case + $refund = $temp->transactions()->refunds()->where('status', ApprovalStatus::APPROVED)->first(); + if($refund){ + $transaction = $temp; + } + else{ + throw new Exception("No payment found for booking '$booking->id'."); + } + } + + $transaction_object = new TransactionObject( + $billNumber, + TransactionType::SUPPLIER_DELIVER, + $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 + ); + $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(!$generateEInvoiceRefund){ + $this->updatesBookingStatus->execute($booking, $bookingOriginalStatus); + //} + + // update perfex crm + // if(config('perfexcrm.is_enabled') == 'true'){ + // CreatePerfexCRMInvoice::dispatch($invoice_transaction, $purchaseOrder, $supplier); + // } + } +} diff --git a/resources/assets/vue/components/bookings/forms/RegenerateEInvoiceRefundComponent.vue b/resources/assets/vue/components/bookings/forms/RegenerateEInvoiceRefundComponent.vue new file mode 100644 index 00000000..75d19280 --- /dev/null +++ b/resources/assets/vue/components/bookings/forms/RegenerateEInvoiceRefundComponent.vue @@ -0,0 +1,43 @@ + + diff --git a/resources/assets/vue/components/bookings/sections/BookingDetailsSectionComponent.vue b/resources/assets/vue/components/bookings/sections/BookingDetailsSectionComponent.vue index 271826ff..bc5f3dca 100644 --- a/resources/assets/vue/components/bookings/sections/BookingDetailsSectionComponent.vue +++ b/resources/assets/vue/components/bookings/sections/BookingDetailsSectionComponent.vue @@ -5,7 +5,7 @@
-
+
@@ -133,6 +133,58 @@
+
+
+
+
+
+
+
+
+
+ +
+
+ + + +
+
+ +
+

E-Invoice (Pending)

+
+
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
@@ -343,6 +395,14 @@
+
+
+
Regenerate E-Invoice
(Refund)
+
+ + + +
Regenerate E-Invoice
diff --git a/resources/views/pages/pdfs/e_invoice.blade.php b/resources/views/pages/pdfs/e_invoice.blade.php index 9c7dce39..cf3069ca 100644 --- a/resources/views/pages/pdfs/e_invoice.blade.php +++ b/resources/views/pages/pdfs/e_invoice.blade.php @@ -25,7 +25,7 @@
E-Invoice
EI#: {{ $autocountId ?? 'NONE'}}
-
Ref# {{ $po_order_transaction->booking->marking }}
+
Ref# {{ $booking->marking }}
Date: {{ $document_date->toDateString() }}
 
diff --git a/resources/views/pages/pdfs/purchase_order_table.blade.php b/resources/views/pages/pdfs/purchase_order_table.blade.php index 542f1144..ce85538b 100644 --- a/resources/views/pages/pdfs/purchase_order_table.blade.php +++ b/resources/views/pages/pdfs/purchase_order_table.blade.php @@ -25,7 +25,7 @@ use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\TransactionType; - $booking = $po_order_transaction->owner; + $booking = $po_order_transaction->owner ?? $booking; $paymentSum = $booking->transactions() ->where('type', TransactionType::PAYMENT) ->where('status', ApprovalStatus::COMPLETED) @@ -36,6 +36,8 @@ $totalPayment = 0; $average_currency_rate = $transaction->currency_rate; + + $paymentSumRefund = 0; if ($paymentSum){ $average_currency_rate = $booking->transactions() ->where('type', TransactionType::PAYMENT) @@ -53,30 +55,41 @@ $totalPayment = $paymentSum - $refundedAmount - $refundedServiceCharge; } + else{ + $paymentSumRefund = $booking->transactions() + ->where('type', TransactionType::PAYMENT) + ->where('status', ApprovalStatus::REFUNDED) + ->get() + ->sum(function ($transaction) { + return round($transaction->amount, 2); + }); + } ?> - @foreach ($po_order_transaction->transactionDetails as $key => $transaction_detail) - @php - $exactUnitPrice = ($currency_id) === 1 ? $transaction_detail->price : bcdiv($transaction_detail->price, $average_currency_rate, 7); - $displayUnitPrice = round($exactUnitPrice, 2); - $itemTotal = bcmul($exactUnitPrice, $transaction_detail->quantity, 5); - $displayedItemTotal = round(bcmul($displayUnitPrice, $transaction_detail->quantity, 7), 2); - $displayedSubtotal = bcadd($displayedSubtotal, $displayedItemTotal, 2); - $subtotal = bcadd($subtotal, $itemTotal, 5); - @endphp - - {{ $key + 1 }} - {{ $transaction_detail->product_code }} - {{ $transaction_detail->product_name }} - {{ $transaction_detail->quantity }} - - {{ number_format($displayUnitPrice, 2) }} - - - {{ number_format($displayedItemTotal, 2) }} - - - @endforeach + @if (!empty($po_order_transaction) && $po_order_transaction->transactionDetails) + @foreach ($po_order_transaction->transactionDetails as $key => $transaction_detail) + @php + $exactUnitPrice = ($currency_id) === 1 ? $transaction_detail->price : bcdiv($transaction_detail->price, $average_currency_rate, 7); + $displayUnitPrice = round($exactUnitPrice, 2); + $itemTotal = bcmul($exactUnitPrice, $transaction_detail->quantity, 5); + $displayedItemTotal = round(bcmul($displayUnitPrice, $transaction_detail->quantity, 7), 2); + $displayedSubtotal = bcadd($displayedSubtotal, $displayedItemTotal, 2); + $subtotal = bcadd($subtotal, $itemTotal, 5); + @endphp + + {{ $key + 1 }} + {{ $transaction_detail->product_code }} + {{ $transaction_detail->product_name }} + {{ $transaction_detail->quantity }} + + {{ number_format($displayUnitPrice, 2) }} + + + {{ number_format($displayedItemTotal, 2) }} + + + @endforeach + @endif @php @@ -101,7 +114,7 @@ ->get() ->sum(function ($transaction) { return $transaction->service_charge; - }); + }); } ?> {{ number_format($serviceCharge, 2) }} @@ -142,11 +155,11 @@ $displayedTotal = bcadd( bcadd( - bcadd($displayedSubtotal, $serviceCharge, 5), - $tax, + bcadd($displayedSubtotal, $serviceCharge, 5), + $tax, 5 - ), - $voucherDiscount, + ), + $voucherDiscount, 5 ); @@ -159,6 +172,10 @@ $discrepancy = bcsub($expectedTotal, $displayedTotal, 5); $total = $totalPayment; } + + if($paymentSumRefund){ + $total = $paymentSumRefund; + } @endphp @@ -173,4 +190,4 @@ - \ No newline at end of file +