diff --git a/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessorWithInvoiceNo.php b/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessorWithInvoiceNo.php new file mode 100644 index 00000000..27dfbe59 --- /dev/null +++ b/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessorWithInvoiceNo.php @@ -0,0 +1,210 @@ +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 + * @return void + * @throws MalformedRequestException + */ + public function execute(Booking $booking, String $invoiceNo) + { + + if ($booking->status === ApprovalStatus::COMPLETED) { + return; + } + + $payable_amount = $this->calculatesBookingPayableAmount->execute($booking, $booking->fix_currency_id); + $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; + } + + $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) { + return; + } + + // $transaction = $booking->transactions() + // ->where('type', TransactionType::PAYMENT) + // ->first(); + + $transaction = $booking->transactions() + ->where('type', TransactionType::PAYMENT) + ->latest()->get()[0]; + + // $billNumber = $this->generatesTransactionBillNumber->execute('INV-'); + $billNumber = $invoiceNo; + + $booking_currency_average_rate = $this->calculatesBookingCurrencyAverageRate->execute($booking, TransactionType::PAYMENT); + + $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, $transaction_object); + + $voucherRedemption = $transaction->voucherRedemption; + + $supplier = $this->fetchesCompany->execute(['id' => $transaction->receiver]); + + // purchase order + $this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::PURCHASE_ORDER, $voucherRedemption); + + // deliver order + $this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::DELIVER_ORDER, $voucherRedemption); + + // invoice + $this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::INVOICE, $voucherRedemption); + + $billNumber = $this->generatesTransactionBillNumber->execute('SPDO-'); + + $booking_currency_average_rate = $this->calculatesBookingCurrencyAverageRate->execute($booking, TransactionType::BILL); + + $transaction = $booking->transactions()->payments()->where('status', ApprovalStatus::COMPLETED)->first() + ->transactions()->where('type', TransactionType::BILL)->first(); + + $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); + + $this->updatesBookingStatus->execute($booking, ApprovalStatus::COMPLETED); + + // update perfex crm + // if(config('perfexcrm.is_enabled') == 'true'){ + // CreatePerfexCRMInvoice::dispatch($invoice_transaction, $purchaseOrder, $supplier); + // } + } +} diff --git a/routes/web.php b/routes/web.php index 7980b80a..b1188854 100644 --- a/routes/web.php +++ b/routes/web.php @@ -26,6 +26,7 @@ use Webklex\PDFMerger\Facades\PDFMergerFacade as PDFMerger; use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject; use App\Classes\Modules\Bookings\Processors\CreatePurchaseOrderFor1688OrderProcessor; use App\Classes\Modules\Documents\Services\DeletesDocument; +use App\Classes\Modules\Transactions\Processors\CreateInvoiceTransactionProcessorWithInvoiceNo; use App\Classes\Modules\Transactions\Services\DeletesTransaction; /* @@ -487,7 +488,10 @@ Route::get('/payments/manual', function(){ Route::get('/invoice/fix', function(){ set_time_limit(14400); - $bookings = Booking::where('status', ApprovalStatus::COMPLETED)->whereDate('updated_at', '>=', Carbon::parse('01-01-2023'))->get(); + $bookings = Booking::where('status', ApprovalStatus::COMPLETED) + ->whereDate('updated_at', '>=', Carbon::parse('01-01-2023')) + ->take(10) // to test on development + ->get(); foreach($bookings as $booking){ $booking->transactions()->whereIn('transactions.type', [TransactionType::INVOICE, TransactionType::SUPPLIER_DELIVER])->delete(); @@ -495,7 +499,29 @@ Route::get('/invoice/fix', function(){ $booking->status = ApprovalStatus::APPROVED; $booking->save(); - (App()->make(CreateInvoiceTransactionProcessor::class))->execute($booking); + $deletedInvoice = $booking->transactions() + ->whereIn('type', [TransactionType::INVOICE]) + ->onlyTrashed() + ->orderBy('created_at', 'asc') + ->first(); + + if ($deletedInvoice) { + $bill_no = $deletedInvoice->bill_no; + + // check if bill_no ends with '-deleted' + if (str_ends_with($bill_no, '-deleted')) { + $bill_no = str_replace('-deleted', '', $bill_no); + } + + $deletedInvoice->bill_no = $bill_no . '-deleted'; + (App()->make(CreateInvoiceTransactionProcessorWithInvoiceNo::class))->execute($booking, $bill_no); + $deletedInvoice->save(); + dump('regenerated invoice. Booking Marking - ' . $booking->marking . '. Bill_no - ' . $bill_no . '. Old bill_no - ' . $deletedInvoice->bill_no); + } else { + (App()->make(CreateInvoiceTransactionProcessor::class))->execute($booking); + dump('regenerated new invoice. Booking Marking - ' . $booking->marking); + } + } })->name('invoice.fix');