diff --git a/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php b/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php index b6537420..42726384 100644 --- a/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php +++ b/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php @@ -2,31 +2,32 @@ namespace App\Classes\Modules\Billplzs\ControllersLogic; -use App\Classes\Modules\Wallets\DataTransferObjects\WalletObject; -use App\Classes\Modules\Wallets\Services\UpdatesWallet; +use App\Classes\Exceptions\MalformedRequestException; +use App\Classes\Exceptions\ResourceNotFoundException; +use App\Classes\General\Abstracts\AbstractControllerLogic; +use App\Classes\Jobs\Commands\V2\CreateInvoiceTransactionV2CommandJob; +use App\Classes\Modules\Billplzs\DataTransferObjects\BillplzXSignatureObject; +use App\Classes\Modules\Billplzs\Services\GetBillplzBill; use App\Classes\Modules\Transactions\Processors\CreateCashBackTransactionProcessor; use App\Classes\Modules\Transactions\Processors\CreateReceiptVoucherTransactionProcessor; - -use App\Classes\Exceptions\ResourceNotFoundException; +use App\Classes\Modules\Transactions\Services\FetchesTransaction; +use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus; +use App\Classes\Modules\Wallets\DataTransferObjects\WalletObject; +use App\Classes\Modules\Wallets\Services\RecalculatesWalletBalance; +use App\Classes\Modules\Wallets\Services\UpdatesWallet; use App\Classes\Modules\Wallets\Services\UpdatesWalletBalance; +use App\Classes\ValueObjects\Constants\ApprovalStatus; +use App\Classes\ValueObjects\Constants\TransactionType; use App\Http\Resources\TransactionResource; + use App\Models\Booking; use App\Models\User; use App\Models\Wallet; -use Illuminate\Http\Request; -use Illuminate\Http\JsonResponse; -use App\Classes\Exceptions\MalformedRequestException; -use App\Classes\ValueObjects\Constants\ApprovalStatus; -use App\Classes\ValueObjects\Constants\TransactionType; -use App\Classes\Modules\Billplzs\Services\GetBillplzBill; -use App\Classes\Modules\Billplzs\DataTransferObjects\BillplzXSignatureObject; -use App\Classes\General\Abstracts\AbstractControllerLogic; -use App\Classes\Modules\Transactions\Services\FetchesTransaction; -use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus; +use Illuminate\Http\JsonResponse; +use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Log; -use App\Classes\Modules\Wallets\Services\RecalculatesWalletBalance; class CallbackBillplzLogic { @@ -117,6 +118,10 @@ class CallbackBillplzLogic $this->createReceiptVoucherTransactionProcessor->execute($booking, $transaction); } + if($booking){ + CreateInvoiceTransactionV2CommandJob::dispatch($booking); + } + // if ($transaction->type == TransactionType::PAYMENT) { // $cash_back_transaction = $this->createCashBackTransactionProcessor->execute($transaction); // } diff --git a/app/Classes/Modules/Bookings/ControllersLogic/ApprovePurchaseOrderLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/ApprovePurchaseOrderLogic.php index 1a533294..3360946a 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/ApprovePurchaseOrderLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/ApprovePurchaseOrderLogic.php @@ -72,7 +72,8 @@ class ApprovePurchaseOrderLogic extends AbstractControllerLogic 'generateEInvoiceWithNormalInvoiceTemplate' => false, 'generateEInvoiceRefund' => false, 'bookingOriginalStatus' => $booking->status - ]); + ] + ); return $this->response([]); } diff --git a/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingAmountLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingAmountLogic.php index 695aafd0..73625a26 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingAmountLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingAmountLogic.php @@ -2,28 +2,29 @@ namespace App\Classes\Modules\Bookings\ControllersLogic; +use App\Classes\Exceptions\MalformedRequestException; +use App\Classes\Exceptions\CriteriaNotFulfilledException; +use App\Classes\General\Abstracts\AbstractControllerLogic; +use App\Classes\Jobs\Commands\V2\CreateInvoiceTransactionV2CommandJob; +use App\Classes\Modules\Bookings\DataTransferObjects\BookingObject; +use App\Classes\Modules\Bookings\DataTransferObjects\UpdateBookingInvoiceStatusObject; +use App\Classes\Modules\Bookings\Services\CalculatesBookingOutstanding; +use App\Classes\Modules\Bookings\Services\FetchesBooking; +use App\Classes\Modules\Bookings\Services\UpdatesBookingInvoiceStatus; use App\Classes\Modules\Bookings\Services\UpdatesBookingFixedAmount; +use App\Classes\Modules\Bookings\Standards\Rules\CanUpdateBooking; +use App\Classes\Modules\Transactions\Processors\CreateInvoiceTransactionV2Processor; use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\TransactionType; use App\Http\Resources\BookingResource; - -use App\Classes\General\Abstracts\AbstractControllerLogic; - -use App\Classes\Modules\Bookings\Services\FetchesBooking; - -use App\Classes\Modules\Bookings\Standards\Rules\CanUpdateBooking; -use App\Classes\Modules\Bookings\DataTransferObjects\BookingObject; use App\Classes\Modules\Rules\DataTransferObjects\CheckTransferPeriodLockRuleVariant2DTO; -use App\Classes\Modules\Bookings\Services\CalculatesBookingOutstanding; use App\Classes\Modules\Rules\Services\RuleEvaluator; use App\Classes\Modules\Rules\Standards\Rules\CanPassTransferPeriodLockRule; use ErrorException; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; -use App\Classes\Exceptions\MalformedRequestException; -use App\Classes\Exceptions\CriteriaNotFulfilledException; use Illuminate\Support\Facades\Log; class UpdateBookingAmountLogic extends AbstractControllerLogic @@ -61,6 +62,12 @@ class UpdateBookingAmountLogic extends AbstractControllerLogic /** @var CanPassTransferPeriodLockRule */ private $canPassTransferPeriodLockRule; + /** @var UpdatesBookingInvoiceStatus */ + private $updatesBookingInvoiceStatus; + + /** @var CreateInvoiceTransactionV2Processor */ + private $createInvoiceTransactionProcessor; + /** * UpdateBookingAmountLogic constructor. * @param CanUpdateBooking $canUpdateBooking @@ -70,8 +77,10 @@ class UpdateBookingAmountLogic extends AbstractControllerLogic * @param UpdatesTransactionStatus $updatesTransactionStatus * @param RuleEvaluator $ruleEvaluator * @param CanPassTransferPeriodLockRule $canPassTransferPeriodLockRule + * @param UpdatesBookingInvoiceStatus $updatesBookingInvoiceStatus + * @param CreateInvoiceTransactionV2Processor $createInvoiceTransactionProcessor */ - public function __construct(CanUpdateBooking $canUpdateBooking, UpdatesBookingFixedAmount $updatesBookingFixedAmount, FetchesBooking $fetchesBooking, CalculatesBookingOutstanding $calculatesBookingOutstanding, UpdatesTransactionStatus $updatesTransactionStatus, RuleEvaluator $ruleEvaluator, CanPassTransferPeriodLockRule $canPassTransferPeriodLockRule) + public function __construct(CanUpdateBooking $canUpdateBooking, UpdatesBookingFixedAmount $updatesBookingFixedAmount, FetchesBooking $fetchesBooking, CalculatesBookingOutstanding $calculatesBookingOutstanding, UpdatesTransactionStatus $updatesTransactionStatus, RuleEvaluator $ruleEvaluator, CanPassTransferPeriodLockRule $canPassTransferPeriodLockRule, UpdatesBookingInvoiceStatus $updatesBookingInvoiceStatus, CreateInvoiceTransactionV2Processor $createInvoiceTransactionProcessor) { $this->canUpdateBooking = $canUpdateBooking; $this->updatesBookingFixedAmount = $updatesBookingFixedAmount; @@ -80,6 +89,8 @@ class UpdateBookingAmountLogic extends AbstractControllerLogic $this->updatesTransactionStatus = $updatesTransactionStatus; $this->ruleEvaluator = $ruleEvaluator; $this->canPassTransferPeriodLockRule = $canPassTransferPeriodLockRule; + $this->updatesBookingInvoiceStatus = $updatesBookingInvoiceStatus; + $this->createInvoiceTransactionProcessor = $createInvoiceTransactionProcessor; } /** @@ -124,6 +135,14 @@ class UpdateBookingAmountLogic extends AbstractControllerLogic $booking = $this->updatesBookingFixedAmount->execute($booking, $input_amount); + if($booking->invoice_status === ApprovalStatus::APPROVED){ + $updateBookingInvoiceStatusObject = new UpdateBookingInvoiceStatusObject($booking->id, ApprovalStatus::PENDING_VERIFICATION); + $this->updatesBookingInvoiceStatus->execute($booking, $updateBookingInvoiceStatusObject); + } + else{ + $this->createInvoiceTransactionProcessor->execute($booking); + } + return $this->resourceResponse(new BookingResource($booking)); } diff --git a/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingAmountOnHoldLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingAmountOnHoldLogic.php index 760aa488..2bc2fc64 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingAmountOnHoldLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingAmountOnHoldLogic.php @@ -91,6 +91,7 @@ class UpdateBookingAmountOnHoldLogic extends AbstractControllerLogic } $key = "BOOKING_AMOUNT_UPDATE"; + $keyValuePairObject = new KeyValuePairObject($key, $input_amount); $metadata = $booking->attributesKVP()->where('key', $key)->first(); if($metadata){ diff --git a/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingAmountWithPOLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingAmountWithPOLogic.php index 4def81f7..b97a2667 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingAmountWithPOLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingAmountWithPOLogic.php @@ -10,6 +10,10 @@ use App\Classes\Modules\Bookings\Services\UpdatesBookingFixedAmount; use App\Classes\Modules\Bookings\Services\CalculatesBookingOutstanding; use App\Classes\Modules\Bookings\Services\CalculatesBookingPayableAmount; use App\Classes\Modules\Bookings\Services\CalculatesBookingRefundAmount; +use App\Classes\Modules\Bookings\Services\UpdatesBookingInvoiceStatus; +use App\Classes\Modules\Transactions\Processors\CreateInvoiceTransactionV2Processor; +use App\Classes\Modules\Bookings\DataTransferObjects\UpdateBookingInvoiceStatusObject; +use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\TransactionType; use App\Http\Resources\BookingResource; use App\Models\Booking; @@ -45,6 +49,12 @@ class UpdateBookingAmountWithPOLogic extends AbstractControllerLogic /** @var CalculatesBookingRefundAmount */ private $calculatesBookingRefundAmount; + /** @var UpdatesBookingInvoiceStatus */ + private $updatesBookingInvoiceStatus; + + /** @var CreateInvoiceTransactionV2Processor */ + private $createInvoiceTransactionProcessor; + /** * UpdateBookingAmountWithPOLogic constructor. * @param FetchesBooking $fetchesBooking @@ -52,14 +62,18 @@ class UpdateBookingAmountWithPOLogic extends AbstractControllerLogic * @param CalculatesBookingOutstanding $calculatesBookingOutstanding * @param CalculatesBookingPayableAmount $calculatesBookingPayableAmount * @param CalculatesBookingRefundAmount $calculatesBookingRefundAmount + * @param UpdatesBookingInvoiceStatus $updatesBookingInvoiceStatus + * @param CreateInvoiceTransactionV2Processor $createInvoiceTransactionProcessor */ - public function __construct(FetchesBooking $fetchesBooking, UpdatesBookingFixedAmount $updatesBookingFixedAmount, CalculatesBookingOutstanding $calculatesBookingOutstanding, CalculatesBookingPayableAmount $calculatesBookingPayableAmount, CalculatesBookingRefundAmount $calculatesBookingRefundAmount) + public function __construct(FetchesBooking $fetchesBooking, UpdatesBookingFixedAmount $updatesBookingFixedAmount, CalculatesBookingOutstanding $calculatesBookingOutstanding, CalculatesBookingPayableAmount $calculatesBookingPayableAmount, CalculatesBookingRefundAmount $calculatesBookingRefundAmount, UpdatesBookingInvoiceStatus $updatesBookingInvoiceStatus, CreateInvoiceTransactionV2Processor $createInvoiceTransactionProcessor) { $this->fetchesBooking = $fetchesBooking; $this->updatesBookingFixedAmount = $updatesBookingFixedAmount; $this->calculatesBookingOutstanding = $calculatesBookingOutstanding; $this->calculatesBookingPayableAmount = $calculatesBookingPayableAmount; $this->calculatesBookingRefundAmount = $calculatesBookingRefundAmount; + $this->updatesBookingInvoiceStatus = $updatesBookingInvoiceStatus; + $this->createInvoiceTransactionProcessor = $createInvoiceTransactionProcessor; } /** @@ -110,6 +124,14 @@ class UpdateBookingAmountWithPOLogic extends AbstractControllerLogic $booking->transactions()->where('type', TransactionType::PROFORMA)->delete(); $booking = $this->updatesBookingFixedAmount->execute($booking, $bookingAmountUpdate); + if($booking->invoice_status === ApprovalStatus::APPROVED){ + $updateBookingInvoiceStatusObject = new UpdateBookingInvoiceStatusObject($booking->id, ApprovalStatus::PENDING_VERIFICATION); + $this->updatesBookingInvoiceStatus->execute($booking, $updateBookingInvoiceStatusObject); + } + else{ + $this->createInvoiceTransactionProcessor->execute($booking); + } + $request->merge(['is_privilleged_update' => true]); $bookingAttribute->delete(); diff --git a/app/Classes/Modules/Bookings/DataTransferObjects/UpdateBookingInvoiceStatusObject.php b/app/Classes/Modules/Bookings/DataTransferObjects/UpdateBookingInvoiceStatusObject.php new file mode 100644 index 00000000..6b04a695 --- /dev/null +++ b/app/Classes/Modules/Bookings/DataTransferObjects/UpdateBookingInvoiceStatusObject.php @@ -0,0 +1,42 @@ +id = $id; + $this->invoiceStatus = $invoiceStatus; + } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } + + /** + * @return int + */ + public function getInvoiceStatus(): int + { + return $this->invoiceStatus; + } +} diff --git a/app/Classes/Modules/Bookings/Processors/CreatePurchaseOrderFor1688OrderProcessor.php b/app/Classes/Modules/Bookings/Processors/CreatePurchaseOrderFor1688OrderProcessor.php index 8a24a5ab..83b25386 100644 --- a/app/Classes/Modules/Bookings/Processors/CreatePurchaseOrderFor1688OrderProcessor.php +++ b/app/Classes/Modules/Bookings/Processors/CreatePurchaseOrderFor1688OrderProcessor.php @@ -88,7 +88,13 @@ class CreatePurchaseOrderFor1688OrderProcessor if($purchaseOrder->amount === $booking->fix_amount){ $this->updatesTransactionStatus->execute($purchaseOrder, ApprovalStatus::APPROVED); - $this->createInvoiceTransactionProcessor->execute($booking); + $this->createInvoiceTransactionProcessor->execute($booking, "", null, [ + 'generateEInvoice' => false, + 'generateEInvoiceWithNormalInvoiceTemplate' => false, + 'generateEInvoiceRefund' => false, + 'bookingOriginalStatus' => ApprovalStatus::COMPLETED + ] + ); } } diff --git a/app/Classes/Modules/Bookings/Services/UpdatesBookingInvoiceStatus.php b/app/Classes/Modules/Bookings/Services/UpdatesBookingInvoiceStatus.php new file mode 100644 index 00000000..97342170 --- /dev/null +++ b/app/Classes/Modules/Bookings/Services/UpdatesBookingInvoiceStatus.php @@ -0,0 +1,23 @@ +invoice_status = $object->getInvoiceStatus(); + return $this->handler($model); + } +} diff --git a/app/Classes/Modules/Exports/Services/ExportsSalesInvoiceReport.php b/app/Classes/Modules/Exports/Services/ExportsSalesInvoiceReport.php index 2ec40315..66254a9d 100644 --- a/app/Classes/Modules/Exports/Services/ExportsSalesInvoiceReport.php +++ b/app/Classes/Modules/Exports/Services/ExportsSalesInvoiceReport.php @@ -73,7 +73,7 @@ class ExportsSalesInvoiceReport implements FromQuery, WithHeadings, WithHeadingR 'transactions.voucherRedemption.voucher.campaign' ]) // ->whereIn('status', [ApprovalStatus::COMPLETED]) - ->where('is_invoice_generated', 1) + ->whereIn('invoice_status', [ApprovalStatus::APPROVED]) ->whereHas('transactions', function ($query) use ($startDate, $endDate) { $query->payments() ->complete() diff --git a/app/Classes/Modules/Transactions/ControllersLogic/CreatePaymentProofDocumentLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/CreatePaymentProofDocumentLogic.php index baed9a8f..412d88ab 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/CreatePaymentProofDocumentLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/CreatePaymentProofDocumentLogic.php @@ -91,7 +91,13 @@ class CreatePaymentProofDocumentLogic extends AbstractControllerLogic $this->updatesTransactionStatus->execute($transaction, ApprovalStatus::APPROVED); - $this->createInvoiceTransactionProcessor->execute($transaction->owner->booking); + $this->createInvoiceTransactionProcessor->execute($transaction->owner->booking, "", null, [ + 'generateEInvoice' => false, + 'generateEInvoiceWithNormalInvoiceTemplate' => false, + 'generateEInvoiceRefund' => false, + 'bookingOriginalStatus' => ApprovalStatus::COMPLETED + ] + ); //cief todo: Prototype Period Lock - Starts $this->updateOrCreateKeyValuePair($transaction->owner->booking, KVPKey::BOOKING_IS_LOCKED, 1); diff --git a/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionV2Processor.php b/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionV2Processor.php index ead713ab..e7c2dc87 100644 --- a/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionV2Processor.php +++ b/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionV2Processor.php @@ -104,7 +104,12 @@ class CreateInvoiceTransactionV2Processor $generateEInvoice = $options['generateEInvoice'] ?? false; $generateEInvoiceWithNormalInvoiceTemplate = $options['generateEInvoiceWithNormalInvoiceTemplate'] ?? false; $generateEInvoiceRefund = $options['generateEInvoiceRefund'] ?? false; - $bookingOriginalStatus = $options['bookingOriginalStatus'] ?? ApprovalStatus::COMPLETED; + $bookingOriginalStatus = $options['bookingOriginalStatus'] ?? ApprovalStatus::APPROVED; + + // 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)); if ($booking->status === ApprovalStatus::COMPLETED && !$generateEInvoiceRefund) { Log::info('CreateInvoiceTransactionV2Processor Check 1 Bypass New Business Logic Update for booking ' . $booking->id); @@ -133,6 +138,7 @@ class CreateInvoiceTransactionV2Processor ->where('type', TransactionType::PURCHASE_ORDER) ->complete() ->first(); + if(!$purchaseOrder && $generateEInvoiceRefund){ $purchaseOrder = $booking->transactions() ->where('type', TransactionType::PURCHASE_ORDER) @@ -141,14 +147,9 @@ class CreateInvoiceTransactionV2Processor } $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(); + // if ($constants->detail->is_billable && !$purchaseOrder && !$generateEInvoiceRefund) { + // return; + // } $transaction = $booking->transactions() ->where('type', TransactionType::PAYMENT) @@ -207,29 +208,39 @@ class CreateInvoiceTransactionV2Processor ->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(); + } - - $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(!$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->is_invoice_generated = true; + $booking->invoice_status = ApprovalStatus::APPROVED; $booking->save(); if ($kvpCopies) { @@ -240,7 +251,7 @@ class CreateInvoiceTransactionV2Processor $voucherRedemption = $transaction->voucherRedemption; - if($generateEInvoiceRefund){ + if($generateEInvoiceRefund){ $metadata = $booking->attributesKVP()->where('key', KVPKey::AUTOCOUNT_DOCNO_INVOICE)->first(); if($metadata){ $generateEInvoice = true; @@ -253,84 +264,86 @@ class CreateInvoiceTransactionV2Processor } } - // 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); + if($purchaseOrder){ + // purchase order + if(!$generateEInvoiceRefund){ + $this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::PURCHASE_ORDER, $voucherRedemption, $generateEInvoiceWithNormalInvoiceTemplate); } - } - // 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(); + // deliver order + if(!$generateEInvoiceRefund){ + $this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::DELIVER_ORDER, $voucherRedemption, $generateEInvoiceWithNormalInvoiceTemplate); } - 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){ - $transaction = $paymentTransactionTemp->transactions()->where('type', TransactionType::BILL)->first(); + + // e-invoice + if ($eInvoice) + { + if($generateEInvoice){ + $this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::EINVOICE, $voucherRedemption, $generateEInvoiceWithNormalInvoiceTemplate, $generateEInvoiceRefund); } - else{ - Log::info("CreateInvoiceTransactionV2Processor NO completed payment transaction, refund transaction found for booking '$booking->id'."); + } + // 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); } } - if($transaction){ - $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); + //if(!$generateEInvoiceRefund){ + $this->updatesBookingStatus->execute($booking, $bookingOriginalStatus); + //} - // 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(!$generateEInvoiceRefund){ - $this->updatesBookingStatus->execute($booking, $bookingOriginalStatus); - //} - - // update perfex crm - // if(config('perfexcrm.is_enabled') == 'true'){ - // CreatePerfexCRMInvoice::dispatch($invoice_transaction, $purchaseOrder, $supplier); - // } } } diff --git a/app/Classes/Modules/Transactions/Processors/CreateSupplierTransactionProcessor.php b/app/Classes/Modules/Transactions/Processors/CreateSupplierTransactionProcessor.php index b514b404..42a21d71 100644 --- a/app/Classes/Modules/Transactions/Processors/CreateSupplierTransactionProcessor.php +++ b/app/Classes/Modules/Transactions/Processors/CreateSupplierTransactionProcessor.php @@ -86,6 +86,7 @@ class CreateSupplierTransactionProcessor $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(); diff --git a/app/Classes/ValueObjects/Constants/ApprovalStatus.php b/app/Classes/ValueObjects/Constants/ApprovalStatus.php index ba7660d4..987dbc6a 100644 --- a/app/Classes/ValueObjects/Constants/ApprovalStatus.php +++ b/app/Classes/ValueObjects/Constants/ApprovalStatus.php @@ -29,5 +29,5 @@ final class ApprovalStatus { self::SUSPENDED => "Suspended", self::EXPIRED => "Expired", self::REFUNDED => "Refunded", - ]; + ]; } diff --git a/app/Http/Resources/BookingResource.php b/app/Http/Resources/BookingResource.php index 8486e645..73571b1b 100644 --- a/app/Http/Resources/BookingResource.php +++ b/app/Http/Resources/BookingResource.php @@ -58,15 +58,13 @@ class BookingResource extends JsonResource 'convertible_currency' => new CurrencyResource($this->convertibleCurrency), 'conversion_currency' => new CurrencyResource($this->conversionCurrency), 'documents' => [ - 'purchase_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::PURCHASE_ORDER)->first()), - 'delivery_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::DELIVER_ORDER)->first()), - 'invoice' => new DocumentResource($this->documents()->where('document_type', DocumentType::INVOICE)->first()), + 'purchase_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::PURCHASE_ORDER)->latest()->first()), + 'delivery_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::DELIVER_ORDER)->latest()->first()), + 'invoice' => new DocumentResource($this->documents()->where('document_type', DocumentType::INVOICE)->latest()->first()), 'e_invoice' => new DocumentResource($this->documents()->where('document_type', DocumentType::EINVOICE)->latest()->first()), - 'supplier_delivery_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::SUPPLIER_DELIVER_ORDER)->first()), - 'proforma_invoice' => new DocumentResource($this->documents()->where('document_type', DocumentType::PROFORMA_INVOICE)->whereNotIn('status', [ApprovalStatus::REJECTED, ApprovalStatus::EXPIRED])->orderByDesc('id')->first()), - 'ecommerce_purchase_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::ECOMMERCE_PURCHASE_ORDER)->first()), - 'banking_invoice' => new DocumentResource($this->documents()->where('document_type', DocumentType::BANKING_INVOICE)->whereNotIn('status', [ApprovalStatus::REJECTED, ApprovalStatus::EXPIRED])->orderByDesc('id')->first()), - 'delivery_order_banking' => new DocumentResource($this->documents()->where('document_type', DocumentType::DELIVER_ORDER_BANKING)->orderByDesc('id')->first()), + 'supplier_delivery_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::SUPPLIER_DELIVER_ORDER)->latest()->first()), + 'proforma_invoice' => new DocumentResource($this->documents()->where('document_type', DocumentType::PROFORMA_INVOICE)->whereNotIn('status', [ApprovalStatus::REJECTED, ApprovalStatus::EXPIRED])->latest()->first()), + 'ecommerce_purchase_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::ECOMMERCE_PURCHASE_ORDER)->latest()->first()), ], 'order_reference_no' => $this->modelAttributes()->where('name', BookingAttributeNames::ORDER_REFERENCE_NO)->get()->map(function ($attr) { return [ @@ -100,7 +98,7 @@ class BookingResource extends JsonResource })->latest()->get()) ]), 'einvoice' => $eInvoice, - 'is_invoice_generated' => $this->is_invoice_generated, + 'invoice_status' => $this->invoice_status, ]; } } diff --git a/database/migrations/2025_11_27_120102_add_invoice_status_to_bookings_table.php b/database/migrations/2025_11_27_120102_add_invoice_status_to_bookings_table.php new file mode 100644 index 00000000..124800b4 --- /dev/null +++ b/database/migrations/2025_11_27_120102_add_invoice_status_to_bookings_table.php @@ -0,0 +1,37 @@ +unsignedTinyInteger('invoice_status') + ->default(0) + ->after('status'); + + $table->index('invoice_status', 'bookings_invoice_status_index'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('bookings', function (Blueprint $table) { + $table->dropIndex('bookings_invoice_status_index'); + $table->dropColumn('invoice_status'); + }); + } +} diff --git a/database/migrations/2025_11_27_121256_add_invoice_status_to_booking_logs_table.php b/database/migrations/2025_11_27_121256_add_invoice_status_to_booking_logs_table.php new file mode 100644 index 00000000..d0b21f09 --- /dev/null +++ b/database/migrations/2025_11_27_121256_add_invoice_status_to_booking_logs_table.php @@ -0,0 +1,34 @@ +boolean('invoice_status') + ->default(false) + ->after('status'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('booking_logs', function (Blueprint $table) { + $table->dropColumn('invoice_status'); + }); + } +} diff --git a/database/seeds/DummyDataSeeder.php b/database/seeds/DummyDataSeeder.php index a752ee6f..328dcc15 100644 --- a/database/seeds/DummyDataSeeder.php +++ b/database/seeds/DummyDataSeeder.php @@ -679,8 +679,13 @@ class DummyDataSeeder extends Seeder // once the invoice is generated the transaction table will include 2 new transaction type TransactionType::INVOICE, TransactionType::SUPPLIER_DELIVERY // and for documents will be generated and attached to the booking. // once this process is complete the booking status will update to ApprovalStatus::COMPLETED - $this->createInvoiceTransactionProcessor->execute($booking); - + $this->createInvoiceTransactionProcessor->execute($booking, "", null, [ + 'generateEInvoice' => false, + 'generateEInvoiceWithNormalInvoiceTemplate' => false, + 'generateEInvoiceRefund' => false, + 'bookingOriginalStatus' => ApprovalStatus::COMPLETED + ] + ); } } diff --git a/resources/assets/vue/components/bookings/sections/BookingDetailsSectionComponent.vue b/resources/assets/vue/components/bookings/sections/BookingDetailsSectionComponent.vue index 8071cbab..6cc005ed 100644 --- a/resources/assets/vue/components/bookings/sections/BookingDetailsSectionComponent.vue +++ b/resources/assets/vue/components/bookings/sections/BookingDetailsSectionComponent.vue @@ -21,7 +21,7 @@