From 13ba4e5c1254ffe1e335c9a3af67a9eb09353584 Mon Sep 17 00:00:00 2001 From: Dillon Date: Fri, 20 Jan 2023 01:23:03 +0800 Subject: [PATCH 001/434] Edit book recipient bank details --- .../UpdateBookingRecipientLogic.php | 94 ++++++++++++ .../UpdateBookingRecipientController.php | 20 +++ .../banks/forms/BankAccountFormComponent.vue | 25 +++- .../banks/forms/PhoneAccountFormComponent.vue | 27 +++- .../BookingRecipientEditComponent.vue | 141 ++++++++++++++++++ .../BookingPaymentQuotationComponent.vue | 33 +++- .../bookings/forms/UpdateBookingComponent.vue | 41 +++++ routes/booking.php | 3 +- 8 files changed, 371 insertions(+), 13 deletions(-) create mode 100644 app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingRecipientLogic.php create mode 100644 app/Http/Controllers/Bookings/UpdateBookingRecipientController.php create mode 100644 resources/assets/vue/components/bookings/elements/BookingRecipientEditComponent.vue create mode 100644 resources/assets/vue/components/bookings/forms/UpdateBookingComponent.vue diff --git a/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingRecipientLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingRecipientLogic.php new file mode 100644 index 00000000..8bdee9e3 --- /dev/null +++ b/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingRecipientLogic.php @@ -0,0 +1,94 @@ + 'Updated Booking', + 'message' => 'You have successfully updated the Booking' + ]; + } + + /** @var CanUpdateBooking */ + private $canUpdateBooking; + + /** @var UpdatesBooking */ + private $updatesBooking; + + /** @var FetchesBooking */ + private $fetchesBooking; + + + /** + * UpdateBookingRecipientLogic constructor. + * @param CanUpdateBooking $canUpdateBooking + * @param UpdatesBooking $updatesBooking + * @param FetchesBooking $fetchesBooking + */ + public function __construct( + CanUpdateBooking $canUpdateBooking, + UpdatesBooking $updatesBooking, + FetchesBooking $fetchesBooking + ) + { + $this->canUpdateBooking = $canUpdateBooking; + $this->updatesBooking = $updatesBooking; + $this->fetchesBooking = $fetchesBooking; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws ErrorException + */ + public function logic(Request $request) : JsonResponse + { + try { + DB::beginTransaction(); + + $booking = $this->fetchesBooking->execute(['id' => $request->route('id')]); + + + $booking_object = new BookingObject( + $booking->service_id, + $request->input('transferable_bank_id', $booking->transferable_bank_id), + $booking->marking, + $booking->fix_amount, + $booking->fix_currency_id, + $booking->convertible_currency_id, + $booking->conversion_currency_id + ); + $this->canUpdateBooking->passes($booking_object); + $booking = $this->updatesBooking->execute($booking, $booking_object); + + DB::commit(); + + return $this->resourceResponse(new BookingResource($booking)); + + } catch (\Exception $exception){ + throw new ErrorException($exception->getMessage(), $exception->getCode()); + } + } + +} diff --git a/app/Http/Controllers/Bookings/UpdateBookingRecipientController.php b/app/Http/Controllers/Bookings/UpdateBookingRecipientController.php new file mode 100644 index 00000000..670db6da --- /dev/null +++ b/app/Http/Controllers/Bookings/UpdateBookingRecipientController.php @@ -0,0 +1,20 @@ +execute($request); + } + +} diff --git a/resources/assets/vue/components/banks/forms/BankAccountFormComponent.vue b/resources/assets/vue/components/banks/forms/BankAccountFormComponent.vue index 6e9518d9..e1fd6f0d 100644 --- a/resources/assets/vue/components/banks/forms/BankAccountFormComponent.vue +++ b/resources/assets/vue/components/banks/forms/BankAccountFormComponent.vue @@ -136,9 +136,12 @@
{{disabled ? 'Change Recipient Account' : 'Cancel'}}
-
+
Add Account
+
+
Update Details
+
@@ -179,6 +182,10 @@ type: String, required: false, default: 'RMB' + }, + isEditing: { + type: Boolean, + default: false } }, data(){ @@ -224,10 +231,22 @@ }, methods: { submitForm(){ - this.submit(route('api.bank.create'), 'post', this.section, true, false); + if(this.isEditing){ + this.parameters.company_id = this.company_id; + this.parameters.account_type = this.type; + this.submit(route('api.bank.update', this.parameters.id), 'put', this.section, true, false); + } + else{ + this.submit(route('api.bank.create'), 'post', this.section, true, false); + } }, successHandler(response){ - this.type !== 2 ? this.closeModal() : this.$emit('createdBank', response.payload.data); + if(this.isEditing){ + this.type !== 2 ? this.closeModal() : this.$emit('updatedBankDetails', response.payload.data); + } + else{ + this.type !== 2 ? this.closeModal() : this.$emit('createdBank', response.payload.data); + } this.formHandler(); this.resetForm(); }, diff --git a/resources/assets/vue/components/banks/forms/PhoneAccountFormComponent.vue b/resources/assets/vue/components/banks/forms/PhoneAccountFormComponent.vue index 76401d2b..aea24179 100644 --- a/resources/assets/vue/components/banks/forms/PhoneAccountFormComponent.vue +++ b/resources/assets/vue/components/banks/forms/PhoneAccountFormComponent.vue @@ -42,9 +42,12 @@
{{disabled ? 'Change Recipient Account' : 'Cancel'}}
-
+
+
+ +
@@ -80,6 +83,10 @@ type: Object, required: false, default: null + }, + isEditing: { + type: Boolean, + default: false } }, data(){ @@ -115,10 +122,22 @@ submitForm(){ this.parameters.account_type = 3; this.parameters.bank_name = '-'; - this.submit(route('api.bank.create'), 'post', this.section, true, false); + if(this.isEditing){ + this.parameters.company_id = this.company_id; + this.parameters.account_type = this.type; + this.submit(route('api.bank.update', this.parameters.id), 'put', this.section, true, false); + } + else{ + this.submit(route('api.bank.create'), 'post', this.section, true, false); + } }, successHandler(response){ - this.type !== 2 ? this.closeModal() : this.$emit('createdBank', response.payload.data); + if(this.isEditing){ + this.type !== 2 ? this.closeModal() : this.$emit('updatedBankDetails', response.payload.data); + } + else{ + this.type !== 2 ? this.closeModal() : this.$emit('createdBank', response.payload.data); + } this.formHandler(); this.resetForm(); }, @@ -140,4 +159,4 @@ mixins: [FormHandler] } - \ No newline at end of file + diff --git a/resources/assets/vue/components/bookings/elements/BookingRecipientEditComponent.vue b/resources/assets/vue/components/bookings/elements/BookingRecipientEditComponent.vue new file mode 100644 index 00000000..ffdbece2 --- /dev/null +++ b/resources/assets/vue/components/bookings/elements/BookingRecipientEditComponent.vue @@ -0,0 +1,141 @@ + + + diff --git a/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue b/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue index 37a51a43..e2f5dfad 100644 --- a/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue +++ b/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue @@ -81,6 +81,14 @@ +
+
+
EDIT
+
+ + + +
@@ -540,12 +548,26 @@ id: '', status: false }, - onlinePayment: { + onlinePayment: { id: '', status: false }, amount: (Math.round((this.data.outstanding_amount + Number.EPSILON) * 100) / 100).toFixed(2), - calculation: null + calculation: null, + recipientBanks: { + company: this.data.company, + serviceType: { + status: false, + id: this.data.service.id, + name: this.data.service.name, + currencies: this.data.service.configurations.currencies, + selectedCurrency: this.data.service.configurations.currencies[0] + }, + bankAccount: this.data.bank, + bankAccountDefault: this.data.bank, + recipientBanks: this.data.company.recipient_banks.accounts, + bookingId: this.data.id + } } }, validations () { @@ -575,14 +597,12 @@ id: bankCode, status: true, } - }, submitForm(){ this.parameters = { payment_method: this.paymentMethod.id, amount: this.amount }; - this.submit(route('api.booking.payment.quotation', this.item.id), 'post', this.section, false, false) this.calculation = null; }, @@ -600,9 +620,12 @@ cancelQuotation(){ this.calculation = null; this.expandPayment = false; + }, + updatedBankDetails(bank){ + this.item.bank = bank; } }, mixins: [componentHandler], directives: {money: VMoney} } - \ No newline at end of file + diff --git a/resources/assets/vue/components/bookings/forms/UpdateBookingComponent.vue b/resources/assets/vue/components/bookings/forms/UpdateBookingComponent.vue new file mode 100644 index 00000000..73d6d51f --- /dev/null +++ b/resources/assets/vue/components/bookings/forms/UpdateBookingComponent.vue @@ -0,0 +1,41 @@ + + + diff --git a/routes/booking.php b/routes/booking.php index 0cbeca76..e54ba278 100644 --- a/routes/booking.php +++ b/routes/booking.php @@ -7,6 +7,7 @@ Route::group(['prefix' => 'booking', 'as' => 'booking.', 'namespace' => 'Booking Route::get('/list', 'ListBookingsController@list')->name('list'); Route::post('/create', 'CreateBookingController@create')->name('create'); Route::put('/update/{id}', 'UpdateBookingController@update')->name('update'); + Route::put('/recipient/update/{id}', 'UpdateBookingRecipientController@update')->name('update.recipient'); Route::put('/cancel/{id}', 'CancelBookingController@cancel')->name('cancel'); Route::put('/restore/{id}', 'RestoreBookingController@restore')->name('restore'); Route::delete('/delete/{id}', 'DeleteBookingController@delete')->name('delete'); @@ -33,4 +34,4 @@ Route::group(['prefix' => 'booking', 'as' => 'booking.', 'namespace' => 'Booking Route::post('{id}/proforma/create', 'CreateProformaInvoiceTransaction@create')->name('proforma.create'); -}); \ No newline at end of file +}); From 0b37cf6e7275c5f5d18f4e8d51715b1b976a92f7 Mon Sep 17 00:00:00 2001 From: Dillon Date: Fri, 20 Jan 2023 23:47:22 +0800 Subject: [PATCH 002/434] Edit recipient details do not allow empty --- .../bookings/elements/BookingRecipientEditComponent.vue | 1 + .../vue/components/bookings/forms/UpdateBookingComponent.vue | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/assets/vue/components/bookings/elements/BookingRecipientEditComponent.vue b/resources/assets/vue/components/bookings/elements/BookingRecipientEditComponent.vue index ffdbece2..6240b629 100644 --- a/resources/assets/vue/components/bookings/elements/BookingRecipientEditComponent.vue +++ b/resources/assets/vue/components/bookings/elements/BookingRecipientEditComponent.vue @@ -129,6 +129,7 @@ this.createBank = false; this.isEditing = false; this.account_no = ''; + this.parameters.bankAccount = {}; }, cancelUpdate(){ this.parameters.bankAccount = this.parameters.bankAccountDefault; diff --git a/resources/assets/vue/components/bookings/forms/UpdateBookingComponent.vue b/resources/assets/vue/components/bookings/forms/UpdateBookingComponent.vue index 73d6d51f..16cae41c 100644 --- a/resources/assets/vue/components/bookings/forms/UpdateBookingComponent.vue +++ b/resources/assets/vue/components/bookings/forms/UpdateBookingComponent.vue @@ -3,7 +3,7 @@
-
+
From 9f2b431f215c04c255b42b9edf546e634bf8607b Mon Sep 17 00:00:00 2001 From: edmondlang Date: Sat, 16 Sep 2023 14:38:02 +0800 Subject: [PATCH 003/434] regenerate-invoice-with-first-bill-no --- .../RegenerateInvoiceBookingLogic.php | 48 ++++++++++++++----- ...oiceTransactionWithInvoiceNoProcessor.php} | 2 +- routes/web.php | 4 +- 3 files changed, 40 insertions(+), 14 deletions(-) rename app/Classes/Modules/Transactions/Processors/{CreateInvoiceTransactionProcessorWithInvoiceNo.php => CreateInvoiceTransactionWithInvoiceNoProcessor.php} (99%) diff --git a/app/Classes/Modules/Bookings/ControllersLogic/RegenerateInvoiceBookingLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/RegenerateInvoiceBookingLogic.php index 252412a2..6af18568 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/RegenerateInvoiceBookingLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/RegenerateInvoiceBookingLogic.php @@ -9,6 +9,7 @@ use App\Classes\Modules\Bookings\Services\UpdatesBookingStatus; use App\Classes\Modules\Transactions\Services\DeletesTransaction; use App\Classes\Modules\Documents\Services\DeletesDocument; use App\Classes\Modules\Transactions\Processors\CreateInvoiceTransactionProcessor; +use App\Classes\Modules\Transactions\Processors\CreateInvoiceTransactionWithInvoiceNoProcessor; use App\Classes\ValueObjects\Constants\DocumentType; use App\Http\Resources\BookingResource; @@ -16,6 +17,7 @@ use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\TransactionType; +use Illuminate\Support\Carbon; class RegenerateInvoiceBookingLogic extends AbstractControllerLogic { @@ -23,7 +25,8 @@ class RegenerateInvoiceBookingLogic extends AbstractControllerLogic /** * @return array */ - protected function notification():array { + protected function notification(): array + { return [ 'title' => 'Regenerate Booking Invoice', 'message' => 'You have successfully regenerate booking invoice' @@ -48,6 +51,9 @@ class RegenerateInvoiceBookingLogic extends AbstractControllerLogic /** @var CreateInvoiceTransactionProcessor */ private $createInvoiceTransactionProcessor; + /** @var CreateInvoiceTransactionWithInvoiceNoProcessor */ + private $createInvoiceTransactionWithInvoiceNoProcessor; + /** * FetchBookingLogic constructor. * @param CanFetchBooking $canFetchBooking @@ -56,6 +62,7 @@ class RegenerateInvoiceBookingLogic extends AbstractControllerLogic * @param UpdatesBookingStatus $updatesBookingStatus * @param DeletesDocument $deletesDocument * @param CreateInvoiceTransactionProcessor $createInvoiceTransactionProcessor + * @param CreateInvoiceTransactionWithInvoiceNoProcessor $createInvoiceTransactionWithInvoiceNoProcessor */ public function __construct( CanFetchBooking $canFetchBooking, @@ -63,15 +70,16 @@ class RegenerateInvoiceBookingLogic extends AbstractControllerLogic DeletesTransaction $deletesTransaction, UpdatesBookingStatus $updatesBookingStatus, DeletesDocument $deletesDocument, - CreateInvoiceTransactionProcessor $createInvoiceTransactionProcessor - ) - { + CreateInvoiceTransactionProcessor $createInvoiceTransactionProcessor, + CreateInvoiceTransactionWithInvoiceNoProcessor $createInvoiceTransactionWithInvoiceNoProcessor + ) { $this->canFetchBooking = $canFetchBooking; $this->fetchesBooking = $fetchesBooking; $this->deletesTransaction = $deletesTransaction; $this->updatesBookingStatus = $updatesBookingStatus; $this->deletesDocument = $deletesDocument; $this->createInvoiceTransactionProcessor = $createInvoiceTransactionProcessor; + $this->createInvoiceTransactionWithInvoiceNoProcessor = $createInvoiceTransactionWithInvoiceNoProcessor; } @@ -82,18 +90,37 @@ class RegenerateInvoiceBookingLogic extends AbstractControllerLogic * @throws \App\Classes\Exceptions\MalformedRequestException * @throws \App\Classes\Exceptions\RequestValidationException */ - public function logic(Request $request) : JsonResponse + public function logic(Request $request): JsonResponse { $this->canFetchBooking->passes(); - $booking = $this->fetchesBooking->execute([ - 'id' => $request->route('id'), - 'status' => ApprovalStatus::COMPLETED, - 'with_transactions' => true] + $booking = $this->fetchesBooking->execute( + [ + 'id' => $request->route('id'), + 'status' => ApprovalStatus::COMPLETED, + 'with_transactions' => true + ] ); $this->updatesBookingStatus->execute($booking, ApprovalStatus::APPROVED); + $firstInvoice = $booking->transactions() + ->whereIn('type', [TransactionType::INVOICE]) + ->withTrashed() + ->orderBy('created_at', 'asc') + ->first(); + + // get the first bill_no + $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(); + $currentInvoice->bill_no = $currentInvoice->bill_no ."-deleted-" . (string)(Carbon::now()->timestamp); + $currentInvoice->save(); + $transaction = $booking->transactions()->whereIn('type', [TransactionType::INVOICE, TransactionType::SUPPLIER_DELIVER])->get(); foreach ($transaction as $key => $row) { $this->deletesTransaction->execute($row); @@ -104,9 +131,8 @@ class RegenerateInvoiceBookingLogic extends AbstractControllerLogic $this->deletesDocument->execute($row); } - $this->createInvoiceTransactionProcessor->execute($booking); + $this->createInvoiceTransactionWithInvoiceNoProcessor->execute($booking, $firstBillNo); return $this->resourceResponse(new BookingResource($booking)); } - } diff --git a/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessorWithInvoiceNo.php b/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionWithInvoiceNoProcessor.php similarity index 99% rename from app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessorWithInvoiceNo.php rename to app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionWithInvoiceNoProcessor.php index 27dfbe59..612033f8 100644 --- a/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessorWithInvoiceNo.php +++ b/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionWithInvoiceNoProcessor.php @@ -21,7 +21,7 @@ use App\Classes\ValueObjects\Constants\DocumentType; use App\Models\Booking; use App\Models\SegmentConstant; -class CreateInvoiceTransactionProcessorWithInvoiceNo +class CreateInvoiceTransactionWithInvoiceNoProcessor { /** @var CreatesTransaction */ diff --git a/routes/web.php b/routes/web.php index e2357c00..d75c96b0 100644 --- a/routes/web.php +++ b/routes/web.php @@ -26,7 +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\Processors\CreateInvoiceTransactionWithInvoiceNoProcessor; use App\Classes\Modules\Transactions\Services\DeletesTransaction; use Illuminate\Support\Facades\Log; @@ -541,7 +541,7 @@ Route::get('/invoice/fix', function(){ $existing_invoice_bill_no->forceDelete(); } - (App()->make(CreateInvoiceTransactionProcessorWithInvoiceNo::class))->execute($booking, $bill_no); + (App()->make(CreateInvoiceTransactionWithInvoiceNoProcessor::class))->execute($booking, $bill_no); dump('regenerated invoice. Booking Marking - ' . $booking->marking . '. Bill_no - ' . $bill_no . '. Old bill_no - ' . $deletedInvoice->bill_no); Log::channel('regenerateInvoice')->info('regenerated invoice. Booking Marking - ' . $booking->marking . '. Bill_no - ' . $bill_no . '. Old bill_no - ' . $deletedInvoice->bill_no); } else { From cd80950d65bb5552d921a1c0e44be6611d89dbe6 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Sat, 23 Sep 2023 11:56:21 +0800 Subject: [PATCH 004/434] expired booking --- .../Commands/ExpiredBookingCommand.php | 95 +++++++++++++++++++ app/Console/Kernel.php | 4 + 2 files changed, 99 insertions(+) create mode 100644 app/Console/Commands/ExpiredBookingCommand.php diff --git a/app/Console/Commands/ExpiredBookingCommand.php b/app/Console/Commands/ExpiredBookingCommand.php new file mode 100644 index 00000000..2598b380 --- /dev/null +++ b/app/Console/Commands/ExpiredBookingCommand.php @@ -0,0 +1,95 @@ +updatesBookingStatus = $updatesBookingStatus; + } + + /** + * Execute the console command. + * + * @return int + */ + public function handle() + { + // Cancel booking without payment & purchase order (1 month) + $bookings = Booking::where('status', ApprovalStatus::APPROVED) + ->where('created_at', '<', now()->subDays(30)->endOfDay()) + ->where(function ($query) { + $query->whereDoesntHave('transactions') + ->orWhereDoesntHave('transactions', function($transaction) { + return $transaction->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); + }); + })->get(); + + foreach ($bookings as $booking) { + $this->updatesBookingStatus->execute($booking, ApprovalStatus::EXPIRED); + Log::info("Expired Booking without payment & purchase order, booking id: " . $booking->id); + $transactions = $booking->transactions; + + foreach ($transactions as $transaction) { + $transaction->status = ApprovalStatus::EXPIRED; + $transaction->save(); + Log::info("Expired Transaction id: {$transaction->id} from Booking id: {$booking->id}"); + } + } + + // Cancel booking without payment but with purchase order (2 month) + $bookings = Booking::where('status', ApprovalStatus::APPROVED) + ->where('created_at', '<', now()->subDays(60)->endOfDay()) + ->where(function ($query) { + $query->whereDoesntHave('transactions', function($transaction) { + return $transaction->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); + })->whereHas('transactions', function($transaction) { + return $transaction->where('type', TransactionType::PURCHASE_ORDER); + }); + })->get(); + + foreach ($bookings as $booking) { + $this->updatesBookingStatus->execute($booking, ApprovalStatus::EXPIRED); + Log::info("Expired Booking without payment but with purchase order, booking id: " . $booking->id); + $transactions = $booking->transactions; + + foreach ($transactions as $transaction) { + $transaction->status = ApprovalStatus::EXPIRED; + $transaction->save(); + Log::info("Expired Transaction id: {$transaction->id} from Booking id: {$booking->id}"); + } + } + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index cb9cf060..0355aea1 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -43,6 +43,10 @@ class Kernel extends ConsoleKernel ->everyMinute() ->appendOutputTo(storage_path().'/logs/regenerateInvoice.log') ->withoutOverlapping(); + + $schedule->command('booking:expired') + ->dailyAt('02:00') + ->withoutOverlapping(); } /** From 32602cab31318eb8813696fdd238a17181cfd38b Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Sat, 23 Sep 2023 13:00:04 +0800 Subject: [PATCH 005/434] auto fill purchase order command --- .../Commands/AutoFillPurchaseOrderCommand.php | 112 ++++++++++++++++++ .../Commands/ExpiredBookingCommand.php | 4 +- 2 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 app/Console/Commands/AutoFillPurchaseOrderCommand.php diff --git a/app/Console/Commands/AutoFillPurchaseOrderCommand.php b/app/Console/Commands/AutoFillPurchaseOrderCommand.php new file mode 100644 index 00000000..059232d2 --- /dev/null +++ b/app/Console/Commands/AutoFillPurchaseOrderCommand.php @@ -0,0 +1,112 @@ +generatesPurchaseOrderProducts = $generatesPurchaseOrderProducts; + $this->generatesTransactionBillNumber = $generatesTransactionBillNumber; + $this->createPurchaseOrderTransactionProcessor = $createPurchaseOrderTransactionProcessor; + } + + /** + * Execute the console command. + * + * @return int + */ + public function handle() + { + $bookings = Booking::where('status', ApprovalStatus::APPROVED) + ->where('created_at', '<', now()->subDays(60)->endOfDay()) + ->whereHas('transactions', function($transaction) { + return $transaction->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); + }) + ->whereDoesntHave('transactions', function($transaction){ + $transaction->where('type', TransactionType::PURCHASE_ORDER); + $transaction->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED]); + })->get(); + + foreach ($bookings as $booking) { + $po = Transaction::where('type', TransactionType::PURCHASE_ORDER) + ->where('status', ApprovalStatus::APPROVED)->where('issuer', $booking->company_id) + ->select('*', DB::raw('abs(amount - ' . $booking->fix_amount . ') as nearest_price'))->orderBy('nearest_price')->first(); + + + if (!$po) { + $po = Transaction::where('type', TransactionType::PURCHASE_ORDER) + ->where('status', ApprovalStatus::APPROVED)->select('*', DB::raw('abs(amount - ' . $booking->fix_amount . ') as nearest_price'))->orderBy('nearest_price')->first(); + } + + $products = $this->generatesPurchaseOrderProducts->execute($po, $booking->fix_amount); + + $deference = $booking->fix_amount - $products->sum('total'); + + if($deference > -150 && $deference < 150 && $deference != 0) { + + $products->push([ + 'description' => $deference < 0 ? 'Discount':'Shipping Fee', + 'quantity' => 1, + 'stockCode' => '', + 'total' => $deference, + 'unit_price' => $deference + ]); + } + + $billNumber = $this->generatesTransactionBillNumber->execute('XPO-'); + + $total = $products->sum('total'); + + $object = new TransactionObject($billNumber, TransactionType::PURCHASE_ORDER, $booking->company->id, 1, + 1, PaymentMethodType::CASH, + $total, $total, $booking->fix_currency_id, $booking->fix_currency_id, + 1, 0, 0, null, ApprovalStatus::PENDING_SUBMISSION, $products->toArray()); + + $this->createPurchaseOrderTransactionProcessor->execute($booking, $object); + } + } +} diff --git a/app/Console/Commands/ExpiredBookingCommand.php b/app/Console/Commands/ExpiredBookingCommand.php index 2598b380..37fe8612 100644 --- a/app/Console/Commands/ExpiredBookingCommand.php +++ b/app/Console/Commands/ExpiredBookingCommand.php @@ -55,7 +55,7 @@ class ExpiredBookingCommand extends Command ->orWhereDoesntHave('transactions', function($transaction) { return $transaction->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); }); - })->get(); + })->get(); foreach ($bookings as $booking) { $this->updatesBookingStatus->execute($booking, ApprovalStatus::EXPIRED); @@ -78,7 +78,7 @@ class ExpiredBookingCommand extends Command })->whereHas('transactions', function($transaction) { return $transaction->where('type', TransactionType::PURCHASE_ORDER); }); - })->get(); + })->get(); foreach ($bookings as $booking) { $this->updatesBookingStatus->execute($booking, ApprovalStatus::EXPIRED); From f1c23d46dde54f6cbcd768df15370d4972624b54 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Tue, 26 Sep 2023 21:30:51 +0800 Subject: [PATCH 006/434] update --- app/Console/Commands/AutoFillPurchaseOrderCommand.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Console/Commands/AutoFillPurchaseOrderCommand.php b/app/Console/Commands/AutoFillPurchaseOrderCommand.php index 059232d2..65a6fa93 100644 --- a/app/Console/Commands/AutoFillPurchaseOrderCommand.php +++ b/app/Console/Commands/AutoFillPurchaseOrderCommand.php @@ -16,7 +16,7 @@ use App\Classes\ValueObjects\Constants\PaymentMethodType; use App\Models\Transaction; use Illuminate\Support\Facades\DB; -class ExpiredBookingCommand extends Command +class AutoFillPurchaseOrderCommand extends Command { /** * The name and signature of the console command. @@ -61,6 +61,7 @@ class ExpiredBookingCommand extends Command */ public function handle() { + // 5. If purchase order not fill up in 2 month, auto fill up it $bookings = Booking::where('status', ApprovalStatus::APPROVED) ->where('created_at', '<', now()->subDays(60)->endOfDay()) ->whereHas('transactions', function($transaction) { From 75f44fae74126045ebf5ac58108e374596b7045e Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Tue, 26 Sep 2023 21:31:09 +0800 Subject: [PATCH 007/434] update --- app/Console/Commands/ExpiredBookingCommand.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Console/Commands/ExpiredBookingCommand.php b/app/Console/Commands/ExpiredBookingCommand.php index 37fe8612..c5b4081c 100644 --- a/app/Console/Commands/ExpiredBookingCommand.php +++ b/app/Console/Commands/ExpiredBookingCommand.php @@ -47,7 +47,7 @@ class ExpiredBookingCommand extends Command */ public function handle() { - // Cancel booking without payment & purchase order (1 month) + // 1. Cancel booking without payment & purchase order (1 month) $bookings = Booking::where('status', ApprovalStatus::APPROVED) ->where('created_at', '<', now()->subDays(30)->endOfDay()) ->where(function ($query) { @@ -69,7 +69,7 @@ class ExpiredBookingCommand extends Command } } - // Cancel booking without payment but with purchase order (2 month) + // 2. Cancel booking without payment but with purchase order (2 month) $bookings = Booking::where('status', ApprovalStatus::APPROVED) ->where('created_at', '<', now()->subDays(60)->endOfDay()) ->where(function ($query) { From 4be3b11a505c663a78f6f6abc42223f5fe0e1bc5 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Tue, 26 Sep 2023 21:32:20 +0800 Subject: [PATCH 008/434] add auto fill purchase order job inside kernel --- app/Console/Kernel.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 0355aea1..46e77f3a 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -47,6 +47,10 @@ class Kernel extends ConsoleKernel $schedule->command('booking:expired') ->dailyAt('02:00') ->withoutOverlapping(); + + $schedule->command('purchaseOrder:autoFill') + ->dailyAt('03:00') + ->withoutOverlapping(); } /** From a84cbdde6a09d0fecc4342f1014e868fae868f36 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Wed, 27 Sep 2023 14:12:32 +0800 Subject: [PATCH 009/434] add cancel booking for refunded payment --- .../Commands/ExpiredBookingCommand.php | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/app/Console/Commands/ExpiredBookingCommand.php b/app/Console/Commands/ExpiredBookingCommand.php index c5b4081c..d79b7b9c 100644 --- a/app/Console/Commands/ExpiredBookingCommand.php +++ b/app/Console/Commands/ExpiredBookingCommand.php @@ -9,6 +9,7 @@ use Illuminate\Console\Command; use Carbon\Carbon; use Illuminate\Support\Facades\Log; use App\Classes\Modules\Bookings\Services\UpdatesBookingStatus; +use App\Models\Transaction; class ExpiredBookingCommand extends Command { @@ -91,5 +92,62 @@ class ExpiredBookingCommand extends Command Log::info("Expired Transaction id: {$transaction->id} from Booking id: {$booking->id}"); } } + + // 3. Cancel fully refunded payment & cancel booking + $transactions = Transaction::where('type', TransactionType::CREDIT_NOTE)->get(); + + foreach ($transactions as $transaction) { + // get the booking marking + $marking = substr($transaction->payment_reference, -5); + + // for a special payment reference on transaction id: 152013 + if (!is_numeric($marking)) { + $payment_reference = explode(" ", trim($transaction->payment_reference)); + if (count($payment_reference) > 1) { + $marking = $payment_reference[count($payment_reference) - 2]; + } + } + + if (is_numeric($marking)) { + $booking = Booking::where('marking', $marking)->first(); + + if ($booking) { + if ($booking->status === ApprovalStatus::APPROVED) { + $bookingPayment = $booking->transactions()->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->first(); + if (!$bookingPayment) { + $bookingPayment = $booking->transactions()->payments()->count(); + Log::info("Credit note transaction id: {$transaction->id}, there are {$bookingPayment} payment for the booking."); + $bookingPayment = $booking->transactions()->payments()->whereIn('status', [ApprovalStatus::EXPIRED, ApprovalStatus::REJECTED])->first(); + $status = ApprovalStatus::APPROVAL_STATUS_ID[$bookingPayment->status]; + Log::info("Credit note transaction id: {$transaction->id}, the payment for the booking is in status {$status}"); + } + $bookingPaymentAmount = $bookingPayment->amount; + // check if the booking is fully refund + $amountDifference = bcsub($transaction->amount, $bookingPaymentAmount); + + if (abs($amountDifference) < 0.01) { + // rejecting booking payment transaction + $bookingPayment->status = ApprovalStatus::REJECTED; + $bookingPayment->save(); + + //expired booking + $this->updatesBookingStatus->execute($booking, ApprovalStatus::EXPIRED); + Log::info("Credit note transaction id: {$transaction->id} is fully refunded, the refunded amount was {$transaction->amount} the payment reference is: {$transaction->payment_reference}"); + Log::info("Credit note transaction id: {$transaction->id}, Rejected Booking Transaction Payment id: {$bookingPayment->id}, the payment amount was {$bookingPayment->amount}"); + Log::info("Credit note transaction id: {$transaction->id}, Expired Booking id: {$booking->id}"); + } else { + Log::info("Credit note transaction id: {$transaction->id} is not fully refunded, the refunded amount was {$transaction->amount}, the payment amount was {$bookingPayment->amount}, the payment reference is: {$transaction->payment_reference}"); + } + } else { + $status = ApprovalStatus::APPROVAL_STATUS_ID[$booking->status]; + Log::info("Credit note transaction id: {$transaction->id}, booking status is {$status}"); + } + } else { + Log::info("Credit note transaction id: {$transaction->id}, booking marking not found, the payment reference is: {$transaction->payment_reference}"); + } + } else { + Log::info("Credit note transaction id: {$transaction->id} does not have booking marking, the payment reference is: {$transaction->payment_reference}"); + } + } } } From 946ee7b6f978305c69f8099aed9f8a9e33d4781c Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Fri, 29 Sep 2023 15:42:15 +0800 Subject: [PATCH 010/434] refund booking --- .../CreateBookingRefundLogic.php | 20 ++++++++++--------- .../UpdateRefundTransactionStatusLogic.php | 4 +++- .../elements/PaymentHistoryComponent.vue | 6 +++--- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php index d31ee2ce..398312c9 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php @@ -19,6 +19,7 @@ use App\Classes\Modules\Bookings\Services\CalculatesBookingRefundAmount; use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject; use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber; use App\Classes\Modules\Transactions\DataTransferObjects\TransactionRefundCalculationObject; +use App\Classes\ValueObjects\Constants\PaymentMethodType; class CreateBookingRefundLogic extends AbstractControllerLogic { @@ -84,21 +85,22 @@ class CreateBookingRefundLogic extends AbstractControllerLogic $billNumber = $this->generatesTransactionBillNumber->execute('RFD-'); - $refund = $transaction->transactions()->refunds()->sum('amount'); + $refund = $transaction->transactions()->refunds()->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED])->sum('original_amount'); if($refund + $request->input('amount') > $transaction->original_amount) throw new MalformedRequestException('Your refund must not be greater than '. $transaction->original_amount .'.'); - $amount = $transaction->booking->fix_currency_id == 1 ? $request->input('amount') : $request->input('amount') / $transaction->currency_rate; + // $transactionRefundCalculationObject = new TransactionRefundCalculationObject($booking, $transaction, $request->input('amount')); + // $transactionRefundCalculationObject->init(); - - $transactionRefundCalculationObject = new TransactionRefundCalculationObject($booking, $transaction, $amount); - $transactionRefundCalculationObject->init(); + $refundAmount = bcdiv($request->input('amount'), $transaction->currency_rate, 7); + // refund service charges if is fully refund + $refundTotal = ($refund + $request->input('amount')) == $transaction->original_amount ? $refundAmount + $transaction->service_charge + $transaction->tax : $refundAmount; $object = new TransactionObject($billNumber, TransactionType::REFUND, 1, $booking->company->id, - 1, $transactionRefundCalculationObject->getConversionObject()->getPaymentMethod(), - $transactionRefundCalculationObject->getRefundTotalAmount(), $transactionRefundCalculationObject->getAmount(), 1, - $transactionRefundCalculationObject->getConversionObject()->getCurrencyId(), $transactionRefundCalculationObject->getTransaction()->currency_rate, - $transactionRefundCalculationObject->getRefundTax(), $transactionRefundCalculationObject->getRefundServiceCharge(), null, ApprovalStatus::PENDING_VERIFICATION, [], $transaction->bill_no); + 1, PaymentMethodType::CASH, + $refundTotal, $request->input('amount'), 1, + $transaction->original_currency_id, $transaction->currency_rate, + $transaction->tax, $transaction->service_charge, null, ApprovalStatus::PENDING_VERIFICATION, [], $transaction->bill_no); $transaction = $this->createsTransaction->execute($transaction, $object); diff --git a/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php index b86e4878..bf704359 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php @@ -73,7 +73,9 @@ class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic $booking = $transaction->owner->owner; - $reference = 'Credit Voucher for Overpaid for Ref. '.$booking->marking; + $paymentTransaction = $transaction->owner; + + $reference = $transaction->amount == $paymentTransaction->amount ? 'Fully Refund for Ref. ' . $booking->marking : 'Partially Refund for Ref. ' . $booking->marking; if ($transaction->status == ApprovalStatus::APPROVED) { $this->creditWalletProcessor->execute($booking->company, $transaction->type, $transaction->amount, $reference); diff --git a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue index ce4ba5a7..63cb4687 100644 --- a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue +++ b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue @@ -133,7 +133,7 @@
Requested Refund Amount
-
{{item.currency.short_code}} {{(Math.round((totalRequestedRefund + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
+
{{item.original_currency.short_code}} {{(Math.round((totalRequestedRefund + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
@@ -271,9 +271,9 @@
-
+
- + From 05b5823fe4d9c579bbd84440865a0efb35c67b92 Mon Sep 17 00:00:00 2001 From: Steve Ng Date: Mon, 23 Oct 2023 09:20:35 +0800 Subject: [PATCH 011/434] fixing unable mapping records and filtering function in Pending Export tab and listing data not same in Pending Export tab with export Invoice to autocount and calculate mapped percentage --- .../StatementTransactionPostingEnd.php | 18 +++++ .../StatementTransactionPostingStart.php | 18 +++++ ...ankStatementTransactionOwnersProcessor.php | 49 +++++++------ .../Services/ExportsInvoiceTransactions.php | 27 +++---- app/Models/AccountStatement.php | 2 + ...apped_rate_to_account_statements_table.php | 34 +++++++++ .../StatementTransactionComponent.vue | 2 +- .../sections/TransactionsMappingComponent.vue | 71 +++++++++++++++++-- 8 files changed, 182 insertions(+), 39 deletions(-) create mode 100644 app/Classes/General/Eloquent/Filters/StatementTransactionPostingEnd.php create mode 100644 app/Classes/General/Eloquent/Filters/StatementTransactionPostingStart.php create mode 100644 database/migrations/2023_10_22_140339_add_mapped_rate_to_account_statements_table.php diff --git a/app/Classes/General/Eloquent/Filters/StatementTransactionPostingEnd.php b/app/Classes/General/Eloquent/Filters/StatementTransactionPostingEnd.php new file mode 100644 index 00000000..e837245e --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/StatementTransactionPostingEnd.php @@ -0,0 +1,18 @@ +whereDate('posting_date', '<=', date('Y-m-d',strtotime($value))); + } +} \ No newline at end of file diff --git a/app/Classes/General/Eloquent/Filters/StatementTransactionPostingStart.php b/app/Classes/General/Eloquent/Filters/StatementTransactionPostingStart.php new file mode 100644 index 00000000..c3560357 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/StatementTransactionPostingStart.php @@ -0,0 +1,18 @@ +whereDate('posting_date', '>=', date('Y-m-d',strtotime($value))); + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Accounting/Processors/CreateBankStatementTransactionOwnersProcessor.php b/app/Classes/Modules/Accounting/Processors/CreateBankStatementTransactionOwnersProcessor.php index 36fc684a..6f7efe5e 100644 --- a/app/Classes/Modules/Accounting/Processors/CreateBankStatementTransactionOwnersProcessor.php +++ b/app/Classes/Modules/Accounting/Processors/CreateBankStatementTransactionOwnersProcessor.php @@ -28,6 +28,7 @@ class CreateBankStatementTransactionOwnersProcessor // $transactions = StatementTransaction::whereDoesntHave('owners')->where('amount', '<', 0)->get(); foreach ($transactions as $transaction) { + $mapped = false; $keywords = array_filter(explode(" ", $transaction->transaction_description . " " . $transaction->transaction_description_2)); if($transaction->amount > 0){ @@ -36,7 +37,7 @@ class CreateBankStatementTransactionOwnersProcessor $creditTransactions = $this->getTransactions($transaction->posting_date, $transaction->amount, TransactionType::PAYMENT, Booking::class, PaymentMethodType::WALLET, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED], $keywords); foreach ($creditTransactions as $creditTransaction) { $isArray = is_array($creditTransaction); - $transaction->owners()->firstOrCreate([ + $data = $transaction->owners()->firstOrCreate([ 'type' => StatementTransactionOwnerType::SALES, 'system' => 'EXCHANGE', 'owner_type' => Transaction::class, @@ -45,12 +46,11 @@ class CreateBankStatementTransactionOwnersProcessor ]); } - // Shipping Portal Sales - $creditTransactions = $this->getTransactionsFromShippingPortal($transaction->amount, $this->getDateRange($transaction->posting_date, 1), 2, PaymentMethodType::WALLET); + $creditTransactions = $this->getTransactionsFromShippingPortal($transaction->amount, $this->getDateRange($transaction->posting_date, 1), [2], PaymentMethodType::WALLET); foreach ($creditTransactions as $creditTransaction) { if($creditTransaction['owner_type'] === Wallet::class) continue; - $transaction->owners()->firstOrCreate([ + $data = $transaction->owners()->firstOrCreate([ 'type' => StatementTransactionOwnerType::SALES, 'system' => 'SHIPPING_PORTAL', 'owner_type' => $creditTransaction['owner_type'], @@ -63,7 +63,7 @@ class CreateBankStatementTransactionOwnersProcessor $creditTransactions = $this->getTransactions($transaction->posting_date, $transaction->amount, TransactionType::TOP_UP, Wallet::class, null, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED], $keywords); foreach ($creditTransactions as $creditTransaction) { $isArray = is_array($creditTransaction); - $transaction->owners()->firstOrCreate([ + $data = $transaction->owners()->firstOrCreate([ 'type' => StatementTransactionOwnerType::WALLET_TOP_UP, 'system' => 'EXCHANGE', 'owner_type' => Transaction::class, @@ -72,9 +72,9 @@ class CreateBankStatementTransactionOwnersProcessor ]); } - $creditTransactions = $this->getTransactionsFromShippingPortal($transaction->amount, $this->getDateRange($transaction->posting_date, 1), 5, null); + $creditTransactions = $this->getTransactionsFromShippingPortal($transaction->amount, $this->getDateRange($transaction->posting_date, 1), [5,15], null); foreach ($creditTransactions as $creditTransaction) { - $transaction->owners()->firstOrCreate([ + $data = $transaction->owners()->firstOrCreate([ 'type' => StatementTransactionOwnerType::WALLET_TOP_UP, 'system' => 'SHIPPING_PORTAL', 'owner_type' => $creditTransaction['owner_type'], @@ -85,7 +85,7 @@ class CreateBankStatementTransactionOwnersProcessor // fpx charge refund if($transaction->transaction_description === 'DUITNOW S/CHRG REFUND'){ - $transaction->owners()->firstOrCreate([ + $data = $transaction->owners()->firstOrCreate([ 'type' => StatementTransactionOwnerType::FPX_CHARGE_REFUND ]); } @@ -94,7 +94,7 @@ class CreateBankStatementTransactionOwnersProcessor // INTERNAL_BANK_TRANSFER_IN if(str_contains($transaction->transaction_description_2, 'CIEF WORLDWIDE')){ - $transaction->owners()->firstOrCreate([ + $data = $transaction->owners()->firstOrCreate([ 'type' => StatementTransactionOwnerType::INTERNAL_BANK_TRANSFER_IN ]); } @@ -119,7 +119,7 @@ class CreateBankStatementTransactionOwnersProcessor ->where('amount', '<=', (($transaction->amount * -1) + 0.01))->whereDate('created_at', '>=', $paymentDateStart)->whereDate('created_at', '<=', $paymentDateEnd)->get(); foreach ($debitTransactions as $debitTransaction) { - $transaction->owners()->firstOrCreate([ + $data = $transaction->owners()->firstOrCreate([ 'type' => StatementTransactionOwnerType::SUPPLIER_PAYMENT, 'system' => 'EXCHANGE', 'owner_type' => Group::class, @@ -135,7 +135,7 @@ class CreateBankStatementTransactionOwnersProcessor $debitTransactions = $this->getTransactions($transaction->posting_date, $transaction->amount, TransactionType::DEBIT_NOTE, Wallet::class, null, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED], $keywords); foreach ($debitTransactions as $debitTransaction) { $isArray = is_array($creditTransaction); - $transaction->owners()->firstOrCreate([ + $data = $transaction->owners()->firstOrCreate([ 'type' => StatementTransactionOwnerType::WALLET_WITHDRAWAL, 'system' => 'EXCHANGE', 'owner_type' => Transaction::class, @@ -148,50 +148,52 @@ class CreateBankStatementTransactionOwnersProcessor // STATUTORY if(str_contains($transaction->transaction_description_2, 'PEMBANGUNAN SUMBER') || str_contains($transaction->transaction_description_2, 'HASIL') || str_contains($transaction->transaction_description_2, 'PERTUBUHAN KESELAMAT') || str_contains($transaction->transaction_description_2, 'KUMPULAN WANG SIMPAN')){ - $transaction->owners()->firstOrCreate([ + $data = $transaction->owners()->firstOrCreate([ 'type' => StatementTransactionOwnerType::STATUTORY ]); } // FPX_CHARGE if($transaction->transaction_description === 'DR DUITNOW S/CHRG' || str_contains($transaction->transaction_description, 'Manual FPX') || str_contains($transaction->transaction_description, 'CMS - DR FPX CHG')){ - $transaction->owners()->firstOrCreate([ + $data = $transaction->owners()->firstOrCreate([ 'type' => StatementTransactionOwnerType::FPX_CHARGE ]); } // BANK_CHARGE if($transaction->transaction_description === 'CMS - DR CORP CHG' || $transaction->transaction_description === 'MONTHLY PROFIT DEBIT'){ - $transaction->owners()->firstOrCreate([ + $data = $transaction->owners()->firstOrCreate([ 'type' => StatementTransactionOwnerType::BANK_CHARGE ]); } // CREDIT_CARD_PAYMENT if(str_contains($transaction->transaction_description_2, 'VISA CARD')){ - $transaction->owners()->firstOrCreate([ + $data = $transaction->owners()->firstOrCreate([ 'type' => StatementTransactionOwnerType::CREDIT_CARD_PAYMENT ]); } // INTERNAL_BANK_TRANSFER_OUT if(str_contains($transaction->transaction_description_2, 'CIEF WORLDWIDE') || str_contains($transaction->transaction_description_2, 'CIEF WORLWIDE') || str_contains($transaction->transaction_description_2, 'IZYIM GLOBAL')){ - $transaction->owners()->firstOrCreate([ + $data = $transaction->owners()->firstOrCreate([ 'type' => StatementTransactionOwnerType::INTERNAL_BANK_TRANSFER_OUT ]); } // non-operational charges if(str_contains($transaction->transaction_description_2, 'HIRE PURCHASE') || str_contains($transaction->transaction_description_2, 'TENAGA NASIONAL') || str_contains($transaction->transaction_description, 'CABLE CHARGE') || str_contains($transaction->transaction_description_2, 'CTOS DATA SYSTEMS') || str_contains($transaction->transaction_description_2, 'MAXIS')){ - $transaction->owners()->firstOrCreate([ + $data = $transaction->owners()->firstOrCreate([ 'type' => StatementTransactionOwnerType::NON_OPERATIONAL ]); } } + if (isset($data) && $data->wasRecentlyCreated) $mapped = true; + $this->updateMappedRate($transaction, $mapped); } - } + } - private function getTransactions($date, $amount, $type, $ownerType, $paymentMethod, $statuses, $keywords, $model = Transaction::class) { + private function getTransactions($date, $amount, $type, $ownerType, $paymentMethod, $statuses, $keywords, $model = Transaction::class) { $dateRange = $this->getDateRange($date, 4); if (App::environment(['production'])) { $query = $model::whereIn('status', $statuses) @@ -318,7 +320,7 @@ class CreateBankStatementTransactionOwnersProcessor try{ $client = new \GuzzleHttp\Client(['verify' => false]); - $response = $client->request('GET', $url.'?api-key=510acd13d8d24375cf038ad626c282565451461a9c2399357e0b65365300787e&filters={"order_by":{"column":"id","DESC":true},"status_in":[2]'.$paymentMethodFilter.',"created_after":"'.$dateRange['start_date'].'","created_before":"'.$dateRange['end_date'].'","amount_exceed":'.($amount - 0.01).',"amount_short":'.($amount + 0.01).',"type_in":['.$type.']}'); + $response = $client->request('GET', $url.'?api-key=510acd13d8d24375cf038ad626c282565451461a9c2399357e0b65365300787e&filters={"order_by":{"column":"id","DESC":true},"status_in":[2]'.$paymentMethodFilter.',"created_after":"'.$dateRange['start_date'].'","created_before":"'.$dateRange['end_date'].'","amount_exceed":'.($amount - 0.01).',"amount_short":'.($amount + 0.01).',"type_in":'.json_encode($type).'}'); $body = $response->getBody(); $data = json_decode($body, true); $payload = $data['payload']; @@ -345,4 +347,11 @@ class CreateBankStatementTransactionOwnersProcessor 'end_date' => $nextDay, ]; } + + private function updateMappedRate($transaction, $mapped) { + $statement = $transaction->statement; + $statement->total_rows = StatementTransaction::where('account_statement_id',$transaction->account_statement_id)->count(); + $statement->mapped_rows = $mapped ? $statement->mapped_rows+1 : $statement->mapped_rows; + $statement->save(); + } } diff --git a/app/Classes/Modules/Exports/Services/ExportsInvoiceTransactions.php b/app/Classes/Modules/Exports/Services/ExportsInvoiceTransactions.php index 79ca4380..2ecaada8 100644 --- a/app/Classes/Modules/Exports/Services/ExportsInvoiceTransactions.php +++ b/app/Classes/Modules/Exports/Services/ExportsInvoiceTransactions.php @@ -4,7 +4,6 @@ namespace App\Classes\Modules\Exports\Services; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\StatementTransactionOwnerType; -use App\Models\StatementTransactionOwner; use App\Models\Transaction; use Maatwebsite\Excel\Concerns\Exportable; use Maatwebsite\Excel\Concerns\FromQuery; @@ -18,6 +17,8 @@ use App\Classes\Modules\Accounting\Processors\ListShippingPortalTransactions; use App\Classes\ValueObjects\Constants\ShippingTransactionType; use App\Classes\ValueObjects\Constants\TransactionType; use Illuminate\Support\Facades\Log; +use App\Classes\General\Eloquent\ApplyFiltersToQuery; +use App\Models\StatementTransaction; class ExportsInvoiceTransactions implements FromQuery, WithHeadings, WithHeadingRow, WithMapping, ShouldAutoSize { @@ -64,10 +65,9 @@ class ExportsInvoiceTransactions implements FromQuery, WithHeadings, WithHeading */ public function query() { - $data = StatementTransactionOwner::whereNull('invoice_reference') - ->whereIn('type', [StatementTransactionOwnerType::SALES, StatementTransactionOwnerType::WALLET_TOP_UP]) - ->whereIn('status', [ApprovalStatus::COMPLETED, ApprovalStatus::APPROVED]); - if ($this->request->has('bankStatementOwnerId')) $data = $data->whereIn('id',json_decode($this->request->input('bankStatementOwnerId'))); + $data = (new ApplyFiltersToQuery())->execute(StatementTransaction::query(), json_decode($this->request->input('filter'), true)); + if ($this->request->has('bankStatementTransactionId')) $data = $data->whereIn('id',json_decode($this->request->input('bankStatementTransactionId'), true)); + return $data; } @@ -78,11 +78,12 @@ class ExportsInvoiceTransactions implements FromQuery, WithHeadings, WithHeading */ public function map($transaction): array { + $statementTransactionOwner = $transaction->owners()->whereIn('status', [ApprovalStatus::APPROVED])->first(); $logArray = [ 'counter' => $this->counter, - 'system' => $transaction->system, - 'StatementTransactionOwner_id' => $transaction->id, - 'transaction_table_id' => $transaction->owner_id, + 'system' => $statementTransactionOwner->system, + 'StatementTransactionOwner_id' => $statementTransactionOwner->id, + 'transaction_table_id' => $statementTransactionOwner->owner_id, ]; $this->counter += 1; $logArray = json_encode($logArray); @@ -92,8 +93,8 @@ class ExportsInvoiceTransactions implements FromQuery, WithHeadings, WithHeading $textToAppend = Carbon::now()->format('[Y-m-d H:i:s]') . ' ' . $logArray . PHP_EOL; file_put_contents($filePath, $textToAppend, FILE_APPEND); - if ($transaction->system == 'EXCHANGE') { - $row = (App()->make($transaction->owner_type))->where('id', $transaction->owner_id)->first(); + if ($statementTransactionOwner->system == 'EXCHANGE') { + $row = (App()->make($statementTransactionOwner->owner_type))->where('id', $statementTransactionOwner->owner_id)->first(); $company = $row->type === TransactionType::PAYMENT ? $row->owner->company : $row->owner->owner; $booking = $row->owner; @@ -116,15 +117,15 @@ class ExportsInvoiceTransactions implements FromQuery, WithHeadings, WithHeading ]; } else { $row = (App()->make(ListShippingPortalTransactions::class))->execute([ - 'id' => $transaction->owner_id, + 'id' => $statementTransactionOwner->owner_id, 'with_company' => true, ]); if (empty($row) || $row[0]['status'] != 'success') { $textToAppend = Carbon::now()->format('[Y-m-d H:i:s]') . ' Fetch Shipping Transaction Fail ' . json_encode([ - 'id' => $transaction->owner_id, + 'id' => $statementTransactionOwner->owner_id, 'with_company' => true, - 'StatementTransactionOwner_id' => $transaction->id, + 'StatementTransactionOwner_id' => $statementTransactionOwner->id, ]) . PHP_EOL; file_put_contents($errorFilePath, $textToAppend, FILE_APPEND); diff --git a/app/Models/AccountStatement.php b/app/Models/AccountStatement.php index d9e53d60..2f5b0e8c 100644 --- a/app/Models/AccountStatement.php +++ b/app/Models/AccountStatement.php @@ -16,6 +16,8 @@ class AccountStatement extends Model 'total_amount', 'begin_balance', 'end_balance', + 'total_rows', + 'mapped_rows', ]; protected $casts = [ diff --git a/database/migrations/2023_10_22_140339_add_mapped_rate_to_account_statements_table.php b/database/migrations/2023_10_22_140339_add_mapped_rate_to_account_statements_table.php new file mode 100644 index 00000000..f6a8e7e7 --- /dev/null +++ b/database/migrations/2023_10_22_140339_add_mapped_rate_to_account_statements_table.php @@ -0,0 +1,34 @@ +integer('total_rows')->unsigned()->default(0)->after('end_balance'); + $table->integer('mapped_rows')->unsigned()->default(0)->after('end_balance'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('account_statements', function (Blueprint $table) { + $table->dropColumn('total_rows'); + $table->dropColumn('mapped_rows'); + }); + } +} diff --git a/resources/assets/vue/components/accounting/elements/StatementTransactionComponent.vue b/resources/assets/vue/components/accounting/elements/StatementTransactionComponent.vue index 1caef408..b09b9a56 100644 --- a/resources/assets/vue/components/accounting/elements/StatementTransactionComponent.vue +++ b/resources/assets/vue/components/accounting/elements/StatementTransactionComponent.vue @@ -126,7 +126,7 @@
- +
Pending...
diff --git a/resources/assets/vue/components/accounting/sections/TransactionsMappingComponent.vue b/resources/assets/vue/components/accounting/sections/TransactionsMappingComponent.vue index 9d74dce1..4604f2e5 100644 --- a/resources/assets/vue/components/accounting/sections/TransactionsMappingComponent.vue +++ b/resources/assets/vue/components/accounting/sections/TransactionsMappingComponent.vue @@ -74,6 +74,32 @@
+ + +
+
+
+ + + + +
+
+ + + + +
+
+
+ + Search + +
+
+
+
+
@@ -202,6 +228,10 @@ export default { data(){ return { + parameters: { + startDate: '', + endDate: '', + }, type: null, stage: null, exportStage: 0, @@ -215,6 +245,14 @@ export default { } }, validations: { + parameters: { + startDate: { + required + }, + endDate: { + required + }, + }, files: { // required // todo-new: set required if is pdf section } @@ -227,17 +265,31 @@ export default { this.mappedTrue = true; }, exportInvoiceToAutoCount(){ - window.open(this.route('invoiceTransactions.export')+'?bankStatementOwnerId='+this.getCheckedStatementOwners()+'&type=invoices', '_blank'); + const checkedStatementTransactions = this.getCheckedStatementOwners(); + + let route = this.route('invoiceTransactions.export')+'?type=invoices&filter='+JSON.stringify(this.filter); + if (checkedStatementTransactions) { + route += '&bankStatementTransactionId='+checkedStatementTransactions; + } + + window.open(route, '_blank'); }, exportReceiptToAutoCount(){ - window.open(this.route('invoiceTransactions.export')+'?bankStatementOwnerId='+this.getCheckedStatementOwners()+'&type=receipts', '_blank'); + const checkedStatementTransactions = this.getCheckedStatementOwners(); + + let route = this.route('invoiceTransactions.export')+'?type=receipts&filter='+JSON.stringify(this.filter); + if (checkedStatementTransactions) { + route += '&bankStatementTransactionId='+checkedStatementTransactions; + } + + window.open(route, '_blank'); }, getCheckedStatementOwners() { - let bankStatementOwnerId = []; + let bankStatementTransactionId = []; $('.request_export_item:checked').each(function() { - bankStatementOwnerId.push($(this).val()); + bankStatementTransactionId.push($(this).val()); }); - return JSON.stringify(bankStatementOwnerId); + return (bankStatementTransactionId.length > 0 ? JSON.stringify(bankStatementTransactionId) : null); }, successHandler(){ this.step += 1; @@ -263,6 +315,10 @@ export default { break; case 4: this.filter = {min_amount: 0, is_mapped: true, statement_transaction_owner_type_in: [1, 2], statement_transaction_owner_status_in: [2], per_page: 100, order_by: {column: 'posting_date', DESC: true}} + + if (typeof this.parameters.startDate != 'undefined' && this.parameters.startDate != '') this.filter = {...this.filter, ...{statement_transaction_posting_start: this.parameters.startDate}}; + + if (typeof this.parameters.endDate != 'undefined' && this.parameters.endDate != '') this.filter = {...this.filter, ...{statement_transaction_posting_end:this.parameters.endDate}}; break; } } @@ -280,6 +336,11 @@ export default { break; case 4: this.filter = {max_amount: 0, is_mapped: true, statement_transaction_owner_type_in: [3, 5], statement_transaction_owner_status_in: [2], per_page: 100, order_by: {column: 'posting_date', DESC: true}} + + if (typeof this.parameters.startDate != 'undefined' && this.parameters.startDate != '') this.filter = {...this.filter, ...{statement_transaction_posting_start: this.parameters.startDate}}; + + if (typeof this.parameters.endDate != 'undefined' && this.parameters.endDate != '') this.filter = {...this.filter, ...{statement_transaction_posting_end:this.parameters.endDate}}; + break; } } From bc5a8a91939e3b992a20ff0bb61069ba505bebd4 Mon Sep 17 00:00:00 2001 From: Steve Ng Date: Tue, 24 Oct 2023 21:21:51 +0800 Subject: [PATCH 012/434] fix bug in function import invoices --- .../Imports/ImportStatementInvoiceController.php | 10 ++-------- app/Models/StatementTransactionOwner.php | 1 + app/Models/Transaction.php | 16 ++++++++++++++++ 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/app/Http/Controllers/Imports/ImportStatementInvoiceController.php b/app/Http/Controllers/Imports/ImportStatementInvoiceController.php index 7ea3454e..73e58e87 100644 --- a/app/Http/Controllers/Imports/ImportStatementInvoiceController.php +++ b/app/Http/Controllers/Imports/ImportStatementInvoiceController.php @@ -137,16 +137,10 @@ class ImportStatementInvoiceController private function mappingExchange(Array $row) { $date = $row['date']; - $transactions = Transaction::where('original_amount', $row['net_total'])->whereRaw("DATE(created_at) = '$date'") - ->whereHas('receiverCompany', function($q) use($row) { - $q->where('debtor',$row['debtor_code']); - })->get(); + $transactions = Transaction::getReceiverWithJoinStatementTransactionAndOwner($row)->select('transactions.*')->where('statement_transactions.amount', $row['net_total'])->whereRaw("DATE(posting_date) = '$date'")->get(); if ($transactions && $transactions->count() == 0) { - $transactions = Transaction::where(DB::raw('FLOOR(original_amount)'), floor($row['net_total']))->whereRaw("DATE(created_at) = '$date'") - ->whereHas('receiverCompany', function($q) use($row) { - $q->where('debtor',$row['debtor_code']); - })->get(); + $transactions = Transaction::getReceiverWithJoinStatementTransactionAndOwner($row)->select('transactions.*')->where(DB::raw('FLOOR(statement_transactions.amount)'), floor($row['net_total']))->whereRaw("DATE(posting_date) = '$date'")->get(); } if ($transactions && $transactions->count() == 1) { diff --git a/app/Models/StatementTransactionOwner.php b/app/Models/StatementTransactionOwner.php index fb13f4b4..bd96efff 100644 --- a/app/Models/StatementTransactionOwner.php +++ b/app/Models/StatementTransactionOwner.php @@ -5,6 +5,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\MorphTo; class StatementTransactionOwner extends Model { diff --git a/app/Models/Transaction.php b/app/Models/Transaction.php index 631a5fa5..185fdb36 100644 --- a/app/Models/Transaction.php +++ b/app/Models/Transaction.php @@ -221,6 +221,22 @@ class Transaction extends AbstractModel implements Documentable, Transactionable return $query->whereIn('status', [ApprovalStatus::APPROVED]); } + /** + * @param Builder $query + * @return Builder + */ + public function scopeGetReceiverWithJoinStatementTransactionAndOwner(Builder $query, Array $row) { + $query->join('companies',function($q) use ($row) { + $q->on('companies.id','=','transactions.receiver'); + $q->where('debtor',$row['debtor_code']); + }) + ->join('statement_transaction_owners', function ($q) { + $q->on('statement_transaction_owners.owner_id','=','transactions.id'); + $q->where('statement_transaction_owners.owner_type','=',Transaction::class); + }) + ->join('statement_transactions','statement_transactions.id','=','statement_transaction_owners.statement_transaction_id'); + } + /** * @return MorphMany */ From 910f190075c82c4e2467abab2318e6236f1365cd Mon Sep 17 00:00:00 2001 From: Steve Ng Date: Wed, 25 Oct 2023 18:03:31 +0800 Subject: [PATCH 013/434] fixing the unknown tab to list the transactions of is_mapped false and also mapped and status in rejected --- .../IsMappedFalseOrMappedButStatusIn.php | 25 +++++++++++++++++++ .../sections/TransactionsMappingComponent.vue | 2 +- 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 app/Classes/General/Eloquent/Filters/IsMappedFalseOrMappedButStatusIn.php diff --git a/app/Classes/General/Eloquent/Filters/IsMappedFalseOrMappedButStatusIn.php b/app/Classes/General/Eloquent/Filters/IsMappedFalseOrMappedButStatusIn.php new file mode 100644 index 00000000..8b264ff5 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/IsMappedFalseOrMappedButStatusIn.php @@ -0,0 +1,25 @@ +where(function($q) use ($value) { + $q->whereDoesntHave('owners'); + $q->orwhereHas('owners', function($query) use ($value) { + $query->whereIn('status', $value); + }); + }); + } + +} diff --git a/resources/assets/vue/components/accounting/sections/TransactionsMappingComponent.vue b/resources/assets/vue/components/accounting/sections/TransactionsMappingComponent.vue index 4604f2e5..160221bf 100644 --- a/resources/assets/vue/components/accounting/sections/TransactionsMappingComponent.vue +++ b/resources/assets/vue/components/accounting/sections/TransactionsMappingComponent.vue @@ -311,7 +311,7 @@ export default { this.filter = {min_amount: 0, is_mapped: true, is_mapped_with_multiple: true, statement_transaction_owner_type_in: [1, 2], statement_transaction_owner_status_in: [1], per_page: 100, order_by: {column: 'posting_date', DESC: true}} break; case 3: - this.filter = {min_amount: 0, is_mapped: false, per_page: 100, order_by: {column: 'posting_date', DESC: true}} + this.filter = {min_amount: 0, is_mapped_false_or_mapped_but_status_in: [4], per_page: 100, order_by: {column: 'posting_date', DESC: true}} break; case 4: this.filter = {min_amount: 0, is_mapped: true, statement_transaction_owner_type_in: [1, 2], statement_transaction_owner_status_in: [2], per_page: 100, order_by: {column: 'posting_date', DESC: true}} From f47c3c9ecc1e4cfdb81121c85759d88a8ae80431 Mon Sep 17 00:00:00 2001 From: Steve Ng Date: Thu, 26 Oct 2023 00:01:10 +0800 Subject: [PATCH 014/434] fixing the unknown tab to list the transactions of is_mapped false and also mapped and status in rejected --- .../Eloquent/Filters/IsMappedFalseOrMappedButStatusIn.php | 4 +--- app/Models/StatementTransaction.php | 5 +++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/Classes/General/Eloquent/Filters/IsMappedFalseOrMappedButStatusIn.php b/app/Classes/General/Eloquent/Filters/IsMappedFalseOrMappedButStatusIn.php index 8b264ff5..c0eb9e74 100644 --- a/app/Classes/General/Eloquent/Filters/IsMappedFalseOrMappedButStatusIn.php +++ b/app/Classes/General/Eloquent/Filters/IsMappedFalseOrMappedButStatusIn.php @@ -16,9 +16,7 @@ class IsMappedFalseOrMappedButStatusIn implements Filter { return $builder->where(function($q) use ($value) { $q->whereDoesntHave('owners'); - $q->orwhereHas('owners', function($query) use ($value) { - $query->whereIn('status', $value); - }); + $q->orwhereDoesntHave('owner_status'); }); } diff --git a/app/Models/StatementTransaction.php b/app/Models/StatementTransaction.php index eb4bcdc8..4bba7903 100644 --- a/app/Models/StatementTransaction.php +++ b/app/Models/StatementTransaction.php @@ -49,6 +49,11 @@ class StatementTransaction extends Model return $this->hasMany(StatementTransactionOwner::class); } + public function owner_status() + { + return $this->owners()->whereIn('status',[ApprovalStatus::APPROVED,ApprovalStatus::COMPLETED,ApprovalStatus::PENDING_VERIFICATION]); + } + public function scopeDoesntMapStatement($query) { $query->whereDoesntHave('owners', function($query){ From 5b681ac8c05e2f1f1fbd9b2292caaa2982322f26 Mon Sep 17 00:00:00 2001 From: Steve Ng Date: Sun, 29 Oct 2023 08:44:31 +0800 Subject: [PATCH 015/434] fixing the structure of export receipt to autocount and import receipt to exchange map failed --- .../Services/ExportsInvoiceTransactions.php | 21 +-- .../Services/ExportsReceiptTransactions.php | 132 ++++++++++++++++++ .../ExportCustomersToExcelController.php | 10 +- .../ImportStatementReceiptsController.php | 11 +- .../sections/TransactionsMappingComponent.vue | 5 +- routes/web.php | 1 + 6 files changed, 158 insertions(+), 22 deletions(-) create mode 100644 app/Classes/Modules/Exports/Services/ExportsReceiptTransactions.php diff --git a/app/Classes/Modules/Exports/Services/ExportsInvoiceTransactions.php b/app/Classes/Modules/Exports/Services/ExportsInvoiceTransactions.php index 2ecaada8..796ec19d 100644 --- a/app/Classes/Modules/Exports/Services/ExportsInvoiceTransactions.php +++ b/app/Classes/Modules/Exports/Services/ExportsInvoiceTransactions.php @@ -34,19 +34,12 @@ class ExportsInvoiceTransactions implements FromQuery, WithHeadings, WithHeading public function headings(): array { - $header = []; - if ($this->request->input('type') == 'invoices') { - $header[] = 'DocNo'; - $header[] = 'DocDate'; - $header[] = 'DebtorCode'; - } else { - $header[] = 'OrNo'; - $header[] = 'OrDate'; - $header[] = 'CreditorCode'; - } - $header[] = 'Ref'; - $header[] = ($this->request->input('type') == 'invoices' ? 'DebtorName' : 'CreditorName'); - $header = array_merge($header, [ + $header = [ + 'DocNo', + 'DocDate', + 'DebtorCode', + 'Ref', + 'DebtorName', 'CurrencyCode', 'ShipInfo', 'ItemCode', @@ -56,7 +49,7 @@ class ExportsInvoiceTransactions implements FromQuery, WithHeadings, WithHeading 'UnitPrice', 'AccNo', 'DeptNo' - ]); + ]; return $header; } diff --git a/app/Classes/Modules/Exports/Services/ExportsReceiptTransactions.php b/app/Classes/Modules/Exports/Services/ExportsReceiptTransactions.php new file mode 100644 index 00000000..07c5d3c1 --- /dev/null +++ b/app/Classes/Modules/Exports/Services/ExportsReceiptTransactions.php @@ -0,0 +1,132 @@ +request = $request; + } + + public function headings(): array + { + $header = [ + 'DocNo', + 'DocDate', + 'DebtorCode', + 'Description', + 'DocNo2', + 'ProjNo', + 'DeptNo', + 'CurrencyCode', + 'ToHomeRate', + 'ToDebtorRate', + 'Note', + 'PaymentMethod', + 'ChequeNo', + 'PaymentAmt', + 'BankCharge', + 'ToBankRate', + 'BankChargeTaxType', + 'BankChargeTaxRefNo', + 'BankChargeProjNo', + 'BankChargeDeptNo', + 'PaymentBy', + 'FloatDay', + 'IsRCHQ', + 'RCHQDate', + 'KnockOffDocType', + 'KnockOffDocNo', + 'KnockOffAmt', + '', + ]; + return $header; + } + + /** + * @return \Illuminate\Support\Collection|mixed + */ + public function query() + { + $data = (new ApplyFiltersToQuery())->execute(StatementTransaction::query(), json_decode($this->request->input('filter'), true)); + if ($this->request->has('bankStatementTransactionId')) $data = $data->whereIn('id',json_decode($this->request->input('bankStatementTransactionId'), true)); + + return $data; + } + + /** + * @param StatementTransaction $transaction + * + * @return array + */ + public function map($transaction): array + { + $statementTransactionOwner = $transaction->owners()->whereIn('status', [ApprovalStatus::APPROVED])->first(); + $logArray = [ + 'counter' => $this->counter, + 'system' => $statementTransactionOwner->system, + 'StatementTransactionOwner_id' => $statementTransactionOwner->id, + 'transaction_table_id' => $statementTransactionOwner->owner_id, + ]; + $this->counter += 1; + $logArray = json_encode($logArray); + + $filePath = storage_path('logs/exports_receipt_transactions.log'); + $errorFilePath = storage_path('logs/exports_receipt_transactions_error.log'); + $textToAppend = Carbon::now()->format('[Y-m-d H:i:s]') . ' ' . $logArray . PHP_EOL; + file_put_contents($filePath, $textToAppend, FILE_APPEND); + + $company = Company::where('name',$transaction->transaction_description_2)->first(); + + return [ + '<>', + Carbon::parse($transaction->posting_date)->format('d/m/Y'), + ($company ? $company->debtor : null), + $transaction->transaction_description, + '', + '', + '', + 'MYR', + 1, + 1, + '', + 'MBB', + '', + $transaction->amount, + '', + 1, + '', + '', + '', + '', + '', + '0', + '', + '', + 'RI', + $transaction->transaction_ref, + $transaction->amount, + '', + ]; + } +} diff --git a/app/Http/Controllers/Exports/ExportCustomersToExcelController.php b/app/Http/Controllers/Exports/ExportCustomersToExcelController.php index 7dfe0485..733c84fa 100644 --- a/app/Http/Controllers/Exports/ExportCustomersToExcelController.php +++ b/app/Http/Controllers/Exports/ExportCustomersToExcelController.php @@ -17,6 +17,7 @@ use Illuminate\Support\Facades\Auth; use Maatwebsite\Excel\Excel; use App\Classes\Modules\Exports\Services\ExportsImportedInvoiceMappeds; use App\Models\TransactionMappingLog; +use App\Classes\Modules\Exports\Services\ExportsReceiptTransactions; class ExportCustomersToExcelController { @@ -61,7 +62,14 @@ class ExportCustomersToExcelController public function invoiceTransactions(Request $request){ $exportsTransactions = new ExportsInvoiceTransactions($request); - $response = $exportsTransactions->download(($request->input('type') == 'invoices' ? 'invoice-transactions' : 'receipt-transactions').'.xls', Excel::XLS, ['Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']); + $response = $exportsTransactions->download('invoice-transactions.xls', Excel::XLS, ['Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']); + ob_end_clean(); + return $response; + } + + public function receiptTransactions(Request $request){ + $exportsTransactions = new ExportsReceiptTransactions($request); + $response = $exportsTransactions->download('receipt-transactions.xls', Excel::XLS, ['Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']); ob_end_clean(); return $response; } diff --git a/app/Http/Controllers/Imports/ImportStatementReceiptsController.php b/app/Http/Controllers/Imports/ImportStatementReceiptsController.php index 8021e3a9..f3b89db7 100644 --- a/app/Http/Controllers/Imports/ImportStatementReceiptsController.php +++ b/app/Http/Controllers/Imports/ImportStatementReceiptsController.php @@ -21,6 +21,7 @@ use App\Models\TransactionMappingLog; use App\Classes\ValueObjects\Response\ApiResponseObject; use App\Classes\ValueObjects\Constants\HttpStatus; use Illuminate\Http\JsonResponse; +use Illuminate\Support\Facades\DB; class ImportStatementReceiptsController { @@ -78,11 +79,11 @@ class ImportStatementReceiptsController private function mappingExchange(Array $row) { $date = $row['date']; - $transactions = Transaction::where('original_amount', $row['local_payment_amount'])->whereRaw("DATE(created_at) = '$date'") - ->whereHas('issuerCompany', function($q) use($row) { - $q->where('debtor',$row['debtor_code']); - }) - ->get(); + $transactions = Transaction::getReceiverWithJoinStatementTransactionAndOwner($row)->select('transactions.*')->where('statement_transactions.amount', $row['payment_amount'])->whereRaw("DATE(posting_date) = '$date'")->get(); + + if ($transactions && $transactions->count() == 0) { + $transactions = Transaction::getReceiverWithJoinStatementTransactionAndOwner($row)->select('transactions.*')->where(DB::raw('FLOOR(statement_transactions.amount)'), floor($row['payment_amount']))->whereRaw("DATE(posting_date) = '$date'")->get(); + } if ($transactions && $transactions->count() == 1) { foreach ($transactions as $key => $transaction) { diff --git a/resources/assets/vue/components/accounting/sections/TransactionsMappingComponent.vue b/resources/assets/vue/components/accounting/sections/TransactionsMappingComponent.vue index 160221bf..7a677bad 100644 --- a/resources/assets/vue/components/accounting/sections/TransactionsMappingComponent.vue +++ b/resources/assets/vue/components/accounting/sections/TransactionsMappingComponent.vue @@ -267,7 +267,7 @@ export default { exportInvoiceToAutoCount(){ const checkedStatementTransactions = this.getCheckedStatementOwners(); - let route = this.route('invoiceTransactions.export')+'?type=invoices&filter='+JSON.stringify(this.filter); + let route = this.route('invoiceTransactions.export')+'?filter='+JSON.stringify(this.filter); if (checkedStatementTransactions) { route += '&bankStatementTransactionId='+checkedStatementTransactions; } @@ -277,7 +277,8 @@ export default { exportReceiptToAutoCount(){ const checkedStatementTransactions = this.getCheckedStatementOwners(); - let route = this.route('invoiceTransactions.export')+'?type=receipts&filter='+JSON.stringify(this.filter); + this.filter['statement_transaction_owner_type_in'] = [3,4,5,7,13,14]; + let route = this.route('receiptTransactions.export')+'?filter='+JSON.stringify(this.filter); if (checkedStatementTransactions) { route += '&bankStatementTransactionId='+checkedStatementTransactions; } diff --git a/routes/web.php b/routes/web.php index 1dece5c3..18f8aa86 100644 --- a/routes/web.php +++ b/routes/web.php @@ -261,6 +261,7 @@ Route::get('/export/payment-transactions/f614e339d7058904a831aad742e24d55', 'Exp Route::get('/export/wallet-transactions/f614e339d7058904a831aad742e24d55', 'Exports\ExportCustomersToExcelController@walletTransactions')->name('walletTransactions.export'); Route::get('/export/booking-transactions', 'Exports\ExportCustomersToExcelController@bookingTransactions')->name('export.transactions.booking'); Route::get('/export/invoice-transactions/f614e339d7058904a831aad742e24d55', 'Exports\ExportCustomersToExcelController@invoiceTransactions')->name('invoiceTransactions.export'); +Route::get('/export/invoice-transactions/f614e339d7058904a831aad742e24d55', 'Exports\ExportCustomersToExcelController@receiptTransactions')->name('receiptTransactions.export'); Route::get('/export/imported-invoice-mapped', 'Exports\ExportCustomersToExcelController@importedInvoiceMapped')->name('importedInvoiceMapped.export'); Route::get('/products', function (\App\Classes\Modules\Exports\Services\ExportsProducts $exportsProducts) { From 5c5f54e03b6256131291cedf79d75e3d5ba0f6cc Mon Sep 17 00:00:00 2001 From: edmondlang Date: Mon, 30 Oct 2023 18:39:19 +0800 Subject: [PATCH 016/434] delete booking / expire the order payment --- .../ExpireBookingPaymentControllerLogic.php | 57 +++++++++++++++++++ .../ExpireBookingPaymentController.php | 20 +++++++ .../BookingDetailsSectionComponent.vue | 16 ++++++ routes/booking.php | 1 + 4 files changed, 94 insertions(+) create mode 100644 app/Classes/Modules/Bookings/ControllersLogic/ExpireBookingPaymentControllerLogic.php create mode 100644 app/Http/Controllers/Bookings/ExpireBookingPaymentController.php diff --git a/app/Classes/Modules/Bookings/ControllersLogic/ExpireBookingPaymentControllerLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/ExpireBookingPaymentControllerLogic.php new file mode 100644 index 00000000..8ee2bbfa --- /dev/null +++ b/app/Classes/Modules/Bookings/ControllersLogic/ExpireBookingPaymentControllerLogic.php @@ -0,0 +1,57 @@ + 'Expire Payment', + 'message' => 'You have successfully expire the Payment' + ]; + } + + /** @var FetchesBooking */ + private $fetchesBooking; + + /** + * DeletePurchaseOrderPdfLogic constructor. + * @param FetchesBooking $fetchesBooking + */ + public function __construct(fetchesBooking $fetchesBooking) + { + $this->fetchesBooking = $fetchesBooking; + } + + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\MalformedRequestException + */ + public function logic(Request $request) : JsonResponse + { + $booking = $this->fetchesBooking->execute(['id' => $request->route('id')]); + + $payment = $booking->transactions() + ->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]) + ->first(); + + $payment->status = ApprovalStatus::EXPIRED; + $payment->save(); + + return $this->response([]); + } + +} diff --git a/app/Http/Controllers/Bookings/ExpireBookingPaymentController.php b/app/Http/Controllers/Bookings/ExpireBookingPaymentController.php new file mode 100644 index 00000000..f09fa38a --- /dev/null +++ b/app/Http/Controllers/Bookings/ExpireBookingPaymentController.php @@ -0,0 +1,20 @@ +execute($request); + } + +} \ No newline at end of file diff --git a/resources/assets/vue/components/bookings/sections/BookingDetailsSectionComponent.vue b/resources/assets/vue/components/bookings/sections/BookingDetailsSectionComponent.vue index a65c2ce8..a2762ce7 100644 --- a/resources/assets/vue/components/bookings/sections/BookingDetailsSectionComponent.vue +++ b/resources/assets/vue/components/bookings/sections/BookingDetailsSectionComponent.vue @@ -289,6 +289,22 @@
+
+
+
Delete Transfer
+
+ + + + +
diff --git a/routes/booking.php b/routes/booking.php index 81db27b6..119d24fa 100644 --- a/routes/booking.php +++ b/routes/booking.php @@ -19,6 +19,7 @@ Route::group(['prefix' => 'booking', 'as' => 'booking.', 'namespace' => 'Booking Route::post('create', 'CreateBookingPaymentController@create')->name('create'); Route::post('{payment_id}/verification/create', 'CreatePaymentVerificationController@create')->name('verification.create'); Route::put('/{payment_id}/approval/{status}', 'ApprovePaymentVerificationController@approve')->where('status', 'approve|reject')->name('approval'); + Route::post('delete', 'ExpireBookingPaymentController@expire')->name('expire'); }); Route::group(['prefix' => '{id}/refund', 'as' => 'refund.'], function () { From 4bf32ac28521dd0f36329e7395b6b19cd98c9854 Mon Sep 17 00:00:00 2001 From: Steve Ng Date: Wed, 1 Nov 2023 13:43:36 +0800 Subject: [PATCH 017/434] fix bug of update status of statement transaction owner when update invoice or receipt success, and paginate when next page with filtering date in Pending Export tab, and error on export invoive to autocount --- .../Controllers/Imports/ImportStatementInvoiceController.php | 5 ++++- .../Imports/ImportStatementReceiptsController.php | 5 ++++- .../assets/vue/components/general/elements/ListComponent.vue | 1 + routes/web.php | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/Imports/ImportStatementInvoiceController.php b/app/Http/Controllers/Imports/ImportStatementInvoiceController.php index 73e58e87..6cfdec08 100644 --- a/app/Http/Controllers/Imports/ImportStatementInvoiceController.php +++ b/app/Http/Controllers/Imports/ImportStatementInvoiceController.php @@ -154,7 +154,10 @@ class ImportStatementInvoiceController public function updateTransactionOwnerReference($transaction, String $docNo) { $transactionOwner = $transaction->transaction_owner; if ($transactionOwner) { - $transactionOwner->update(['invoice_reference'=>$docNo]); + $transactionOwner->update([ + 'invoice_reference'=>$docNo, + 'status'=>ApprovalStatus::COMPLETED + ]); return $transactionOwner->owner_reference; } return false; diff --git a/app/Http/Controllers/Imports/ImportStatementReceiptsController.php b/app/Http/Controllers/Imports/ImportStatementReceiptsController.php index f3b89db7..3c919376 100644 --- a/app/Http/Controllers/Imports/ImportStatementReceiptsController.php +++ b/app/Http/Controllers/Imports/ImportStatementReceiptsController.php @@ -96,7 +96,10 @@ class ImportStatementReceiptsController public function updateTransactionOwnerReference($transaction, String $docNo) { $transactionOwner = $transaction->transaction_owner; if ($transactionOwner) { - $transactionOwner->update(['receipt_reference'=>$docNo]); + $transactionOwner->update([ + 'receipt_reference'=>$docNo, + 'status'=>ApprovalStatus::COMPLETED + ]); return $transactionOwner->owner_reference; } return false; diff --git a/resources/assets/vue/components/general/elements/ListComponent.vue b/resources/assets/vue/components/general/elements/ListComponent.vue index 50d2fa19..8f54548b 100644 --- a/resources/assets/vue/components/general/elements/ListComponent.vue +++ b/resources/assets/vue/components/general/elements/ListComponent.vue @@ -99,6 +99,7 @@ updateFilters(filters){ this.filters = filters; this.setDecoratorDefault(); + this.$store.dispatch('updateListQueue', {'name': this.section, 'page': 1, 'filters': this.filters}); this.submit(this.endpoint + '?page=1&filters=' + JSON.stringify(this.filters), 'get', this.section, false, false) }, successHandler(response){ diff --git a/routes/web.php b/routes/web.php index 18f8aa86..989d3296 100644 --- a/routes/web.php +++ b/routes/web.php @@ -261,7 +261,7 @@ Route::get('/export/payment-transactions/f614e339d7058904a831aad742e24d55', 'Exp Route::get('/export/wallet-transactions/f614e339d7058904a831aad742e24d55', 'Exports\ExportCustomersToExcelController@walletTransactions')->name('walletTransactions.export'); Route::get('/export/booking-transactions', 'Exports\ExportCustomersToExcelController@bookingTransactions')->name('export.transactions.booking'); Route::get('/export/invoice-transactions/f614e339d7058904a831aad742e24d55', 'Exports\ExportCustomersToExcelController@invoiceTransactions')->name('invoiceTransactions.export'); -Route::get('/export/invoice-transactions/f614e339d7058904a831aad742e24d55', 'Exports\ExportCustomersToExcelController@receiptTransactions')->name('receiptTransactions.export'); +Route::get('/export/receipt-transactions/f614e339d7058904a831aad742e24d55', 'Exports\ExportCustomersToExcelController@receiptTransactions')->name('receiptTransactions.export'); Route::get('/export/imported-invoice-mapped', 'Exports\ExportCustomersToExcelController@importedInvoiceMapped')->name('importedInvoiceMapped.export'); Route::get('/products', function (\App\Classes\Modules\Exports\Services\ExportsProducts $exportsProducts) { From db88edabfe8116c4685ea862515d3d1de6377d90 Mon Sep 17 00:00:00 2001 From: Steve Ng Date: Sat, 4 Nov 2023 10:45:41 +0800 Subject: [PATCH 018/434] fix bug unmapped invoice --- .../Services/ExportsInvoiceTransactions.php | 19 ++++++++++++++++++- .../ImportStatementInvoiceController.php | 9 +-------- .../ImportStatementReceiptsController.php | 9 +-------- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/app/Classes/Modules/Exports/Services/ExportsInvoiceTransactions.php b/app/Classes/Modules/Exports/Services/ExportsInvoiceTransactions.php index 796ec19d..a7041b1c 100644 --- a/app/Classes/Modules/Exports/Services/ExportsInvoiceTransactions.php +++ b/app/Classes/Modules/Exports/Services/ExportsInvoiceTransactions.php @@ -127,7 +127,24 @@ class ExportsInvoiceTransactions implements FromQuery, WithHeadings, WithHeading Log::info('Error in Exports Invoice Transactions ' . $this->counter); - return []; + return [ + 'Transaction Not Found', + $transaction->posting_date->format('m/d/Y H:m'), + $transaction->transaction_description.' - '.$transaction->transaction_description_2, + $statementTransactionOwner->system, + '', + '', + '', + '', + '', + '', + 0, + $transaction->amount, + '', + '', + '', + '' + ]; } $row = $row[0]; diff --git a/app/Http/Controllers/Imports/ImportStatementInvoiceController.php b/app/Http/Controllers/Imports/ImportStatementInvoiceController.php index 6cfdec08..8d2b920b 100644 --- a/app/Http/Controllers/Imports/ImportStatementInvoiceController.php +++ b/app/Http/Controllers/Imports/ImportStatementInvoiceController.php @@ -55,7 +55,7 @@ class ImportStatementInvoiceController foreach ($excelRows as $row) { $row['mapped_result_reference'] = null; $row['mapped_status'] = 'failed'; - $row['date'] = $this->changeExcelDate($row['date']); + $row['date'] = date('Y-m-d', strtotime($row['date'])); // Shipping Info // TOPUP -> map with transaction.bill_no @@ -162,11 +162,4 @@ class ImportStatementInvoiceController } return false; } - - public function changeExcelDate($date) - { - $unixTime = (($date - 25569) * 86400); - $date = new DateTime("@$unixTime"); - return $date->format('Y-m-d'); // Change the format to 'Y-m-d' - } } diff --git a/app/Http/Controllers/Imports/ImportStatementReceiptsController.php b/app/Http/Controllers/Imports/ImportStatementReceiptsController.php index 3c919376..4006e130 100644 --- a/app/Http/Controllers/Imports/ImportStatementReceiptsController.php +++ b/app/Http/Controllers/Imports/ImportStatementReceiptsController.php @@ -53,7 +53,7 @@ class ImportStatementReceiptsController foreach ($excelRows as $row) { $row['mapped_result_reference'] = null; $row['mapped_status'] = 'failed'; - $row['date'] = $this->changeExcelDate($row['doc_date']); + $row['date'] = date('Y-m-d', strtotime($row['doc_date'])); $returnReference = $this->mappingExchange($row); if ($returnReference) { @@ -104,11 +104,4 @@ class ImportStatementReceiptsController } return false; } - - public function changeExcelDate($date) - { - $unixTime = (($date - 25569) * 86400); - $date = new DateTime("@$unixTime"); - return $date->format('Y-m-d'); // Change the format to 'Y-m-d' - } } From 4de027c82f37df52d34615dae11a08e732b3a69a Mon Sep 17 00:00:00 2001 From: edmondlang Date: Thu, 9 Nov 2023 00:24:55 +0800 Subject: [PATCH 019/434] regenerate customer invoice in certain date period --- routes/web.php | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/routes/web.php b/routes/web.php index 7325c90b..0efe0616 100644 --- a/routes/web.php +++ b/routes/web.php @@ -766,3 +766,71 @@ Route::get('/customer/vouchers/{marking}', function ($marking) { })->name('customer.reward'); Route::get('transaction/{id}/credit_note/download', 'Transactions\GenerateCreditNotePdfController@download')->name('transaction.credit_note.download'); + +Route::get('/invoice/{marking}/{started_at}/{ended_at}/fix', function($marking, $started_at, $ended_at) { + + set_time_limit(14400); + $processed_invoice = 1; + + if (is_null($marking) || empty($marking)) { + return 'Error - Marking is empty'; + } + + if (is_null($started_at) || empty($started_at)) { + return 'Error - Start Date is empty'; + } + + if (is_null($ended_at) || empty($ended_at)) { + return 'Error - End Date is empty'; + } + + $company = Company::where('reference', $marking)->first(); + if (!$company) { + return 'Error - Marking not found'; + } + dump('Company Id - ' . $company->id); + + // dd($marking, $started_at, $ended_at); + + $bookings = $company->bookings() + ->where('status', ApprovalStatus::COMPLETED) + ->whereDate('updated_at', '>=', Carbon::parse($started_at)) + ->whereDate('updated_at', '<=', Carbon::parse($ended_at)) + ->orderBy('id') + ->chunk(100, function ($bookings) use (&$processed_invoice) { + foreach ($bookings as $booking) { + + Log::channel('regenerateInvoice')->info('Counter ' . $processed_invoice); + dump('Counter ' . $processed_invoice); + $processed_invoice += 1; + + $booking->status = ApprovalStatus::APPROVED; + $booking->save(); + + $firstInvoice = $booking->transactions() + ->whereIn('type', [TransactionType::INVOICE]) + ->withTrashed() + ->orderBy('created_at', 'asc') + ->first(); + + // get the first bill_no + $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(); + $currentInvoice->bill_no = $currentInvoice->bill_no ."-deleted-" . (string)(Carbon::now()->timestamp); + $currentInvoice->save(); + + $booking->transactions()->whereIn('transactions.type', [TransactionType::INVOICE, TransactionType::SUPPLIER_DELIVER])->delete(); + $booking->documents()->whereIn('document_type', [DocumentType::INVOICE, DocumentType::PURCHASE_ORDER, DocumentType::DELIVER_ORDER, DocumentType::SUPPLIER_DELIVER_ORDER])->delete(); + + (App()->make(CreateInvoiceTransactionWithInvoiceNoProcessor::class))->execute($booking, $firstBillNo); + dump('regenerated invoice. Booking Marking - ' . $booking->marking . '. Bill_no - ' . $firstBillNo . '. Old bill_no - ' . $currentInvoice->bill_no); + Log::channel('regenerateInvoice')->info('regenerated invoice. Booking Marking - ' . $booking->marking . '. Bill_no - ' . $firstBillNo . '. Old bill_no - ' . $currentInvoice->bill_no); + } + } + ); +})->name('invoice.fix.byCustomerMarking'); \ No newline at end of file From 9b46981593142d4b0ae140bd85eb691ca4adee9f Mon Sep 17 00:00:00 2001 From: edmondlang Date: Thu, 9 Nov 2023 09:43:09 +0800 Subject: [PATCH 020/434] update regenerate documents link --- routes/web.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/routes/web.php b/routes/web.php index 0efe0616..e2cd97fb 100644 --- a/routes/web.php +++ b/routes/web.php @@ -794,8 +794,8 @@ Route::get('/invoice/{marking}/{started_at}/{ended_at}/fix', function($marking, $bookings = $company->bookings() ->where('status', ApprovalStatus::COMPLETED) - ->whereDate('updated_at', '>=', Carbon::parse($started_at)) - ->whereDate('updated_at', '<=', Carbon::parse($ended_at)) + ->whereDate('created_at', '>=', Carbon::parse($started_at)) + ->whereDate('created_at', '<=', Carbon::parse($ended_at)) ->orderBy('id') ->chunk(100, function ($bookings) use (&$processed_invoice) { foreach ($bookings as $booking) { From fc2bdb4ff0afc230c2814de98021ce19483c6ec8 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Thu, 9 Nov 2023 10:07:13 +0800 Subject: [PATCH 021/434] update regenerate invoice --- routes/web.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/routes/web.php b/routes/web.php index e2cd97fb..447d0d72 100644 --- a/routes/web.php +++ b/routes/web.php @@ -821,9 +821,17 @@ Route::get('/invoice/{marking}/{started_at}/{ended_at}/fix', function($marking, // update currentInvoice bill_no to '-deleted-' $currentInvoice = $booking->transactions()->where('type', TransactionType::INVOICE)->first(); - $currentInvoice->bill_no = $currentInvoice->bill_no ."-deleted-" . (string)(Carbon::now()->timestamp); + $currentInvoice->bill_no = $currentInvoice->bill_no ."-deleted-" . Str::random(10); $currentInvoice->save(); + $transactionWithSameBillNo = Transaction::where('bill_no', $firstBillNo)->get(); + if ($transactionWithSameBillNo) { + foreach ($transactionWithSameBillNo as $transaction) { + $transaction->bill_no = $transaction->bill_no . "-deleted-" . Str::random(10); + $transaction->save(); + } + } + $booking->transactions()->whereIn('transactions.type', [TransactionType::INVOICE, TransactionType::SUPPLIER_DELIVER])->delete(); $booking->documents()->whereIn('document_type', [DocumentType::INVOICE, DocumentType::PURCHASE_ORDER, DocumentType::DELIVER_ORDER, DocumentType::SUPPLIER_DELIVER_ORDER])->delete(); From 6fe1ca3e0e08fe62105ef971763a3090d965f1ab Mon Sep 17 00:00:00 2001 From: edmondlang Date: Thu, 9 Nov 2023 10:21:04 +0800 Subject: [PATCH 022/434] update regenerate invoice --- .../RegenerateInvoiceBookingLogic.php | 11 ++++++++++- routes/web.php | 3 ++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/app/Classes/Modules/Bookings/ControllersLogic/RegenerateInvoiceBookingLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/RegenerateInvoiceBookingLogic.php index 6af18568..5d067fd5 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/RegenerateInvoiceBookingLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/RegenerateInvoiceBookingLogic.php @@ -10,13 +10,14 @@ use App\Classes\Modules\Transactions\Services\DeletesTransaction; use App\Classes\Modules\Documents\Services\DeletesDocument; use App\Classes\Modules\Transactions\Processors\CreateInvoiceTransactionProcessor; use App\Classes\Modules\Transactions\Processors\CreateInvoiceTransactionWithInvoiceNoProcessor; - +use Illuminate\Support\Str; use App\Classes\ValueObjects\Constants\DocumentType; use App\Http\Resources\BookingResource; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\TransactionType; +use App\Models\Transaction; use Illuminate\Support\Carbon; class RegenerateInvoiceBookingLogic extends AbstractControllerLogic @@ -121,6 +122,14 @@ class RegenerateInvoiceBookingLogic extends AbstractControllerLogic $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); diff --git a/routes/web.php b/routes/web.php index 447d0d72..ead4b3d2 100644 --- a/routes/web.php +++ b/routes/web.php @@ -802,6 +802,7 @@ Route::get('/invoice/{marking}/{started_at}/{ended_at}/fix', function($marking, Log::channel('regenerateInvoice')->info('Counter ' . $processed_invoice); dump('Counter ' . $processed_invoice); + dump('Marking ' . $booking->marking); $processed_invoice += 1; $booking->status = ApprovalStatus::APPROVED; @@ -824,7 +825,7 @@ Route::get('/invoice/{marking}/{started_at}/{ended_at}/fix', function($marking, $currentInvoice->bill_no = $currentInvoice->bill_no ."-deleted-" . Str::random(10); $currentInvoice->save(); - $transactionWithSameBillNo = Transaction::where('bill_no', $firstBillNo)->get(); + $transactionWithSameBillNo = Transaction::where('bill_no', $firstBillNo)->withTrashed()->get(); if ($transactionWithSameBillNo) { foreach ($transactionWithSameBillNo as $transaction) { $transaction->bill_no = $transaction->bill_no . "-deleted-" . Str::random(10); From d8a4510fc41e51c9480e3ac7ec73b8924c88019c Mon Sep 17 00:00:00 2001 From: Steve Ng Date: Sun, 12 Nov 2023 11:49:26 +0800 Subject: [PATCH 023/434] fix bug in import invoices and unknow tabs for status not in rejected --- .../UpdateBankStatementDetailLogic.php | 2 +- .../ImportStatementInvoiceController.php | 181 ++++++++++-------- .../ImportStatementReceiptsController.php | 65 ++++--- .../ImportedInvoiceMappedComponent.vue | 11 ++ 4 files changed, 152 insertions(+), 107 deletions(-) diff --git a/app/Classes/Modules/Accounting/ControllersLogic/UpdateBankStatementDetailLogic.php b/app/Classes/Modules/Accounting/ControllersLogic/UpdateBankStatementDetailLogic.php index 9f6c28e6..70186ce1 100644 --- a/app/Classes/Modules/Accounting/ControllersLogic/UpdateBankStatementDetailLogic.php +++ b/app/Classes/Modules/Accounting/ControllersLogic/UpdateBankStatementDetailLogic.php @@ -157,7 +157,7 @@ class UpdateBankStatementDetailLogic extends AbstractControllerLogic 'owner_reference' => $owner_reference, ]; - return $bankStatementTransaction->owners()->firstOrCreate($ownerData); + return $bankStatementTransaction->owners()->where('status','<>',ApprovalStatus::REJECTED)->firstOrCreate($ownerData); } private function editAccountMapped(StatementTransactionOwner $owner){ diff --git a/app/Http/Controllers/Imports/ImportStatementInvoiceController.php b/app/Http/Controllers/Imports/ImportStatementInvoiceController.php index 8d2b920b..56eecc7d 100644 --- a/app/Http/Controllers/Imports/ImportStatementInvoiceController.php +++ b/app/Http/Controllers/Imports/ImportStatementInvoiceController.php @@ -34,93 +34,111 @@ class ImportStatementInvoiceController $this->responseMessage = 'You have successfully imported invoice mapping'; } - /** - * @param Request $request - * @return array - * @throws \App\Classes\Exceptions\MalformedRequestException - */ - public function import(Request $request) : JsonResponse - { - ini_set('memory_limit', '-1'); - $importDate = date('Y-m-d H:i:s'); - $object = new DocumentObject('', $request->input('files'), '', ApprovalStatus::APPROVED, 'imports'); - $file = json_decode($object->getFiles()[0])->file_info->original->file; - - $import = new GenericImport(); - Excel::import($import, $file); - $excelRows = $import->rows; - $excelRows = $excelRows->toArray(); - - $data = []; - foreach ($excelRows as $row) { - $row['mapped_result_reference'] = null; - $row['mapped_status'] = 'failed'; - $row['date'] = date('Y-m-d', strtotime($row['date'])); - - // Shipping Info - // TOPUP -> map with transaction.bill_no - if (str_starts_with($row['shipping_info'], 'TOPUP')) { - // find in exchange first, if cannont then find in izyim - foreach (['exchange','izyim'] as $system) { - $returnReference = $this->mappingTopUp($row, $system); - if ($returnReference) { - $row['mapped_result_reference'] = $returnReference; - $row['mapped_status'] = 'success'; - } - } - } else { - $returnReference = $this->mappingExchange($row); + public function mapping($row) { + // Shipping Info + // TOPUP -> map with transaction.bill_no + if (str_starts_with($row['shipping_info'], 'TOPUP')) { + // find in exchange first, if cannont then find in izyim + foreach (['exchange','izyim'] as $system) { + $returnReference = $this->mappingTopUp($row, $system); if ($returnReference) { $row['mapped_result_reference'] = $returnReference; $row['mapped_status'] = 'success'; + return $row; } } - - TransactionMappingLog::create([ - 'imported_date'=>$importDate, - 'data'=>$row, - ]); - array_push($data, $row); - - - // if 5 digits -> exchange booking reference - // find transation - // find statement_transaction_owners, and fill up the details - - // if <5 digits, find the transaction id (order number in izyim), find the payment in izyim - // find transation - // find statement_transaction_owners, and fill up the details - - // dd([ - // 'type' => $statementTransactionOwnerType, - // 'system' => $system, - // // 'owner_type' => Transaction::class, - // // todo-new: make sure owner_type is a class - // 'owner_type' => $owner_type, - // 'owner_id' => $owner_id, - // 'owner_reference' => $owner_reference - // ]); - - // $bankStatementTransaction->owners()->firstOrCreate([ - // 'type' => $statementTransactionOwnerType, - // 'system' => $system, - // // 'owner_type' => Transaction::class, - // // todo-new: make sure owner_type is a class - // 'owner_type' => $owner_type, - // 'owner_id' => $owner_id, - // 'owner_reference' => $owner_reference - // ]); - - + } + + $returnReference = $this->mappingExchange($row); + if ($returnReference) { + $row['mapped_result_reference'] = $returnReference; + $row['mapped_status'] = 'success'; + return $row; } - return $this->response(['data'=>$data,'importedDate'=>$importDate]); + // if still unable to map, will try to check the shipping_info without TOPUP + foreach (['exchange','izyim'] as $system) { + $returnReference = $this->mappingTopUp($row, $system); + if ($returnReference) { + $row['mapped_result_reference'] = $returnReference; + $row['mapped_status'] = 'success'; + } + } + + return $row; } - public function response(?array $data = []) : JsonResponse { - return (new ApiResponseObject($this->responseTitle, - $this->responseMessage, - HttpStatus::OK_WITH_MESSAGE, $data))->handler(); + /** + * @param Request $request + * @return array + */ + public function import(Request $request) : JsonResponse + { + try { + ini_set('memory_limit', '-1'); + $importDate = date('Y-m-d H:i:s'); + $object = new DocumentObject('', $request->input('files'), '', ApprovalStatus::APPROVED, 'imports'); + $file = json_decode($object->getFiles()[0])->file_info->original->file; + + $import = new GenericImport(); + Excel::import($import, $file); + $excelRows = $import->rows; + $excelRows = $excelRows->toArray(); + + $data = []; + foreach ($excelRows as $row) { + $row['mapped_result_reference'] = null; + $row['mapped_status'] = 'failed'; + $row['date'] = in_array(gettype($row['date']), ['integer', 'double']) ? $this->changeExcelDate($row['date']) : date('Y-m-d', strtotime($row['date'])); + + $row = $this->mapping($row); + + TransactionMappingLog::create([ + 'imported_date'=>$importDate, + 'data'=>$row, + ]); + array_push($data, $row); + + + // if 5 digits -> exchange booking reference + // find transation + // find statement_transaction_owners, and fill up the details + + // if <5 digits, find the transaction id (order number in izyim), find the payment in izyim + // find transation + // find statement_transaction_owners, and fill up the details + + // dd([ + // 'type' => $statementTransactionOwnerType, + // 'system' => $system, + // // 'owner_type' => Transaction::class, + // // todo-new: make sure owner_type is a class + // 'owner_type' => $owner_type, + // 'owner_id' => $owner_id, + // 'owner_reference' => $owner_reference + // ]); + + // $bankStatementTransaction->owners()->firstOrCreate([ + // 'type' => $statementTransactionOwnerType, + // 'system' => $system, + // // 'owner_type' => Transaction::class, + // // todo-new: make sure owner_type is a class + // 'owner_type' => $owner_type, + // 'owner_id' => $owner_id, + // 'owner_reference' => $owner_reference + // ]); + + + } + + return $this->response($this->responseTitle, $this->responseMessage, HttpStatus::OK_WITH_MESSAGE, ['data'=>$data,'importedDate'=>$importDate]); + } catch (\Exception $exception){ + return $this->response('import invoice failed',$exception->getMessage(), ($exception->getCode()? $exception->getCode() : HttpStatus::SERVER_ERROR)); + } + } + + public function response(String $responseTitle, String $responseMessage, int $httpStatus, ?array $data = []) : JsonResponse { + return (new ApiResponseObject($responseTitle, $responseMessage, $httpStatus, $data))->handler(); } private function mappingTopUp(Array $row, String $system) { @@ -162,4 +180,11 @@ class ImportStatementInvoiceController } return false; } + + public function changeExcelDate($date) + { + $unixTime = (($date - 25569) * 86400); + $date = new DateTime("@$unixTime"); + return $date->format('Y-m-d'); // Change the format to 'Y-m-d' + } } diff --git a/app/Http/Controllers/Imports/ImportStatementReceiptsController.php b/app/Http/Controllers/Imports/ImportStatementReceiptsController.php index 4006e130..2cafeac0 100644 --- a/app/Http/Controllers/Imports/ImportStatementReceiptsController.php +++ b/app/Http/Controllers/Imports/ImportStatementReceiptsController.php @@ -40,41 +40,43 @@ class ImportStatementReceiptsController */ public function import(Request $request) { - $importDate = date('Y-m-d H:i:s'); - $object = new DocumentObject('', $request->input('files'), '', ApprovalStatus::APPROVED, 'imports'); - $file = json_decode($object->getFiles()[0])->file_info->original->file; + try { + $importDate = date('Y-m-d H:i:s'); + $object = new DocumentObject('', $request->input('files'), '', ApprovalStatus::APPROVED, 'imports'); + $file = json_decode($object->getFiles()[0])->file_info->original->file; - $import = new GenericImport(); - Excel::import($import, $file); - $excelRows = $import->rows; - $excelRows = $excelRows->toArray(); + $import = new GenericImport(); + Excel::import($import, $file); + $excelRows = $import->rows; + $excelRows = $excelRows->toArray(); - $data = []; - foreach ($excelRows as $row) { - $row['mapped_result_reference'] = null; - $row['mapped_status'] = 'failed'; - $row['date'] = date('Y-m-d', strtotime($row['doc_date'])); + $data = []; + foreach ($excelRows as $row) { + $row['mapped_result_reference'] = null; + $row['mapped_status'] = 'failed'; + $row['date'] = in_array(gettype($row['doc_date']), ['integer', 'double']) ? $this->changeExcelDate($row['doc_date']) : date('Y-m-d', strtotime($row['doc_date'])); - $returnReference = $this->mappingExchange($row); - if ($returnReference) { - $row['mapped_result_reference'] = $returnReference; - $row['mapped_status'] = 'success'; - } + $returnReference = $this->mappingExchange($row); + if ($returnReference) { + $row['mapped_result_reference'] = $returnReference; + $row['mapped_status'] = 'success'; + } - TransactionMappingLog::create([ - 'imported_date'=>$importDate, - 'data'=>$row, - ]); - array_push($data, $row); + TransactionMappingLog::create([ + 'imported_date'=>$importDate, + 'data'=>$row, + ]); + array_push($data, $row); + } + + return $this->response($this->responseTitle, $this->responseMessage, HttpStatus::OK_WITH_MESSAGE, ['data'=>$data,'importedDate'=>$importDate]); + } catch (\Exception $exception){ + return $this->response('import invoice failed',$exception->getMessage(), ($exception->getCode()? $exception->getCode() : HttpStatus::SERVER_ERROR)); } - - return $this->response(['data'=>$data,'importedDate'=>$importDate]); } - public function response(?array $data = []) : JsonResponse { - return (new ApiResponseObject($this->responseTitle, - $this->responseMessage, - HttpStatus::OK_WITH_MESSAGE, $data))->handler(); + public function response(String $responseTitle, String $responseMessage, int $httpStatus, ?array $data = []) : JsonResponse { + return (new ApiResponseObject($responseTitle, $responseMessage, $httpStatus, $data))->handler(); } private function mappingExchange(Array $row) { @@ -104,4 +106,11 @@ class ImportStatementReceiptsController } return false; } + + public function changeExcelDate($date) + { + $unixTime = (($date - 25569) * 86400); + $date = new DateTime("@$unixTime"); + return $date->format('Y-m-d'); // Change the format to 'Y-m-d' + } } diff --git a/resources/assets/vue/components/accounting/sections/ImportedInvoiceMappedComponent.vue b/resources/assets/vue/components/accounting/sections/ImportedInvoiceMappedComponent.vue index 3e52b70b..9fd29e45 100644 --- a/resources/assets/vue/components/accounting/sections/ImportedInvoiceMappedComponent.vue +++ b/resources/assets/vue/components/accounting/sections/ImportedInvoiceMappedComponent.vue @@ -8,6 +8,11 @@

{{ componentTitle }}

+
+
+ {{error}} +
+
- +
- +
Apply a voucher
@@ -262,11 +262,11 @@ {{ voucherCodeFailedReason }} Voucher applied
- +
From 1c29e45744b497f6cfb781db9232611cc4f9924e Mon Sep 17 00:00:00 2001 From: Steve Ng Date: Sun, 3 Dec 2023 18:58:55 +0800 Subject: [PATCH 026/434] add payment received date in import invoice result and fix structure export receipts to autocount --- .../ExportsImportedInvoiceMappeds.php | 4 +- .../Services/ExportsReceiptTransactions.php | 127 +++++++++++++----- .../ImportStatementInvoiceController.php | 14 +- .../ImportedInvoiceMappedComponent.vue | 3 +- 4 files changed, 112 insertions(+), 36 deletions(-) diff --git a/app/Classes/Modules/Exports/Services/ExportsImportedInvoiceMappeds.php b/app/Classes/Modules/Exports/Services/ExportsImportedInvoiceMappeds.php index 71363b52..e629675f 100644 --- a/app/Classes/Modules/Exports/Services/ExportsImportedInvoiceMappeds.php +++ b/app/Classes/Modules/Exports/Services/ExportsImportedInvoiceMappeds.php @@ -39,7 +39,8 @@ class ExportsImportedInvoiceMappeds implements FromQuery, WithHeadings, WithHead 'Net Total', 'Cancelled', 'Mapped Status', - 'Mapped Reference No' + 'Mapped Reference No', + 'MapPayment Received Date' ]; } @@ -72,6 +73,7 @@ class ExportsImportedInvoiceMappeds implements FromQuery, WithHeadings, WithHead Arr::get($data,'cancelled'), Arr::get($data,'mapped_status'), Arr::get($data,'mapped_result_reference'), + Arr::get($data,'payment_received_date'), ]; } diff --git a/app/Classes/Modules/Exports/Services/ExportsReceiptTransactions.php b/app/Classes/Modules/Exports/Services/ExportsReceiptTransactions.php index 07c5d3c1..bde46225 100644 --- a/app/Classes/Modules/Exports/Services/ExportsReceiptTransactions.php +++ b/app/Classes/Modules/Exports/Services/ExportsReceiptTransactions.php @@ -15,8 +15,11 @@ use Illuminate\Support\Facades\Log; use App\Classes\General\Eloquent\ApplyFiltersToQuery; use App\Models\StatementTransaction; use App\Models\Company; +use Maatwebsite\Excel\Concerns\WithEvents; +use Maatwebsite\Excel\Concerns\WithCustomStartCell; +use Maatwebsite\Excel\Events\AfterSheet; -class ExportsReceiptTransactions implements FromQuery, WithHeadings, WithHeadingRow, WithMapping, ShouldAutoSize +class ExportsReceiptTransactions implements FromQuery, WithHeadings, WithHeadingRow, WithMapping, ShouldAutoSize, WithEvents, WithCustomStartCell { use Exportable; @@ -28,37 +31,101 @@ class ExportsReceiptTransactions implements FromQuery, WithHeadings, WithHeading $this->request = $request; } + public function startCell(): string + { + return 'A2'; + } + + public function registerEvents(): array { + + return [ + AfterSheet::class => function(AfterSheet $event) { + $sheet = $event->sheet; + + $sheet->mergeCells('A1:A1'); + $sheet->setCellValue('A1', '"'); + + $sheet->mergeCells('M1:Y1'); + $sheet->setCellValue('M1', "Payment Detail Column"); + + $sheet->mergeCells('Z1:AB1'); + $sheet->setCellValue('Z1', "Knock Off Detail"); + + $styleArray = [ + 'alignment' => [ + 'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER, + ], + ]; + + $cellRange = 'A1:AB1'; + $event->sheet->getDelegate()->getStyle($cellRange)->applyFromArray($styleArray); + }, + ]; + } + public function headings(): array { $header = [ - 'DocNo', - 'DocDate', - 'DebtorCode', - 'Description', - 'DocNo2', - 'ProjNo', - 'DeptNo', - 'CurrencyCode', - 'ToHomeRate', - 'ToDebtorRate', - 'Note', - 'PaymentMethod', - 'ChequeNo', - 'PaymentAmt', - 'BankCharge', - 'ToBankRate', - 'BankChargeTaxType', - 'BankChargeTaxRefNo', - 'BankChargeProjNo', - 'BankChargeDeptNo', - 'PaymentBy', - 'FloatDay', - 'IsRCHQ', - 'RCHQDate', - 'KnockOffDocType', - 'KnockOffDocNo', - 'KnockOffAmt', - '', + [ + ' ', + '(20 chars)', + '(Date: dd/MM/yyyy)', + '(12 chars)', + '(40 chars)', + '(25 chars)', + '(10 chars)', + '(10 chars)', + '(5 chars)', + '(Number, use System Currency Rate Decimal)', + '(Number, use System Currency Rate Decimal)', + '(Rich Text)', + '(20 chars)', + '(20 chars)', + '(Number, use System Currency Decimal)', + '(Number, use System Currency Decimal)', + '(Number, use System Currency Rate Decimal)', + '(14 chars)', + '(30 chars)', + '(10 chars)', + '(10 chars)', + '(20 chars)', + '(Integer)', + '(Boolean. Indicate T for stock control or F for non stock control)', + '(Returned Cheque Date: dd/MM/yyyy)', + '(2 chars, RI for Invoice, RD for D/N)', + '', + '(Number, use System Currency Decimal)', + ], + [ + 'DocNo', + 'DocDate', + 'DebtorCode', + 'Description', + 'DocNo2', + 'ProjNo', + 'DeptNo', + 'CurrencyCode', + 'ToHomeRate', + 'ToDebtorRate', + 'Note', + 'PaymentMethod', + 'ChequeNo', + 'PaymentAmt', + 'BankCharge', + 'ToBankRate', + 'BankChargeTaxType', + 'BankChargeTaxRefNo', + 'BankChargeProjNo', + 'BankChargeDeptNo', + 'PaymentBy', + 'FloatDay', + 'IsRCHQ', + 'RCHQDate', + 'KnockOffDocType', + 'KnockOffDocNo', + 'KnockOffAmt', + '', + ] ]; return $header; } @@ -102,7 +169,7 @@ class ExportsReceiptTransactions implements FromQuery, WithHeadings, WithHeading '<>', Carbon::parse($transaction->posting_date)->format('d/m/Y'), ($company ? $company->debtor : null), - $transaction->transaction_description, + 'Payment for '.$transaction->transaction_description, '', '', '', diff --git a/app/Http/Controllers/Imports/ImportStatementInvoiceController.php b/app/Http/Controllers/Imports/ImportStatementInvoiceController.php index b6cfd567..da42d25f 100644 --- a/app/Http/Controllers/Imports/ImportStatementInvoiceController.php +++ b/app/Http/Controllers/Imports/ImportStatementInvoiceController.php @@ -42,16 +42,20 @@ class ImportStatementInvoiceController foreach (['exchange','izyim'] as $system) { $returnReference = $this->mappingTopUp($row, $system); if ($returnReference) { + // $row['mapped_result_reference'] = $data['owner_reference']; + // $row['payment_received_date'] = date('Y-m-d', strtotime($data['created_at'])); $row['mapped_result_reference'] = $returnReference; + $row['payment_received_date'] = ''; $row['mapped_status'] = 'success'; return $row; } } } - $returnReference = $this->mappingExchange($row); + [$returnReference, $transactionDate] = $this->mappingExchange($row); if ($returnReference) { $row['mapped_result_reference'] = $returnReference; + $row['payment_received_date'] = date('d-m-Y', strtotime($transactionDate)); $row['mapped_status'] = 'success'; return $row; } @@ -88,6 +92,7 @@ class ImportStatementInvoiceController $data = []; foreach ($excelRows as $row) { $row['mapped_result_reference'] = null; + $row['payment_received_date'] = null; $row['mapped_status'] = 'failed'; $row['date'] = in_array(gettype($row['date']), ['integer', 'double']) ? $this->changeExcelDate($row['date']) : date('Y-m-d', strtotime($row['date'])); @@ -144,6 +149,7 @@ class ImportStatementInvoiceController private function mappingTopUp(Array $row, String $system) { try { if ($data = (App()->make(ChecksBillNumber::class))->execute($row['shipping_info'], $system)) { + // if ($system == 'izyim' && isset($data['owner_reference'])) return $data; if ($system == 'izyim' && isset($data['owner_reference'])) return $data['owner_reference']; if ($system == 'exchange') return $this->updateTransactionOwnerReference($data, $row['doc_no']); @@ -168,7 +174,7 @@ class ImportStatementInvoiceController if ($transaction && $transaction->count() > 0) { return $this->updateTransactionOwnerReference($transaction, $row['doc_no']); } - return false; + return [false, false]; } public function updateTransactionOwnerReference($transaction, String $docNo) { @@ -178,9 +184,9 @@ class ImportStatementInvoiceController 'invoice_reference'=>$docNo, 'status'=>ApprovalStatus::COMPLETED ]); - return $transactionOwner->owner_reference; + return [$transactionOwner->owner_reference, $transaction->created_at]; } - return false; + return [false, false]; } public function changeExcelDate($date) diff --git a/resources/assets/vue/components/accounting/sections/ImportedInvoiceMappedComponent.vue b/resources/assets/vue/components/accounting/sections/ImportedInvoiceMappedComponent.vue index 9fd29e45..f10f9181 100644 --- a/resources/assets/vue/components/accounting/sections/ImportedInvoiceMappedComponent.vue +++ b/resources/assets/vue/components/accounting/sections/ImportedInvoiceMappedComponent.vue @@ -39,6 +39,7 @@ {{item.cancelled}} {{item.mapped_status}} {{item.mapped_result_reference}} + {{item.payment_received_date}} @@ -101,7 +102,7 @@ }, appendComponentTableHeader() { if (this.section == 'importInvoiceMapping') { - this.tableHeaders = ['No','Doc No','Date','Debtor Code','Debtor Name','Shipping Info','Net Total','Cancelled','Mapped Status','Mapped Reference No']; + this.tableHeaders = ['No','Doc No','Date','Debtor Code','Debtor Name','Shipping Info','Net Total','Cancelled','Mapped Status','Mapped Reference No','Payment Received Date']; } else { this.tableHeaders = ['No','OR No','Date','Creditor Code','Creditor Name','Shipping Info','Net Total','Cancelled','Mapped Status','Mapped Reference No']; } From 52c2dade88e485677bf015b4a3d0cc3d60ea5937 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Sun, 3 Dec 2023 23:13:52 +0800 Subject: [PATCH 027/434] Update UI based on kexin feedback --- .../elements/AvailableVouchersComponent.vue | 19 +++++++++++-------- .../BookingPaymentQuotationComponent.vue | 14 +++++++------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/resources/assets/vue/components/bookings/elements/AvailableVouchersComponent.vue b/resources/assets/vue/components/bookings/elements/AvailableVouchersComponent.vue index 45722aaf..7c3d5494 100644 --- a/resources/assets/vue/components/bookings/elements/AvailableVouchersComponent.vue +++ b/resources/assets/vue/components/bookings/elements/AvailableVouchersComponent.vue @@ -3,18 +3,21 @@
-
-
-

{{ item.voucher.code }}

+
List of Vouchers, click to select
+
+ + {{ item.voucher.code }} +
+
+ Valid till {{ item.voucher.end_date }} -
-
+ + No expiry date -
+
diff --git a/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue b/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue index 50c6c701..50a421b5 100644 --- a/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue +++ b/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue @@ -244,11 +244,11 @@
-
+
@@ -256,17 +256,17 @@
+
+
+ +
+
Apply a voucher
{{ voucherCodeFailedReason }} Voucher applied
-
-
- -
-
From 19d08242d52715ade37228e3fc6dc3fa88af32f8 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Sun, 3 Dec 2023 23:17:09 +0800 Subject: [PATCH 028/434] Update UI based on kexin feedback --- .../forms/BookingPaymentQuotationComponent.vue | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue b/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue index 50a421b5..e0e2ae8d 100644 --- a/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue +++ b/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue @@ -256,17 +256,17 @@
-
-
- -
-
Apply a voucher
{{ voucherCodeFailedReason }} Voucher applied
+
+
+ +
+
From 96c00ea66b68aace86afe6272cc7ee8594739028 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Sun, 3 Dec 2023 23:19:31 +0800 Subject: [PATCH 029/434] Update UI based on kexin feedback --- .../bookings/forms/BookingPaymentQuotationComponent.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue b/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue index e0e2ae8d..73f7a006 100644 --- a/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue +++ b/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue @@ -257,7 +257,7 @@
Apply a voucher -
+
{{ voucherCodeFailedReason }} Voucher applied From 150f6a69d6dc77dcf032723aa49fec3529df3759 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Sun, 3 Dec 2023 23:34:36 +0800 Subject: [PATCH 030/434] Update UI based on kexin feedback --- .../bookings/elements/AvailableVouchersComponent.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/assets/vue/components/bookings/elements/AvailableVouchersComponent.vue b/resources/assets/vue/components/bookings/elements/AvailableVouchersComponent.vue index 7c3d5494..4ac885ff 100644 --- a/resources/assets/vue/components/bookings/elements/AvailableVouchersComponent.vue +++ b/resources/assets/vue/components/bookings/elements/AvailableVouchersComponent.vue @@ -1,9 +1,9 @@ \ No newline at end of file + diff --git a/resources/assets/vue/components/general/elements/SearchComponent.vue b/resources/assets/vue/components/general/elements/SearchComponent.vue index 36bddce1..eca19095 100644 --- a/resources/assets/vue/components/general/elements/SearchComponent.vue +++ b/resources/assets/vue/components/general/elements/SearchComponent.vue @@ -5,7 +5,7 @@
- +
@@ -78,4 +78,4 @@ } } } - \ No newline at end of file + diff --git a/resources/assets/vue/components/general/elements/bearComponent.vue b/resources/assets/vue/components/general/elements/bearComponent.vue index 4f92caa7..d72be2e8 100644 --- a/resources/assets/vue/components/general/elements/bearComponent.vue +++ b/resources/assets/vue/components/general/elements/bearComponent.vue @@ -1,7 +1,7 @@ diff --git a/resources/views/pages/billings_experiment.blade.php b/resources/views/pages/billings_experiment.blade.php new file mode 100644 index 00000000..d1caee2d --- /dev/null +++ b/resources/views/pages/billings_experiment.blade.php @@ -0,0 +1,9 @@ +@extends('layouts.base_portal') +@section('inner_content') +
+
+ + +
+
+@endsection diff --git a/routes/job.php b/routes/job.php index f32d142e..028e9468 100644 --- a/routes/job.php +++ b/routes/job.php @@ -4,4 +4,5 @@ use Illuminate\Support\Facades\Route; Route::group(['prefix' => 'job', 'as' => 'job.', 'namespace' => 'Jobs'], function () { Route::get('/fetch/{job_id}', 'FetchJobResultController@fetch')->name('fetch'); + Route::get('/fetch/{job_id}/{is_last}', 'FetchJobResultController@fetch')->name('fetch.last.attempt'); }); diff --git a/routes/web.php b/routes/web.php index ead4b3d2..4e9afd11 100644 --- a/routes/web.php +++ b/routes/web.php @@ -92,6 +92,12 @@ Route::get('/billings', function () { return view('pages.billings'); })->name('billings'); +/* Vue Polling Experiment - Starts */ +Route::get('/billings-experiment', function () { + return view('pages.billings_experiment'); +})->name('billings.experiment'); +/* Vue Polling Experiment - Ends */ + Route::get('/currency_orders', function () { return view('pages.currency_orders'); })->name('currency_orders'); @@ -813,13 +819,13 @@ Route::get('/invoice/{marking}/{started_at}/{ended_at}/fix', function($marking, ->withTrashed() ->orderBy('created_at', 'asc') ->first(); - + // get the first bill_no $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(); $currentInvoice->bill_no = $currentInvoice->bill_no ."-deleted-" . Str::random(10); @@ -842,4 +848,4 @@ Route::get('/invoice/{marking}/{started_at}/{ended_at}/fix', function($marking, } } ); -})->name('invoice.fix.byCustomerMarking'); \ No newline at end of file +})->name('invoice.fix.byCustomerMarking'); From ea4795e5c861616064c9ceae521aefedd60769c2 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Sun, 11 Feb 2024 09:53:09 +0000 Subject: [PATCH 101/434] Revert "Merge branch 'dillon/51-vue-polling-experimental-2' into 'master'" This reverts merge request !152 --- .../JobResourceNotFoundException.php | 11 - .../Abstracts/AbstractControllerLogic.php | 15 +- .../General/Eloquent/AbstractFetchRecord.php | 14 +- .../General/Eloquent/AbstractGetRecord.php | 26 +-- .../General/Eloquent/AbstractListRecord.php | 14 +- .../General/Eloquent/Filters/JobId.php | 20 -- .../Eloquent/Filters/OrderByIdDesc.php | 20 -- .../Eloquent/Filters/RequestSignature.php | 19 -- .../Eloquent/Filters/ResultNotNull.php | 18 -- app/Classes/General/Helper.php | 24 -- app/Classes/Jobs/ListBookingsJob.php | 52 ----- app/Classes/Jobs/ListDocumentsJob.php | 63 ------ app/Classes/Jobs/ListTransactionsJob.php | 52 ----- .../ControllersLogic/ListBookingJobLogic.php | 75 ------ .../Processors/ListBookingsJobProcessor.php | 46 ---- .../ControllersLogic/ListDocumentJobLogic.php | 75 ------ .../Processors/ListDocumentsJobProcessor.php | 47 ---- .../ControllersLogic/FetchJobResultLogic.php | 51 ----- .../ListGenericJobObject.php | 118 ---------- .../UpdateJobResultObject.php | 60 ----- .../Processors/FetchesJobResultProcessor.php | 47 ---- .../Processors/UpdateJobResultProcessor.php | 64 ------ .../Jobs/Services/CreatesJobResult.php | 26 --- .../Jobs/Services/FetchesJobResult.php | 33 --- .../Modules/Jobs/Services/ListsJobResult.php | 33 --- .../Jobs/Services/UpdatesJobResult.php | 28 --- .../ListTransactionsJobLogic.php | 74 ------ .../ListTransactionsJobProcessor.php | 45 ---- .../Bookings/ListBookingsJobController.php | 22 -- .../Documents/ListDocumentsJobController.php | 19 -- .../Jobs/FetchJobResultController.php | 19 -- .../ListTransactionsJobController.php | 21 -- app/Http/Resources/BookingResource.php | 2 + app/Http/Resources/CompanyResource.php | 1 + app/Http/Resources/DocumentResource.php | 3 + app/Http/Resources/JobResultResource.php | 22 -- app/Http/Resources/ListBookingJobResource.php | 81 ------- .../Resources/ListDocumentJobResource.php | 31 --- .../Resources/ListTransactionJobResource.php | 54 ----- app/Http/Resources/V2/BookingV2Resource.php | 82 ------- app/Http/Resources/V2/CompanyV2Resource.php | 100 -------- app/Models/JobResult.php | 13 -- ..._08_08_124848_create_job_results_table.php | 35 --- ...31_add_new_column_to_job_results_table.php | 36 --- ..._add_new_column_2_to_job_results_table.php | 34 --- .../AdminPaymentsBillingSectionComponent.vue | 136 ----------- ...PaymentsBillingSectionPollingComponent.vue | 136 ----------- .../SupplierPendingOrdersSectionComponent.vue | 10 +- .../general/elements/ListPollingComponent.vue | 213 ------------------ .../vue/general/mixins/aws/requestV2.js | 49 ---- .../assets/vue/general/mixins/tabHandler.js | 24 -- .../assets/vue/vuex/modules/crudRequestV2.js | 51 ----- resources/assets/vue/vuex/store.js | 4 +- resources/views/pages/billings.blade.php | 126 ++++++++++- .../views/pages/billings_experiment.blade.php | 9 - routes/api.php | 4 - routes/currency.php | 2 +- routes/document.php | 3 +- routes/job.php | 8 - routes/web.php | 12 +- 60 files changed, 152 insertions(+), 2380 deletions(-) delete mode 100644 app/Classes/Exceptions/JobResourceNotFoundException.php delete mode 100644 app/Classes/General/Eloquent/Filters/JobId.php delete mode 100644 app/Classes/General/Eloquent/Filters/OrderByIdDesc.php delete mode 100644 app/Classes/General/Eloquent/Filters/RequestSignature.php delete mode 100644 app/Classes/General/Eloquent/Filters/ResultNotNull.php delete mode 100644 app/Classes/Jobs/ListBookingsJob.php delete mode 100644 app/Classes/Jobs/ListDocumentsJob.php delete mode 100644 app/Classes/Jobs/ListTransactionsJob.php delete mode 100644 app/Classes/Modules/Bookings/ControllersLogic/ListBookingJobLogic.php delete mode 100644 app/Classes/Modules/Bookings/Processors/ListBookingsJobProcessor.php delete mode 100644 app/Classes/Modules/Documents/ControllersLogic/ListDocumentJobLogic.php delete mode 100644 app/Classes/Modules/Documents/Processors/ListDocumentsJobProcessor.php delete mode 100644 app/Classes/Modules/Jobs/ControllersLogic/FetchJobResultLogic.php delete mode 100644 app/Classes/Modules/Jobs/DataTransferObjects/ListGenericJobObject.php delete mode 100644 app/Classes/Modules/Jobs/DataTransferObjects/UpdateJobResultObject.php delete mode 100644 app/Classes/Modules/Jobs/Processors/FetchesJobResultProcessor.php delete mode 100644 app/Classes/Modules/Jobs/Processors/UpdateJobResultProcessor.php delete mode 100644 app/Classes/Modules/Jobs/Services/CreatesJobResult.php delete mode 100644 app/Classes/Modules/Jobs/Services/FetchesJobResult.php delete mode 100644 app/Classes/Modules/Jobs/Services/ListsJobResult.php delete mode 100644 app/Classes/Modules/Jobs/Services/UpdatesJobResult.php delete mode 100644 app/Classes/Modules/Transactions/ControllersLogic/ListTransactionsJobLogic.php delete mode 100644 app/Classes/Modules/Transactions/Processors/ListTransactionsJobProcessor.php delete mode 100644 app/Http/Controllers/Bookings/ListBookingsJobController.php delete mode 100644 app/Http/Controllers/Documents/ListDocumentsJobController.php delete mode 100644 app/Http/Controllers/Jobs/FetchJobResultController.php delete mode 100644 app/Http/Controllers/Transactions/ListTransactionsJobController.php delete mode 100644 app/Http/Resources/JobResultResource.php delete mode 100644 app/Http/Resources/ListBookingJobResource.php delete mode 100644 app/Http/Resources/ListDocumentJobResource.php delete mode 100644 app/Http/Resources/ListTransactionJobResource.php delete mode 100644 app/Http/Resources/V2/BookingV2Resource.php delete mode 100644 app/Http/Resources/V2/CompanyV2Resource.php delete mode 100644 app/Models/JobResult.php delete mode 100644 database/migrations/2023_08_08_124848_create_job_results_table.php delete mode 100644 database/migrations/2023_08_29_063531_add_new_column_to_job_results_table.php delete mode 100644 database/migrations/2023_12_11_193200_add_new_column_2_to_job_results_table.php delete mode 100644 resources/assets/vue/components/bookings/sections/AdminPaymentsBillingSectionComponent.vue delete mode 100644 resources/assets/vue/components/bookings/sections/AdminPaymentsBillingSectionPollingComponent.vue delete mode 100644 resources/assets/vue/components/general/elements/ListPollingComponent.vue delete mode 100644 resources/assets/vue/general/mixins/aws/requestV2.js delete mode 100644 resources/assets/vue/general/mixins/tabHandler.js delete mode 100644 resources/assets/vue/vuex/modules/crudRequestV2.js delete mode 100644 resources/views/pages/billings_experiment.blade.php delete mode 100644 routes/job.php diff --git a/app/Classes/Exceptions/JobResourceNotFoundException.php b/app/Classes/Exceptions/JobResourceNotFoundException.php deleted file mode 100644 index a8ef358e..00000000 --- a/app/Classes/Exceptions/JobResourceNotFoundException.php +++ /dev/null @@ -1,11 +0,0 @@ -getMessage(), - $exception->getTrace()[0]['file'], - $exception->getTrace()[0]['line'] - )); - } - else{ - log::error($exception); - } - + log::error($exception); return (new ApiResponseObject($this->getNotificationTitle().' failed', $exception->getMessage(), $exception->getCode() ? $exception->getCode() : HttpStatus::SERVER_ERROR))->handler(); diff --git a/app/Classes/General/Eloquent/AbstractFetchRecord.php b/app/Classes/General/Eloquent/AbstractFetchRecord.php index 503fb369..248deee7 100644 --- a/app/Classes/General/Eloquent/AbstractFetchRecord.php +++ b/app/Classes/General/Eloquent/AbstractFetchRecord.php @@ -4,11 +4,9 @@ namespace App\Classes\General\Eloquent; use App\Classes\Exceptions\ResourceNotFoundException; -use App\Classes\Exceptions\JobResourceNotFoundException; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Psy\Exception\ErrorException; -use Illuminate\Support\Facades\Log; abstract class AbstractFetchRecord extends AbstractGetRecord { @@ -29,18 +27,12 @@ abstract class AbstractFetchRecord extends AbstractGetRecord * @return Model * @throws ResourceNotFoundException */ - public function getResults(Builder $query, array $param = []): Model { + public function getResults(Builder $query): Model { if(!$query->exists()){ - $table = $query->getModel()->getTable(); - if($table ==='job_results'){ - throw new JobResourceNotFoundException('Unable to find any job based on the criteria provided'); - } - else{ - throw new ResourceNotFoundException('Unable to find any record based on the criteria provided'); - } + throw new ResourceNotFoundException('Unable to find any record based on the criteria provided'); } return $query->first(); } -} +} \ No newline at end of file diff --git a/app/Classes/General/Eloquent/AbstractGetRecord.php b/app/Classes/General/Eloquent/AbstractGetRecord.php index 1a7eac3e..f927d818 100644 --- a/app/Classes/General/Eloquent/AbstractGetRecord.php +++ b/app/Classes/General/Eloquent/AbstractGetRecord.php @@ -30,25 +30,11 @@ abstract class AbstractGetRecord return $this->filters->only(self::DECORATION_FILTERS); } - // /** - // * @param null|string $json - // * @return array - // */ - // public function deserializeFilters(?string $json): array { - // return $json !== null ? collect(json_decode($json))->toArray() : []; - // } - /** - * @param null|string $param + * @param null|string $json * @return array */ - public function deserializeFilters($param): array { - if(gettype($param) == "array"){ - $json = implode(',', $param); - } - else{ - $json = $param; - } + public function deserializeFilters(?string $json): array { return $json !== null ? collect(json_decode($json))->toArray() : []; } @@ -64,9 +50,9 @@ abstract class AbstractGetRecord * @param array $filters * @return mixed */ - public function handler(array $filters, array $params = []){ + public function handler(array $filters){ $this->filters = collect($filters); - return $this->getResults($this->applyFiltersToQuery(), $params); + return $this->getResults($this->applyFiltersToQuery()); } @@ -79,6 +65,6 @@ abstract class AbstractGetRecord * @param Builder $query * @return mixed */ - abstract function getResults(Builder $query, array $params = []); + abstract function getResults(Builder $query); -} +} \ No newline at end of file diff --git a/app/Classes/General/Eloquent/AbstractListRecord.php b/app/Classes/General/Eloquent/AbstractListRecord.php index f898f108..7b7d0df9 100644 --- a/app/Classes/General/Eloquent/AbstractListRecord.php +++ b/app/Classes/General/Eloquent/AbstractListRecord.php @@ -17,11 +17,11 @@ abstract class AbstractListRecord extends AbstractGetRecord * @return mixed * @throws MalformedRequestException */ - public function execute(array $filters = [], array $param = []){ + public function execute(array $filters = []){ try{ - return $this->handler($filters, $param); + return $this->handler($filters); } catch (QueryException $exception){ log::error($exception); @@ -30,24 +30,18 @@ abstract class AbstractListRecord extends AbstractGetRecord } - /** * @param Builder $query * @return mixed */ - public function getResults(Builder $query, array $param = []) { + public function getResults(Builder $query) { $filters = $this->getDecorationFilters(); if($filters->has('order_by')){ $query = $query->orderBy($filters->get('order_by')->column, $filters->get('order_by')->DESC ? 'DESC': 'ASC'); } - if(!empty($param)){ - return $filters->has('per_page') ? $query->paginate($filters->get('per_page'), ['*'], 'page', $param['page']) : $query->get(); //page data from query parameters e.g ?page=1 - } - else{ - return $filters->has('per_page') ? $query->paginate($filters->get('per_page')) : $query->get(); - } + return $filters->has('per_page') ? $query->paginate($filters->get('per_page')) : $query->get(); } diff --git a/app/Classes/General/Eloquent/Filters/JobId.php b/app/Classes/General/Eloquent/Filters/JobId.php deleted file mode 100644 index 42ac51a4..00000000 --- a/app/Classes/General/Eloquent/Filters/JobId.php +++ /dev/null @@ -1,20 +0,0 @@ -where('job_id', $value); - } - -} diff --git a/app/Classes/General/Eloquent/Filters/OrderByIdDesc.php b/app/Classes/General/Eloquent/Filters/OrderByIdDesc.php deleted file mode 100644 index 547ec9bd..00000000 --- a/app/Classes/General/Eloquent/Filters/OrderByIdDesc.php +++ /dev/null @@ -1,20 +0,0 @@ -orderBy('id', 'desc'); - } - -} diff --git a/app/Classes/General/Eloquent/Filters/RequestSignature.php b/app/Classes/General/Eloquent/Filters/RequestSignature.php deleted file mode 100644 index 67dde0a3..00000000 --- a/app/Classes/General/Eloquent/Filters/RequestSignature.php +++ /dev/null @@ -1,19 +0,0 @@ -where('request_signature', $value); - } - -} diff --git a/app/Classes/General/Eloquent/Filters/ResultNotNull.php b/app/Classes/General/Eloquent/Filters/ResultNotNull.php deleted file mode 100644 index 3f6a0341..00000000 --- a/app/Classes/General/Eloquent/Filters/ResultNotNull.php +++ /dev/null @@ -1,18 +0,0 @@ -whereNotNull('result'); - } -} diff --git a/app/Classes/General/Helper.php b/app/Classes/General/Helper.php index 45c72f53..ac89540b 100644 --- a/app/Classes/General/Helper.php +++ b/app/Classes/General/Helper.php @@ -2,7 +2,6 @@ namespace App\Classes\General; -use Illuminate\Http\Resources\Json\ResourceCollection; use Illuminate\Support\Facades\Log; use Illuminate\Support\Str; @@ -43,27 +42,4 @@ class Helper } } } - - /** - * @param null|string $param - * @return array - */ - static function deserializeFilters($param): array { - if(gettype($param) == "array"){ - $json = implode(',', $param); - } - else{ - $json = $param; - } - return $json !== null ? collect(json_decode($json))->toArray() : []; - } - - /** - * @param ResourceCollection $collection - * @return array - */ - static function collectionResponse(ResourceCollection $collection){ - return json_decode($collection->response()->getContent(), true); - } - } diff --git a/app/Classes/Jobs/ListBookingsJob.php b/app/Classes/Jobs/ListBookingsJob.php deleted file mode 100644 index b021b71d..00000000 --- a/app/Classes/Jobs/ListBookingsJob.php +++ /dev/null @@ -1,52 +0,0 @@ -listGenericJobObject = $listGenericJobObject; - } - - public function handle() - { - $rawPayload = $this->job->payload(); - if(isset($rawPayload['data']['commandName'])){ - $this->listGenericJobObject->setJobCommandName($rawPayload['data']['commandName']); - } - - if(isset($rawPayload['data']['command'])){ - $this->listGenericJobObject->setJobCommand($rawPayload['data']['command']); - } - - $result = (App()->make(ListBookingsJobProcessor::class))->execute($this->listGenericJobObject); - } - - public function getJobId(){ - return $this->job->getJobId(); - } -} diff --git a/app/Classes/Jobs/ListDocumentsJob.php b/app/Classes/Jobs/ListDocumentsJob.php deleted file mode 100644 index 6e93062b..00000000 --- a/app/Classes/Jobs/ListDocumentsJob.php +++ /dev/null @@ -1,63 +0,0 @@ -listGenericJobObject = $listGenericJobObject; - } - - public function handle() - { - $rawPayload = $this->job->payload(); - if(isset($rawPayload['data']['commandName'])){ - $this->listGenericJobObject->setJobCommandName($rawPayload['data']['commandName']); - } - - if(isset($rawPayload['data']['command'])){ - $this->listGenericJobObject->setJobCommand($rawPayload['data']['command']); - } - - $result = (App()->make(ListDocumentsJobProcessor::class))->execute($this->listGenericJobObject); - - //cief todo: Insert into DB: job id, query result, timestamp - // Store the result in the job_results table - - //cief todo: why cannot save data in table like this - // $model = new JobResult(); - // $model->job_id = $this->job->getJobId(); - // $model->result = json_encode($result); - // $model->save(); - - // Log::error(json_encode($model->id)); - } - - public function getJobId(){ - return $this->job->getJobId(); - } -} diff --git a/app/Classes/Jobs/ListTransactionsJob.php b/app/Classes/Jobs/ListTransactionsJob.php deleted file mode 100644 index a2b28656..00000000 --- a/app/Classes/Jobs/ListTransactionsJob.php +++ /dev/null @@ -1,52 +0,0 @@ -listGenericJobObject = $listGenericJobObject; - } - - public function handle() - { - $rawPayload = $this->job->payload(); - if(isset($rawPayload['data']['commandName'])){ - $this->listGenericJobObject->setJobCommandName($rawPayload['data']['commandName']); - } - - if(isset($rawPayload['data']['command'])){ - $this->listGenericJobObject->setJobCommand($rawPayload['data']['command']); - } - - $result = (App()->make(ListTransactionsJobProcessor::class))->execute($this->listGenericJobObject); - } - - public function getJobId(){ - return $this->job->getJobId(); - } -} diff --git a/app/Classes/Modules/Bookings/ControllersLogic/ListBookingJobLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/ListBookingJobLogic.php deleted file mode 100644 index ef3570f7..00000000 --- a/app/Classes/Modules/Bookings/ControllersLogic/ListBookingJobLogic.php +++ /dev/null @@ -1,75 +0,0 @@ - 'List Booking Job', - 'message' => 'You have successfully submit a job to list bookings' - ]; - } - - /** @var CreatesJobResult */ - private $createsJobResult; - - /** - * ListPackingListsJobLogic constructor. - * @param CreatesJobResult $createsJobResult - */ - public function __construct(CreatesJobResult $createsJobResult) - { - $this->createsJobResult = $createsJobResult; - } - - - /** - * @param Request $request - * @return JsonResponse - */ - public function logic(Request $request) : JsonResponse - { - $jobId = uniqid(); - - $user = Auth::user(); - $userInfo = (object) [ - 'type' => $user->type, - ]; - - $userInfoJson = json_encode($userInfo); - $requestSignature = md5($userInfoJson . $request->fullUrl()); - - $listGenericJobObject = new ListGenericJobObject( - $request->fullUrl(), - $request->all(), - $requestSignature, - null, - $jobId, - $userInfo - ); - - ListBookingsJob::dispatch($listGenericJobObject); - - $result = []; - $result['job_id'] = $jobId; - - $this->createsJobResult->execute($listGenericJobObject); - - return $this->response(['data' => $result]); - } - -} diff --git a/app/Classes/Modules/Bookings/Processors/ListBookingsJobProcessor.php b/app/Classes/Modules/Bookings/Processors/ListBookingsJobProcessor.php deleted file mode 100644 index 2a09eb12..00000000 --- a/app/Classes/Modules/Bookings/Processors/ListBookingsJobProcessor.php +++ /dev/null @@ -1,46 +0,0 @@ -listsBookings = $listsBookings; - $this->updateJobResultProcessor = $updateJobResultProcessor; - } - - /** - * @param ListGenericJobObject $listGenericJobObject - * @return void - * @throws \App\Classes\Exceptions\MalformedRequestException - * @throws \App\Classes\Exceptions\JobResourceNotFoundException - */ - public function execute(ListGenericJobObject $listGenericJobObject) { - - $query = $this->listsBookings->execute($this->listsBookings->deserializeFilters($listGenericJobObject->getPayload()['filters']), ['page' => $listGenericJobObject->getPayload()['page']]); - foreach ($query->items() as &$item) { - $item['userInfo'] = $listGenericJobObject->getUserInfo(); - } - $resultCurrent = Helper::collectionResponse(ListBookingJobResource::collection($query)); - $this->updateJobResultProcessor->execute($listGenericJobObject, $resultCurrent); - } -} diff --git a/app/Classes/Modules/Documents/ControllersLogic/ListDocumentJobLogic.php b/app/Classes/Modules/Documents/ControllersLogic/ListDocumentJobLogic.php deleted file mode 100644 index 5e895ad8..00000000 --- a/app/Classes/Modules/Documents/ControllersLogic/ListDocumentJobLogic.php +++ /dev/null @@ -1,75 +0,0 @@ - 'List Document Job', - 'message' => 'You have successfully submit a job to list documents' - ]; - } - - /** @var CreatesJobResult */ - private $createsJobResult; - - /** - * ListDocumentJobLogic constructor. - * @param CreatesJobResult $createsJobResult - */ - public function __construct(CreatesJobResult $createsJobResult) - { - $this->createsJobResult = $createsJobResult; - } - - - /** - * @param Request $request - * @return JsonResponse - */ - public function logic(Request $request) : JsonResponse - { - $jobId = uniqid(); - - $user = Auth::user(); - $userInfo = (object) [ - 'email' => $user->email, - 'type' => $user->type, - ]; - - $userInfoJson = json_encode($userInfo); - $requestSignature = md5($userInfoJson . $request->fullUrl()); - - $listGenericJobObject = new ListGenericJobObject( - $request->fullUrl(), - $request->all(), - $requestSignature, - null, - $jobId, - $userInfo - ); - - ListDocumentsJob::dispatch($listGenericJobObject); - - $result = []; - $result['job_id'] = $jobId; - - $this->createsJobResult->execute($listGenericJobObject); - - return $this->response(['data' => $result]); - } -} diff --git a/app/Classes/Modules/Documents/Processors/ListDocumentsJobProcessor.php b/app/Classes/Modules/Documents/Processors/ListDocumentsJobProcessor.php deleted file mode 100644 index 70777f0c..00000000 --- a/app/Classes/Modules/Documents/Processors/ListDocumentsJobProcessor.php +++ /dev/null @@ -1,47 +0,0 @@ -listsDocuments = $listsDocuments; - $this->updateJobResultProcessor = $updateJobResultProcessor; - } - - /** - * @param ListGenericJobObject $listGenericJobObject - * @return void - * @throws \App\Classes\Exceptions\MalformedRequestException - * @throws \App\Classes\Exceptions\JobResourceNotFoundException - */ - public function execute(ListGenericJobObject $listGenericJobObject) { - - $query = $this->listsDocuments->execute($this->listsDocuments->deserializeFilters($listGenericJobObject->getPayload()['filters']), ['page' => $listGenericJobObject->getPayload()['page']]); - foreach ($query->items() as &$item) { - $item['userInfo'] = $listGenericJobObject->getUserInfo(); - } - $resultCurrent = Helper::collectionResponse(ListDocumentJobResource::collection($query)); - $this->updateJobResultProcessor->execute($listGenericJobObject, $resultCurrent); - } -} - diff --git a/app/Classes/Modules/Jobs/ControllersLogic/FetchJobResultLogic.php b/app/Classes/Modules/Jobs/ControllersLogic/FetchJobResultLogic.php deleted file mode 100644 index c4b72cf0..00000000 --- a/app/Classes/Modules/Jobs/ControllersLogic/FetchJobResultLogic.php +++ /dev/null @@ -1,51 +0,0 @@ - 'Retrieved Data', - 'message' => 'You have successfully retrieved data' - ]; - } - - /** @var FetchesJobResultProcessor */ - private $fetchesJobResultProcessor; - - /** - * FetchJobResultLogic constructor. - * @param FetchesJobResultProcessor $fetchesJobResultProcessor - */ - public function __construct(FetchesJobResultProcessor $fetchesJobResultProcessor) - { - $this->fetchesJobResultProcessor = $fetchesJobResultProcessor; - } - - - /** - * @param Request $request - * @return JsonResponse - * @throws \App\Classes\Exceptions\AccessForbiddenException - * @throws \App\Classes\Exceptions\MalformedRequestException - * @throws \App\Classes\Exceptions\RequestValidationException - */ - public function logic(Request $request) : JsonResponse - { - $query = $this->fetchesJobResultProcessor->execute($request); - return $this->resourceResponse(new JobResultResource($query)); - } - -} diff --git a/app/Classes/Modules/Jobs/DataTransferObjects/ListGenericJobObject.php b/app/Classes/Modules/Jobs/DataTransferObjects/ListGenericJobObject.php deleted file mode 100644 index 953d77d7..00000000 --- a/app/Classes/Modules/Jobs/DataTransferObjects/ListGenericJobObject.php +++ /dev/null @@ -1,118 +0,0 @@ -name = $name; - $this->payload = $payload; - $this->jobId = $jobId; - $this->requestSignature = $requestSignature; - $this->resultSignature = $resultSignature; - $this->userInfo = $userInfo; - } - - /** - * @return string - */ - public function getName(): string - { - return $this->name; - } - - /** - * @return array - */ - public function getPayload(): array - { - return $this->payload; - } - - /** - * @return string - */ - public function getJobId(): string - { - return $this->jobId; - } - - /** - * @return string - */ - public function getRequestSignature(): string - { - return $this->requestSignature; - } - - /** - * @return string - */ - public function getResultSignature(): ?string - { - return $this->resultSignature; - } - - /** - * @return object - */ - public function getUserInfo(): object - { - return $this->userInfo; - } - - /** - * @return string - */ - public function getJobCommandName(): string - { - return $this->jobCommandName; - } - - /** - * @return string - */ - public function getJobCommand(): string - { - return $this->jobCommand; - } - - - public function setJobCommandName(string $jobCommandName) - { - $this->jobCommandName = $jobCommandName; - } - - public function setJobCommand(string $jobCommand) - { - $this->jobCommand = $jobCommand; - } - -} diff --git a/app/Classes/Modules/Jobs/DataTransferObjects/UpdateJobResultObject.php b/app/Classes/Modules/Jobs/DataTransferObjects/UpdateJobResultObject.php deleted file mode 100644 index 636c56b0..00000000 --- a/app/Classes/Modules/Jobs/DataTransferObjects/UpdateJobResultObject.php +++ /dev/null @@ -1,60 +0,0 @@ -result = $result; - $this->resultSignature = $resultSignature; - $this->jobCommandName = $jobCommandName; - $this->jobCommand = $jobCommand; - } - - /** - * @return string - */ - public function getResult(): string - { - return $this->result; - } - - /** - * @return array - */ - public function getResultSignature(): string - { - return $this->resultSignature; - } - - /** - * @return string - */ - public function getJobCommandName(): string - { - return $this->jobCommandName; - } - - /** - * @return string - */ - public function getJobCommand(): string - { - return $this->jobCommand; - } -} diff --git a/app/Classes/Modules/Jobs/Processors/FetchesJobResultProcessor.php b/app/Classes/Modules/Jobs/Processors/FetchesJobResultProcessor.php deleted file mode 100644 index 89783fe8..00000000 --- a/app/Classes/Modules/Jobs/Processors/FetchesJobResultProcessor.php +++ /dev/null @@ -1,47 +0,0 @@ -fetchesJobResult = $fetchesJobResult; - } - - - /** - * @param Request $request - * @return Model - * @throws \App\Classes\Exceptions\MalformedRequestException - * @throws \App\Classes\Exceptions\JobResourceNotFoundException - * @throws \App\Classes\Exceptions\ResourceNotFoundException - */ - public function execute(Request $request){ - - $res1 = $this->fetchesJobResult->execute(['job_id' => $request->route('job_id')]); - if($request->route('is_last')){ - $res2 = $this->fetchesJobResult->execute(['request_signature' => $res1->request_signature, 'result_not_null' => true, 'order_by_id_desc' => true]); - return $res2; - } - - if(!$res1->result){ - throw new JobResourceNotFoundException('Unable to find any job based on the criteria provided'); - } - - return $res1; - } -} diff --git a/app/Classes/Modules/Jobs/Processors/UpdateJobResultProcessor.php b/app/Classes/Modules/Jobs/Processors/UpdateJobResultProcessor.php deleted file mode 100644 index 0106417d..00000000 --- a/app/Classes/Modules/Jobs/Processors/UpdateJobResultProcessor.php +++ /dev/null @@ -1,64 +0,0 @@ -fetchesJobResult = $fetchesJobResult; - $this->updatesJobResult = $updatesJobResult; - } - - /** - * @param ListGenericJobObject $listGenericJobObject - * @param array $resultCurrent - * @return void - * @throws \App\Classes\Exceptions\MalformedRequestException - * @throws \App\Classes\Exceptions\JobResourceNotFoundException - */ - public function execute(ListGenericJobObject $listGenericJobObject, $resultCurrent) { - $jobResultCurrent = $this->fetchesJobResult->execute(['job_id' => $listGenericJobObject->getJobId()]); - $resultCurrentJson = json_encode($resultCurrent); - $resultSignatureCurrent = md5($resultCurrentJson); - - try{ - $jobResultExisting = $this->fetchesJobResult->execute(['request_signature' => $jobResultCurrent->request_signature, 'result_not_null' => true, 'order_by_id_desc' => true]); - $resultSignatureExisting = $jobResultExisting->result_signature; - //if($resultSignatureExisting != $resultSignatureCurrent){ - $this->updateJobResult($jobResultCurrent, $resultCurrentJson, $resultSignatureCurrent, $listGenericJobObject->getJobCommandName(), $listGenericJobObject->getJobCommand()); - //} - } catch (JobResourceNotFoundException $exception){ - $this->updateJobResult($jobResultCurrent, $resultCurrentJson, $resultSignatureCurrent, $listGenericJobObject->getJobCommandName(), $listGenericJobObject->getJobCommand()); - } - } - - private function updateJobResult($jobResultCurrent, $resultCurrentJson, $resultSignatureCurrent, $jobCommandName, $jobCommand){ - $updateJobResultObject = new UpdateJobResultObject( - $resultCurrentJson, - $resultSignatureCurrent, - $jobCommandName, - $jobCommand - ); - $create = $this->updatesJobResult->execute($jobResultCurrent, $updateJobResultObject); - } -} diff --git a/app/Classes/Modules/Jobs/Services/CreatesJobResult.php b/app/Classes/Modules/Jobs/Services/CreatesJobResult.php deleted file mode 100644 index e70e0e6a..00000000 --- a/app/Classes/Modules/Jobs/Services/CreatesJobResult.php +++ /dev/null @@ -1,26 +0,0 @@ -job_id = $listGenericJobObject->getJobId(); - $model->request_signature = $listGenericJobObject->getRequestSignature(); - $model->result_signature = $listGenericJobObject->getResultSignature(); - $model->url = $listGenericJobObject->getName(); - - return $this->handler($model); - } -} diff --git a/app/Classes/Modules/Jobs/Services/FetchesJobResult.php b/app/Classes/Modules/Jobs/Services/FetchesJobResult.php deleted file mode 100644 index 1cc99cb6..00000000 --- a/app/Classes/Modules/Jobs/Services/FetchesJobResult.php +++ /dev/null @@ -1,33 +0,0 @@ -repository = $repository; - } - - - /** - * @return Builder - */ - public function getRepository(): Builder - { - return $this->repository->newQuery(); - } -} diff --git a/app/Classes/Modules/Jobs/Services/ListsJobResult.php b/app/Classes/Modules/Jobs/Services/ListsJobResult.php deleted file mode 100644 index 55f3b267..00000000 --- a/app/Classes/Modules/Jobs/Services/ListsJobResult.php +++ /dev/null @@ -1,33 +0,0 @@ -repository = $repository; - } - - - /** - * @return Builder - */ - function getRepository(): Builder - { - return $this->repository->newQuery(); - } -} diff --git a/app/Classes/Modules/Jobs/Services/UpdatesJobResult.php b/app/Classes/Modules/Jobs/Services/UpdatesJobResult.php deleted file mode 100644 index ab3d9385..00000000 --- a/app/Classes/Modules/Jobs/Services/UpdatesJobResult.php +++ /dev/null @@ -1,28 +0,0 @@ -result = $updateJobResultObject->getResult(); - $model->result_signature = $updateJobResultObject->getResultSignature(); - $model->job_command_name = $updateJobResultObject->getJobCommandName(); - $model->job_command = $updateJobResultObject->getJobCommand(); - - return $this->handler($model); - - } -} diff --git a/app/Classes/Modules/Transactions/ControllersLogic/ListTransactionsJobLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/ListTransactionsJobLogic.php deleted file mode 100644 index 654a360f..00000000 --- a/app/Classes/Modules/Transactions/ControllersLogic/ListTransactionsJobLogic.php +++ /dev/null @@ -1,74 +0,0 @@ - 'List Transaction Job', - 'message' => 'You have successfully submit a job to list transactions' - ]; - } - - /** @var CreatesJobResult */ - private $createsJobResult; - - /** - * ListTransactionsJobLogic constructor. - * @param CreatesJobResult $createsJobResult - */ - public function __construct(CreatesJobResult $createsJobResult) - { - $this->createsJobResult = $createsJobResult; - } - - - /** - * @param Request $request - * @return JsonResponse - */ - public function logic(Request $request) : JsonResponse - { - $jobId = uniqid(); - - $user = Auth::user(); - $userInfo = (object) [ - 'type' => $user->type, - ]; - - $userInfoJson = json_encode($userInfo); - $requestSignature = md5($userInfoJson . $request->fullUrl()); - - $listGenericJobObject = new ListGenericJobObject( - $request->fullUrl(), - $request->all(), - $requestSignature, - null, - $jobId, - $userInfo - ); - - ListTransactionsJob::dispatch($listGenericJobObject); - - $result = []; - $result['job_id'] = $jobId; - - $this->createsJobResult->execute($listGenericJobObject); - - return $this->response(['data' => $result]); - } - -} diff --git a/app/Classes/Modules/Transactions/Processors/ListTransactionsJobProcessor.php b/app/Classes/Modules/Transactions/Processors/ListTransactionsJobProcessor.php deleted file mode 100644 index 475d4715..00000000 --- a/app/Classes/Modules/Transactions/Processors/ListTransactionsJobProcessor.php +++ /dev/null @@ -1,45 +0,0 @@ -listsTransactions = $listsTransactions; - $this->updateJobResultProcessor = $updateJobResultProcessor; - } - - /** - * @param ListGenericJobObject $listGenericJobObject - * @return void - * @throws \App\Classes\Exceptions\MalformedRequestException - * @throws \App\Classes\Exceptions\JobResourceNotFoundException - */ - public function execute(ListGenericJobObject $listGenericJobObject) { - - $query = $this->listsTransactions->execute($this->listsTransactions->deserializeFilters($listGenericJobObject->getPayload()['filters']), ['page' => $listGenericJobObject->getPayload()['page']]); - - $resultCurrent = Helper::collectionResponse(ListTransactionJobResource::collection($query)); - $this->updateJobResultProcessor->execute($listGenericJobObject, $resultCurrent); - } -} - diff --git a/app/Http/Controllers/Bookings/ListBookingsJobController.php b/app/Http/Controllers/Bookings/ListBookingsJobController.php deleted file mode 100644 index 9b32fc77..00000000 --- a/app/Http/Controllers/Bookings/ListBookingsJobController.php +++ /dev/null @@ -1,22 +0,0 @@ -execute($request); - } -} diff --git a/app/Http/Controllers/Documents/ListDocumentsJobController.php b/app/Http/Controllers/Documents/ListDocumentsJobController.php deleted file mode 100644 index 8b763085..00000000 --- a/app/Http/Controllers/Documents/ListDocumentsJobController.php +++ /dev/null @@ -1,19 +0,0 @@ -execute($request); - } -} diff --git a/app/Http/Controllers/Jobs/FetchJobResultController.php b/app/Http/Controllers/Jobs/FetchJobResultController.php deleted file mode 100644 index cfef2f5c..00000000 --- a/app/Http/Controllers/Jobs/FetchJobResultController.php +++ /dev/null @@ -1,19 +0,0 @@ -execute($request); - } -} diff --git a/app/Http/Controllers/Transactions/ListTransactionsJobController.php b/app/Http/Controllers/Transactions/ListTransactionsJobController.php deleted file mode 100644 index fb341d5d..00000000 --- a/app/Http/Controllers/Transactions/ListTransactionsJobController.php +++ /dev/null @@ -1,21 +0,0 @@ -execute($request); - } -} diff --git a/app/Http/Resources/BookingResource.php b/app/Http/Resources/BookingResource.php index 70fbc95c..f3a7881d 100644 --- a/app/Http/Resources/BookingResource.php +++ b/app/Http/Resources/BookingResource.php @@ -11,9 +11,11 @@ use App\Classes\ValueObjects\Constants\TransactionType; use App\Classes\ValueObjects\Constants\DocumentType; use Carbon\Carbon; use Illuminate\Http\Resources\Json\JsonResource; +use Illuminate\Support\Facades\Log; class BookingResource extends JsonResource { + /** * Transform the resource into an array. * diff --git a/app/Http/Resources/CompanyResource.php b/app/Http/Resources/CompanyResource.php index eff2bd1b..85ecee16 100644 --- a/app/Http/Resources/CompanyResource.php +++ b/app/Http/Resources/CompanyResource.php @@ -15,6 +15,7 @@ use App\Models\SegmentConstant; use Carbon\Carbon; use Illuminate\Http\Resources\Json\JsonResource; use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\Log; class CompanyResource extends JsonResource { diff --git a/app/Http/Resources/DocumentResource.php b/app/Http/Resources/DocumentResource.php index c0f801bb..59933a67 100644 --- a/app/Http/Resources/DocumentResource.php +++ b/app/Http/Resources/DocumentResource.php @@ -3,7 +3,10 @@ namespace App\Http\Resources; use App\Models\Booking; +use App\Models\Company; +use App\Models\Document; use Carbon\Carbon; +use Illuminate\Database\Eloquent\Model; use Illuminate\Http\Resources\Json\JsonResource; class DocumentResource extends JsonResource diff --git a/app/Http/Resources/JobResultResource.php b/app/Http/Resources/JobResultResource.php deleted file mode 100644 index 51bc1898..00000000 --- a/app/Http/Resources/JobResultResource.php +++ /dev/null @@ -1,22 +0,0 @@ - $this->job_id, - 'result' => $this->result, - ]; - } -} diff --git a/app/Http/Resources/ListBookingJobResource.php b/app/Http/Resources/ListBookingJobResource.php deleted file mode 100644 index 06f8c38d..00000000 --- a/app/Http/Resources/ListBookingJobResource.php +++ /dev/null @@ -1,81 +0,0 @@ -userInfo = $userInfo ?? ($resource->userInfo ?? null); - } - - /** - * Transform the resource into an array. - * - * @param \Illuminate\Http\Request $request - * @return array - * @throws \Illuminate\Contracts\Container\BindingResolutionException - */ - public function toArray($request) - { - return [ - 'id' => $this->id, - 'company' => new CompanyResource($this->company, $this->userInfo), - 'bank' => new BankResource($this->bank), - 'service' => new ServiceTypeResource($this->service), - 'marking' => $this->marking, - 'amount' => $this->fix_amount, - 'floating_amount' => floatval((App()->make(CalculatesBookingFloatingAmount::class))->execute($this->resource, $this->fix_currency_id)), - 'paid_amount' => floatval((App()->make(CalculatesBookingPayableAmount::class))->execute($this->resource, $this->fix_currency_id)) - floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)), - 'outstanding_amount' => floatval((App()->make(CalculatesBookingOutstanding::class))->execute($this->resource)) - floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)), - 'fixed_currency' => new CurrencyResource($this->fixedCurrency), - '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()), - '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()), - ], - 'status' => $this->status, - 'created_at' => Carbon::parse($this->created_at)->format('d-m-Y'), - 'created_at_with_time' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A'), - $this->mergeWhen($this->relationLoaded('transactions'), [ - 'purchase_order' => new TransactionResource($this->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first()), - 'payment_attempts' => TransactionResource::collection( - $this->transactions() - ->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION) - ->whereDate('expires_on', '>=', Carbon::now()) - ->get() - ), - 'expired_payment_attempts' => TransactionResource::collection($this->transactions()->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION)->whereDate('expires_on', '>=', Carbon::now())->where('expires_on', '>', Carbon::now()->toTimeString())->get()), - 'payment_history' => TransactionResource::collection($this->transactions()->where(function($query){ - $query->where(function($query){ - $query->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::COMPLETED, ApprovalStatus::REJECTED]); - })->orWhere(function($query){ - $query->where(function($query){ - $query->where('type', TransactionType::REFUND)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::REJECTED, ApprovalStatus::COMPLETED]); - })->orWhere(function($query){ - $query->where('type', TransactionType::CREDIT_NOTE)->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); - }); - }); - })->latest()->get()) - ]) - ]; - } -} diff --git a/app/Http/Resources/ListDocumentJobResource.php b/app/Http/Resources/ListDocumentJobResource.php deleted file mode 100644 index edf549ef..00000000 --- a/app/Http/Resources/ListDocumentJobResource.php +++ /dev/null @@ -1,31 +0,0 @@ - $this->id, - 'reference' => $this->reference, - 'status' => (int) $this->status, - 'document_type' => $this->document_type, - 'owner' => $this->relationLoaded('owner') ? ($this->owner instanceof Booking ? new BookingV2Resource($this->owner, $this->userInfo) : new CompanyV2Resource($this->owner, $this->userInfo)) : null, - 'files' => FileResource::collection($this->files), - 'created_at' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A') - ]; - } -} diff --git a/app/Http/Resources/ListTransactionJobResource.php b/app/Http/Resources/ListTransactionJobResource.php deleted file mode 100644 index 6c4c0ece..00000000 --- a/app/Http/Resources/ListTransactionJobResource.php +++ /dev/null @@ -1,54 +0,0 @@ -type, [TransactionType::BILL, TransactionType::REFUND])? $this->owner->owner : $this->owner; - $days = $this->created_at->endOfDay()->addWeekdays($booking->service_id === 3 ? 3 : 1); - - return [ - 'id' => $this->id, - 'booking' => new BookingResource($booking), - 'type' => (int) $this->type, - 'bill_no' => $this->bill_no, - 'payment_reference' => $this->payment_reference, - 'payment_method' => (float) $this->payment_method, - 'recipient_bank_account' => new BankResource($booking->bank), - 'issuer_name' => $this->issuerCompany->name, - 'issuer_id' => $this->issuerCompany->id, - 'amount' => (double) $this->amount, - 'original_amount' => (double) $this->original_amount, - 'currency' => new CurrencyResource($this->currency), - 'original_currency' => new CurrencyResource($this->original_currency), - 'service_charge' => (double) $this->service_charge, - 'tax' => (double) $this->tax, - 'currency_rate' => (double) $this->currency_rate, - 'status' => (int) $this->status, - 'details' => TransactionDetailResource::collection($this->transactionDetails), - 'documents' => new DocumentResource($this->documents()->first()), - 'transaction_bill' => new TransactionResource($this->when((int) $this->type === TransactionType::PAYMENT, $this->transactions()->bills()->first())), - 'transaction_refunds' => TransactionResource::collection($this->when((int) $this->type === TransactionType::PAYMENT, $this->transactions()->refunds()->get())), - 'expires_on' => Carbon::parse($this->expires_on)->format('d-m-Y h:i:s A'), - 'updated_at' => Carbon::parse($this->updated_at)->format('d-m-Y h:i:s A'), - 'interval' => [ - 'value' => $days->gt(Carbon::now()) ? '+' : '-', - 'duration' => $days->diff(Carbon::now())->format('%d'), - ], - 'redemption' => new VoucherRedemptionResource($this->voucherRedemption) - ]; - } -} diff --git a/app/Http/Resources/V2/BookingV2Resource.php b/app/Http/Resources/V2/BookingV2Resource.php deleted file mode 100644 index ee17181e..00000000 --- a/app/Http/Resources/V2/BookingV2Resource.php +++ /dev/null @@ -1,82 +0,0 @@ -userInfo = $userInfo ?? ($resource->userInfo ?? null); - } - - /** - * Transform the resource into an array. - * - * @param \Illuminate\Http\Request $request - * @return array - * @throws \Illuminate\Contracts\Container\BindingResolutionException - */ - public function toArray($request) - { - return [ - 'id' => $this->id, - 'company' => new CompanyV2Resource($this->company, $this->userInfo), - 'bank' => new V1\BankResource($this->bank), - 'service' => new V1\ServiceTypeResource($this->service), - 'marking' => $this->marking, - 'amount' => $this->fix_amount, - 'floating_amount' => floatval((App()->make(CalculatesBookingFloatingAmount::class))->execute($this->resource, $this->fix_currency_id)), - 'paid_amount' => floatval((App()->make(CalculatesBookingPayableAmount::class))->execute($this->resource, $this->fix_currency_id)) - floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)), - 'outstanding_amount' => floatval((App()->make(CalculatesBookingOutstanding::class))->execute($this->resource)) - floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)), - 'fixed_currency' => new V1\CurrencyResource($this->fixedCurrency), - 'convertible_currency' => new V1\CurrencyResource($this->convertibleCurrency), - 'conversion_currency' => new V1\CurrencyResource($this->conversionCurrency), - 'documents' => [ - 'purchase_order' => new V1\DocumentResource($this->documents()->where('document_type', DocumentType::PURCHASE_ORDER)->first()), - 'delivery_order' => new V1\DocumentResource($this->documents()->where('document_type', DocumentType::DELIVER_ORDER)->first()), - 'invoice' => new V1\DocumentResource($this->documents()->where('document_type', DocumentType::INVOICE)->first()), - 'supplier_delivery_order' => new V1\DocumentResource($this->documents()->where('document_type', DocumentType::SUPPLIER_DELIVER_ORDER)->first()), - 'proforma_invoice' => new V1\DocumentResource($this->documents()->where('document_type', DocumentType::PROFORMA_INVOICE)->whereNotIn('status', [ApprovalStatus::REJECTED, ApprovalStatus::EXPIRED])->orderByDesc('id')->first()), - 'ecommerce_purchase_order' => new V1\DocumentResource($this->documents()->where('document_type', DocumentType::ECOMMERCE_PURCHASE_ORDER)->first()), - ], - 'status' => $this->status, - 'created_at' => Carbon::parse($this->created_at)->format('d-m-Y'), - 'created_at_with_time' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A'), - $this->mergeWhen($this->relationLoaded('transactions'), [ - 'purchase_order' => new V1\TransactionResource($this->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first()), - 'payment_attempts' => V1\TransactionResource::collection( - $this->transactions() - ->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION) - ->whereDate('expires_on', '>=', Carbon::now()) - ->get() - ), - 'expired_payment_attempts' => V1\TransactionResource::collection($this->transactions()->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION)->whereDate('expires_on', '>=', Carbon::now())->where('expires_on', '>', Carbon::now()->toTimeString())->get()), - 'payment_history' => V1\TransactionResource::collection($this->transactions()->where(function($query){ - $query->where(function($query){ - $query->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::COMPLETED, ApprovalStatus::REJECTED]); - })->orWhere(function($query){ - $query->where(function($query){ - $query->where('type', TransactionType::REFUND)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::REJECTED, ApprovalStatus::COMPLETED]); - })->orWhere(function($query){ - $query->where('type', TransactionType::CREDIT_NOTE)->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); - }); - }); - })->latest()->get()) - ]) - ]; - } -} diff --git a/app/Http/Resources/V2/CompanyV2Resource.php b/app/Http/Resources/V2/CompanyV2Resource.php deleted file mode 100644 index 64fca7c7..00000000 --- a/app/Http/Resources/V2/CompanyV2Resource.php +++ /dev/null @@ -1,100 +0,0 @@ -userInfo = $userInfo; - } - - /** - * Transform the resource into an array. - * - * @param \Illuminate\Http\Request $request - * @return array - */ - public function toArray($request) - { - $lastPayment = $this->transactions()->where('transactions.type', TransactionType::PAYMENT)->whereIn('transactions.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->orderBy('id', 'DESC')->first(); - $totalPayments = $this->transactions()->where('transactions.type', TransactionType::PAYMENT)->whereIn('transactions.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->sum('amount'); - - $segment = SegmentConstant::where('reference', SegmentConstants::SUPPLIER_CURRENCIES)->where('detail->id', $this->id)->first(); - $serviceCharge = SegmentConstant::where('reference', SegmentConstants::SERVICE_CHARGE)->where('detail->id', $this->id)->first(); - - $userResource = null; - - $userInfoEmail = $this->userInfo && isset($this->userInfo->email) ? $this->userInfo->email : null; - $userInfoType = $this->userInfo && isset($this->userInfo->type) ? $this->userInfo->type : null; - - if(!$userInfoEmail && Auth::user()){ - $userInfoEmail = Auth::user()->email; - } - if(!$userInfoType && Auth::user()){ - $userInfoType = Auth::user()->type; - } - - if(!is_null($userInfoEmail) && !is_null($userInfoType)){ - $userResource = new V1\UserResource($userInfoType === RoleTypes::USER ? $this->employees()->where('email', '=', $userInfoEmail)->first() : $this->employees()->orderBy('id', 'DESC')->first()); - } - - return [ - 'id' => $this->id, - 'name' => $this->name, - 'reference' => $this->reference, - 'debtor' => $this->debtor, - 'type' => (int) $this->type, - 'business_type' => (int) $this->business_type, - 'status' => (int) $this->status, - 'contact' => new V1\ContactResource ($this->when($this->has('contacts'), $this->contacts->first())), - 'address' => new V1\AddressResource($this->when($this->has('addresses'), $this->addresses->where('billing', true)->first())), - 'employee' => $userResource, - 'identification' => new V1\DocumentResource($this->documents->whereIn('document_type', DocumentType::IDENTIFICATION_DOCUMENTS)->first()), - 'bookings' => $this->whenLoaded('bookings', $this->bookings()->orderBy('id', 'DESC')->get(), []), - 'confirmed_bookings' => $this->bookings()->whereHas('transactions', function ($query){ - $query->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); - })->count(), - 'total_payments' => (float) $totalPayments, - 'average_spending_per_day' => (float) $totalPayments / ($this->created_at->diff(Carbon::now())->days === 0 ? 1 : $this->created_at->diff(Carbon::now())->days), - 'average_spending_per_booking' => (float) $totalPayments > 0 ? $totalPayments / $this->bookings()->whereHas('transactions', function ($query){ - $query->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); - })->count() : $totalPayments, - 'last_payment' => $lastPayment ? $lastPayment->created_at->diffForHumans() : 'No Payments', - 'personal_banks' => V1\BankResource::collection($this->banks->where('type', BankAccountType::PERSONAL)), - 'recipient_banks' => [ - 'accounts' => V1\BankResource::collection($this->banks->where('type', BankAccountType::EXTERNAL)), - 'default' => new V1\BankResource($this->banks->where('type', BankAccountType::EXTERNAL)->where('default', true)->first()) - ], - 'segments' => V1\SegmentResource::collection($this->segments), - 'seasonalSegment' => $this->whenLoaded('seasonalSegments', V1\SeasonalSegmentResource::collection($this->seasonalSegments)), - 'services' => (new FetchesCompanyServices())->getServices($this->servicesConfigurations()), - 'wallet' => $this->whenLoaded('wallets', new V1\WalletResource($this->wallets()->with('transactions')->first()), new V1\WalletResource($this->wallets()->first())), - 'created_at' => $this->created_at->format('d-m-Y'), - $this->mergeWhen($this->business_type === BusinessType::CURRENCY_VENDOR, [ - 'currencies' => $segment ? V1\CurrencyResource::collection(Currency::whereIn('id', $segment->detail->currencies)->get()) : [], - 'service_charge' => $serviceCharge - ]) - - ]; - } -} diff --git a/app/Models/JobResult.php b/app/Models/JobResult.php deleted file mode 100644 index f30b5076..00000000 --- a/app/Models/JobResult.php +++ /dev/null @@ -1,13 +0,0 @@ -id(); - $table->string('job_id', 50); - $table->longText('result')->nullable(); - $table->timestamps(); - - // $table->foreign('job_id')->references('id')->on('jobs')->onDelete('cascade'); - }); - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::dropIfExists('job_results'); - } -} diff --git a/database/migrations/2023_08_29_063531_add_new_column_to_job_results_table.php b/database/migrations/2023_08_29_063531_add_new_column_to_job_results_table.php deleted file mode 100644 index 8e6b8342..00000000 --- a/database/migrations/2023_08_29_063531_add_new_column_to_job_results_table.php +++ /dev/null @@ -1,36 +0,0 @@ -longText('url')->after('result')->nullable(); - $table->string('job_command_name')->after('url')->nullable(); - $table->longText('job_command')->after('job_command_name')->nullable(); - }); - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::table('job_results', function (Blueprint $table) { - $table->dropColumn('url'); - $table->dropColumn('job_command_name'); - $table->dropColumn('job_command'); - }); - } -} diff --git a/database/migrations/2023_12_11_193200_add_new_column_2_to_job_results_table.php b/database/migrations/2023_12_11_193200_add_new_column_2_to_job_results_table.php deleted file mode 100644 index 12c6d57f..00000000 --- a/database/migrations/2023_12_11_193200_add_new_column_2_to_job_results_table.php +++ /dev/null @@ -1,34 +0,0 @@ -string('request_signature')->after('job_id')->nullable(); - $table->string('result_signature')->after('request_signature')->nullable(); - }); - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::table('job_results', function (Blueprint $table) { - $table->dropColumn('request_signature'); - $table->dropColumn('result_signature'); - }); - } -} diff --git a/resources/assets/vue/components/bookings/sections/AdminPaymentsBillingSectionComponent.vue b/resources/assets/vue/components/bookings/sections/AdminPaymentsBillingSectionComponent.vue deleted file mode 100644 index 966ccbbc..00000000 --- a/resources/assets/vue/components/bookings/sections/AdminPaymentsBillingSectionComponent.vue +++ /dev/null @@ -1,136 +0,0 @@ - - diff --git a/resources/assets/vue/components/bookings/sections/AdminPaymentsBillingSectionPollingComponent.vue b/resources/assets/vue/components/bookings/sections/AdminPaymentsBillingSectionPollingComponent.vue deleted file mode 100644 index 47d14857..00000000 --- a/resources/assets/vue/components/bookings/sections/AdminPaymentsBillingSectionPollingComponent.vue +++ /dev/null @@ -1,136 +0,0 @@ - - diff --git a/resources/assets/vue/components/bookings/sections/SupplierPendingOrdersSectionComponent.vue b/resources/assets/vue/components/bookings/sections/SupplierPendingOrdersSectionComponent.vue index d2b69080..7df9c125 100644 --- a/resources/assets/vue/components/bookings/sections/SupplierPendingOrdersSectionComponent.vue +++ b/resources/assets/vue/components/bookings/sections/SupplierPendingOrdersSectionComponent.vue @@ -117,17 +117,11 @@
- -
@@ -171,7 +165,7 @@ } }, created(){ - this.submit(route('api.company.list') + '?filters=' + JSON.stringify({'business_type': 3, 'status_in': [1, 2, 0]}), 'get', 'pendingOrdersSection', false, false); //cief todo: Uncaught (in promise) null + this.submit(route('api.company.list') + '?filters=' + JSON.stringify({'business_type': 3, 'status_in': [1, 2, 0]}), 'get', 'pendingOrdersSection', false, false) }, methods: { successHandler(response){ @@ -216,4 +210,4 @@ } - + \ No newline at end of file diff --git a/resources/assets/vue/components/general/elements/ListPollingComponent.vue b/resources/assets/vue/components/general/elements/ListPollingComponent.vue deleted file mode 100644 index fcd3b8b8..00000000 --- a/resources/assets/vue/components/general/elements/ListPollingComponent.vue +++ /dev/null @@ -1,213 +0,0 @@ - - - diff --git a/resources/assets/vue/general/mixins/aws/requestV2.js b/resources/assets/vue/general/mixins/aws/requestV2.js deleted file mode 100644 index 12b27542..00000000 --- a/resources/assets/vue/general/mixins/aws/requestV2.js +++ /dev/null @@ -1,49 +0,0 @@ -export default { - methods: { - poll(url, method, section, successNotification = true, errorNotification = true){ - if(!this.validate()){ return; } - if (section) { - this.$store.dispatch('toggleLoading', {name: section, status: true}) - } - this.$store.dispatch('crudRequestV2', { - endpoint: url, - method: method, - parameters: this.parameters - }).then(response => { - let statusCode = response.status, - success = response.ok; - - response.json().then(response => { - - if(!success){ - this.openModal(); - errorNotification ? this.$store.dispatch('createNotification', {title: response.title, message: response.message, type: 'error'}): null; - this.errorHandler(response, statusCode); return; - } - - successNotification ? this.$store.dispatch('createNotification', {title: response.title, message: response.message, type: 'success'}): null; - this.successHandler(response) - - - }); - }).catch((error) => { - this.$store.dispatch('createNotification', {title: 'Unexpected Error', message: 'An unexpected error has occurred. Try again!', type: 'error'}); - }).then(() => { - if (section) { - this.$store.dispatch('toggleLoading', {name: section, status: false}) - } - }) - - }, - validate() { - if(this.$v){ - this.$v.$touch(); - return !this.$v.$invalid; - } - return true; - }, - successHandler(response){}, - errorHandler(response){} - } - -} diff --git a/resources/assets/vue/general/mixins/tabHandler.js b/resources/assets/vue/general/mixins/tabHandler.js deleted file mode 100644 index 81790ed0..00000000 --- a/resources/assets/vue/general/mixins/tabHandler.js +++ /dev/null @@ -1,24 +0,0 @@ -export default { - data() { - return { - activeTab: null, - displayedTabs: [], - }; - }, - methods: { - setActiveTab(event) { - const tabName = event.currentTarget.getAttribute('tab-name'); - // console.log(`Tab "${tabName}" clicked`); - this.activeTab = tabName; - if (!this.displayedTabs.includes(tabName)) { - this.displayedTabs.push(tabName); - } - }, - isActiveTab(tabName) { - return this.activeTab === tabName; - }, - showTabContent(tabName) { - return this.displayedTabs.includes(tabName); - }, - }, -} diff --git a/resources/assets/vue/vuex/modules/crudRequestV2.js b/resources/assets/vue/vuex/modules/crudRequestV2.js deleted file mode 100644 index 355b1edb..00000000 --- a/resources/assets/vue/vuex/modules/crudRequestV2.js +++ /dev/null @@ -1,51 +0,0 @@ -export default { - actions: { - crudRequestV2({getters, dispatch}, {endpoint, method, parameters}){ - return dispatch('ensureReCaptchaIsSet').then(function () { - const queryDomain = endpoint.split('?')[0]; - let encodedParams = endpoint.split('?')[1]; - let decodedParams = fullyDecodeURI(encodedParams); - const queryParams = encodeURIComponent(decodedParams); - encodedParams = queryParams.toString(); - let filteredEncodedParams = encodedParams.replace(/%3D/g,'='); - filteredEncodedParams = filteredEncodedParams.replace(/%26/g,'&'); - let combinedAbsoluteUrl = queryDomain; - if(filteredEncodedParams !== undefined && filteredEncodedParams !== 'undefined'){ - combinedAbsoluteUrl = queryDomain + '?' + filteredEncodedParams; - } - - // return fetch(endpoint, { - return fetch(combinedAbsoluteUrl, { - method: method, - responseType: 'json', - body: parameters ? JSON.stringify(parameters):null, - headers: { - 'content-type': 'application/json', - 'Authorization': 'Bearer '+getters.getAccessToken, - 'captcha-token': getters.getReCaptcha - } - }).then(response => { - - if(response.status === 401 && window.location.href !== route('login')){ - dispatch('userAuthentication', {access_token: '', redirect_url: '/'}); - } - - return response; - - }) - }); - } - } -} - -function isEncoded(uri) { - uri = uri || ''; - return uri !== decodeURIComponent(uri); -} - -function fullyDecodeURI(uri){ - while (isEncoded(uri)){ - uri = decodeURIComponent(uri); - } - return uri; -} diff --git a/resources/assets/vue/vuex/store.js b/resources/assets/vue/vuex/store.js index ff10c673..2c3d911b 100644 --- a/resources/assets/vue/vuex/store.js +++ b/resources/assets/vue/vuex/store.js @@ -4,7 +4,6 @@ import toggleSection from './modules/toggleSection' import toggleLoading from './modules/toggleLoading' import createNotification from './modules/createNotification' import crudRequest from './modules/crudRequest' -import crudRequestV2 from './modules/crudRequestV2' import authentication from './modules/authentication' import loadRequestQueue from './modules/loadRequestQueue' @@ -17,7 +16,6 @@ export default new Vuex.Store({ loadRequestQueue, createNotification, crudRequest, - crudRequestV2, authentication } -}) +}) \ No newline at end of file diff --git a/resources/views/pages/billings.blade.php b/resources/views/pages/billings.blade.php index da84f8b9..4bc012d5 100644 --- a/resources/views/pages/billings.blade.php +++ b/resources/views/pages/billings.blade.php @@ -3,7 +3,129 @@
- + +
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
Invoice
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
Purchase Order
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
Delivery Order
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
Supplier Delivery Order
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+
+
+
-@endsection +@endsection \ No newline at end of file diff --git a/resources/views/pages/billings_experiment.blade.php b/resources/views/pages/billings_experiment.blade.php deleted file mode 100644 index d1caee2d..00000000 --- a/resources/views/pages/billings_experiment.blade.php +++ /dev/null @@ -1,9 +0,0 @@ -@extends('layouts.base_portal') -@section('inner_content') -
-
- - -
-
-@endsection diff --git a/routes/api.php b/routes/api.php index 460bd772..8b4bada0 100644 --- a/routes/api.php +++ b/routes/api.php @@ -67,10 +67,6 @@ Route::group(['middleware' => 'api', 'prefix' => 'v1', 'as' => 'api.'], function require __DIR__ . '/milestone.php'; - // require __DIR__ . '/accounting.php'; //cief todo: To check if this is needed - - require __DIR__ . '/job.php'; - // require __DIR__ . '/rate.php'; // require __DIR__ . '/receipt.php'; diff --git a/routes/currency.php b/routes/currency.php index ba55c9a2..b621aad6 100644 --- a/routes/currency.php +++ b/routes/currency.php @@ -1,4 +1,4 @@ - 'document', 'as' => 'document.', 'namespace' => 'Documents'], function () { Route::get('/list', 'ListDocumentsController@list')->name('list'); - Route::get('/list/job', 'ListDocumentsJobController@list')->name('list.job'); Route::delete('/{id}/delete', 'DeleteDocumentController@delete')->name('delete'); Route::put('/{id}/approve', 'ApproveDocumentController@approve')->name('status.approve'); Route::put('/{id}/reject', 'RejectDocumentController@reject')->name('status.reject'); Route::put('/{id}/reference/update', 'UpdateDocumentReferenceController@update')->name('reference.update'); -}); +}); \ No newline at end of file diff --git a/routes/job.php b/routes/job.php deleted file mode 100644 index 028e9468..00000000 --- a/routes/job.php +++ /dev/null @@ -1,8 +0,0 @@ - 'job', 'as' => 'job.', 'namespace' => 'Jobs'], function () { - Route::get('/fetch/{job_id}', 'FetchJobResultController@fetch')->name('fetch'); - Route::get('/fetch/{job_id}/{is_last}', 'FetchJobResultController@fetch')->name('fetch.last.attempt'); -}); diff --git a/routes/web.php b/routes/web.php index a6590c17..bf2892bb 100644 --- a/routes/web.php +++ b/routes/web.php @@ -92,12 +92,6 @@ Route::get('/billings', function () { return view('pages.billings'); })->name('billings'); -/* Vue Polling Experiment - Starts */ -Route::get('/billings-experiment', function () { - return view('pages.billings_experiment'); -})->name('billings.experiment'); -/* Vue Polling Experiment - Ends */ - Route::get('/currency_orders', function () { return view('pages.currency_orders'); })->name('currency_orders'); @@ -836,13 +830,13 @@ Route::get('/invoice/{marking}/{started_at}/{ended_at}/fix', function($marking, ->withTrashed() ->orderBy('created_at', 'asc') ->first(); - + // get the first bill_no $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(); $currentInvoice->bill_no = $currentInvoice->bill_no ."-deleted-" . Str::random(10); @@ -865,4 +859,4 @@ Route::get('/invoice/{marking}/{started_at}/{ended_at}/fix', function($marking, } } ); -})->name('invoice.fix.byCustomerMarking'); +})->name('invoice.fix.byCustomerMarking'); \ No newline at end of file From f8230990f4f46348cd37551bd18fa1f75a2232d2 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Sun, 11 Feb 2024 10:28:05 +0000 Subject: [PATCH 102/434] Revert "Merge branch 'revert-b9668bb6' into 'master'" This reverts merge request !157 --- .../JobResourceNotFoundException.php | 11 + .../Abstracts/AbstractControllerLogic.php | 15 +- .../General/Eloquent/AbstractFetchRecord.php | 14 +- .../General/Eloquent/AbstractGetRecord.php | 26 ++- .../General/Eloquent/AbstractListRecord.php | 14 +- .../General/Eloquent/Filters/JobId.php | 20 ++ .../Eloquent/Filters/OrderByIdDesc.php | 20 ++ .../Eloquent/Filters/RequestSignature.php | 19 ++ .../Eloquent/Filters/ResultNotNull.php | 18 ++ app/Classes/General/Helper.php | 24 ++ app/Classes/Jobs/ListBookingsJob.php | 52 +++++ app/Classes/Jobs/ListDocumentsJob.php | 63 ++++++ app/Classes/Jobs/ListTransactionsJob.php | 52 +++++ .../ControllersLogic/ListBookingJobLogic.php | 75 ++++++ .../Processors/ListBookingsJobProcessor.php | 46 ++++ .../ControllersLogic/ListDocumentJobLogic.php | 75 ++++++ .../Processors/ListDocumentsJobProcessor.php | 47 ++++ .../ControllersLogic/FetchJobResultLogic.php | 51 +++++ .../ListGenericJobObject.php | 118 ++++++++++ .../UpdateJobResultObject.php | 60 +++++ .../Processors/FetchesJobResultProcessor.php | 47 ++++ .../Processors/UpdateJobResultProcessor.php | 64 ++++++ .../Jobs/Services/CreatesJobResult.php | 26 +++ .../Jobs/Services/FetchesJobResult.php | 33 +++ .../Modules/Jobs/Services/ListsJobResult.php | 33 +++ .../Jobs/Services/UpdatesJobResult.php | 28 +++ .../ListTransactionsJobLogic.php | 74 ++++++ .../ListTransactionsJobProcessor.php | 45 ++++ .../Bookings/ListBookingsJobController.php | 22 ++ .../Documents/ListDocumentsJobController.php | 19 ++ .../Jobs/FetchJobResultController.php | 19 ++ .../ListTransactionsJobController.php | 21 ++ app/Http/Resources/BookingResource.php | 2 - app/Http/Resources/CompanyResource.php | 1 - app/Http/Resources/DocumentResource.php | 3 - app/Http/Resources/JobResultResource.php | 22 ++ app/Http/Resources/ListBookingJobResource.php | 81 +++++++ .../Resources/ListDocumentJobResource.php | 31 +++ .../Resources/ListTransactionJobResource.php | 54 +++++ app/Http/Resources/V2/BookingV2Resource.php | 82 +++++++ app/Http/Resources/V2/CompanyV2Resource.php | 100 ++++++++ app/Models/JobResult.php | 13 ++ ..._08_08_124848_create_job_results_table.php | 35 +++ ...31_add_new_column_to_job_results_table.php | 36 +++ ..._add_new_column_2_to_job_results_table.php | 34 +++ .../AdminPaymentsBillingSectionComponent.vue | 136 +++++++++++ ...PaymentsBillingSectionPollingComponent.vue | 136 +++++++++++ .../SupplierPendingOrdersSectionComponent.vue | 10 +- .../general/elements/ListPollingComponent.vue | 213 ++++++++++++++++++ .../vue/general/mixins/aws/requestV2.js | 49 ++++ .../assets/vue/general/mixins/tabHandler.js | 24 ++ .../assets/vue/vuex/modules/crudRequestV2.js | 51 +++++ resources/assets/vue/vuex/store.js | 4 +- resources/views/pages/billings.blade.php | 126 +---------- .../views/pages/billings_experiment.blade.php | 9 + routes/api.php | 4 + routes/currency.php | 2 +- routes/document.php | 3 +- routes/job.php | 8 + routes/web.php | 12 +- 60 files changed, 2380 insertions(+), 152 deletions(-) create mode 100644 app/Classes/Exceptions/JobResourceNotFoundException.php create mode 100644 app/Classes/General/Eloquent/Filters/JobId.php create mode 100644 app/Classes/General/Eloquent/Filters/OrderByIdDesc.php create mode 100644 app/Classes/General/Eloquent/Filters/RequestSignature.php create mode 100644 app/Classes/General/Eloquent/Filters/ResultNotNull.php create mode 100644 app/Classes/Jobs/ListBookingsJob.php create mode 100644 app/Classes/Jobs/ListDocumentsJob.php create mode 100644 app/Classes/Jobs/ListTransactionsJob.php create mode 100644 app/Classes/Modules/Bookings/ControllersLogic/ListBookingJobLogic.php create mode 100644 app/Classes/Modules/Bookings/Processors/ListBookingsJobProcessor.php create mode 100644 app/Classes/Modules/Documents/ControllersLogic/ListDocumentJobLogic.php create mode 100644 app/Classes/Modules/Documents/Processors/ListDocumentsJobProcessor.php create mode 100644 app/Classes/Modules/Jobs/ControllersLogic/FetchJobResultLogic.php create mode 100644 app/Classes/Modules/Jobs/DataTransferObjects/ListGenericJobObject.php create mode 100644 app/Classes/Modules/Jobs/DataTransferObjects/UpdateJobResultObject.php create mode 100644 app/Classes/Modules/Jobs/Processors/FetchesJobResultProcessor.php create mode 100644 app/Classes/Modules/Jobs/Processors/UpdateJobResultProcessor.php create mode 100644 app/Classes/Modules/Jobs/Services/CreatesJobResult.php create mode 100644 app/Classes/Modules/Jobs/Services/FetchesJobResult.php create mode 100644 app/Classes/Modules/Jobs/Services/ListsJobResult.php create mode 100644 app/Classes/Modules/Jobs/Services/UpdatesJobResult.php create mode 100644 app/Classes/Modules/Transactions/ControllersLogic/ListTransactionsJobLogic.php create mode 100644 app/Classes/Modules/Transactions/Processors/ListTransactionsJobProcessor.php create mode 100644 app/Http/Controllers/Bookings/ListBookingsJobController.php create mode 100644 app/Http/Controllers/Documents/ListDocumentsJobController.php create mode 100644 app/Http/Controllers/Jobs/FetchJobResultController.php create mode 100644 app/Http/Controllers/Transactions/ListTransactionsJobController.php create mode 100644 app/Http/Resources/JobResultResource.php create mode 100644 app/Http/Resources/ListBookingJobResource.php create mode 100644 app/Http/Resources/ListDocumentJobResource.php create mode 100644 app/Http/Resources/ListTransactionJobResource.php create mode 100644 app/Http/Resources/V2/BookingV2Resource.php create mode 100644 app/Http/Resources/V2/CompanyV2Resource.php create mode 100644 app/Models/JobResult.php create mode 100644 database/migrations/2023_08_08_124848_create_job_results_table.php create mode 100644 database/migrations/2023_08_29_063531_add_new_column_to_job_results_table.php create mode 100644 database/migrations/2023_12_11_193200_add_new_column_2_to_job_results_table.php create mode 100644 resources/assets/vue/components/bookings/sections/AdminPaymentsBillingSectionComponent.vue create mode 100644 resources/assets/vue/components/bookings/sections/AdminPaymentsBillingSectionPollingComponent.vue create mode 100644 resources/assets/vue/components/general/elements/ListPollingComponent.vue create mode 100644 resources/assets/vue/general/mixins/aws/requestV2.js create mode 100644 resources/assets/vue/general/mixins/tabHandler.js create mode 100644 resources/assets/vue/vuex/modules/crudRequestV2.js create mode 100644 resources/views/pages/billings_experiment.blade.php create mode 100644 routes/job.php diff --git a/app/Classes/Exceptions/JobResourceNotFoundException.php b/app/Classes/Exceptions/JobResourceNotFoundException.php new file mode 100644 index 00000000..a8ef358e --- /dev/null +++ b/app/Classes/Exceptions/JobResourceNotFoundException.php @@ -0,0 +1,11 @@ +getMessage(), + $exception->getTrace()[0]['file'], + $exception->getTrace()[0]['line'] + )); + } + else{ + log::error($exception); + } + return (new ApiResponseObject($this->getNotificationTitle().' failed', $exception->getMessage(), $exception->getCode() ? $exception->getCode() : HttpStatus::SERVER_ERROR))->handler(); diff --git a/app/Classes/General/Eloquent/AbstractFetchRecord.php b/app/Classes/General/Eloquent/AbstractFetchRecord.php index 248deee7..503fb369 100644 --- a/app/Classes/General/Eloquent/AbstractFetchRecord.php +++ b/app/Classes/General/Eloquent/AbstractFetchRecord.php @@ -4,9 +4,11 @@ namespace App\Classes\General\Eloquent; use App\Classes\Exceptions\ResourceNotFoundException; +use App\Classes\Exceptions\JobResourceNotFoundException; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Psy\Exception\ErrorException; +use Illuminate\Support\Facades\Log; abstract class AbstractFetchRecord extends AbstractGetRecord { @@ -27,12 +29,18 @@ abstract class AbstractFetchRecord extends AbstractGetRecord * @return Model * @throws ResourceNotFoundException */ - public function getResults(Builder $query): Model { + public function getResults(Builder $query, array $param = []): Model { if(!$query->exists()){ - throw new ResourceNotFoundException('Unable to find any record based on the criteria provided'); + $table = $query->getModel()->getTable(); + if($table ==='job_results'){ + throw new JobResourceNotFoundException('Unable to find any job based on the criteria provided'); + } + else{ + throw new ResourceNotFoundException('Unable to find any record based on the criteria provided'); + } } return $query->first(); } -} \ No newline at end of file +} diff --git a/app/Classes/General/Eloquent/AbstractGetRecord.php b/app/Classes/General/Eloquent/AbstractGetRecord.php index f927d818..1a7eac3e 100644 --- a/app/Classes/General/Eloquent/AbstractGetRecord.php +++ b/app/Classes/General/Eloquent/AbstractGetRecord.php @@ -30,11 +30,25 @@ abstract class AbstractGetRecord return $this->filters->only(self::DECORATION_FILTERS); } + // /** + // * @param null|string $json + // * @return array + // */ + // public function deserializeFilters(?string $json): array { + // return $json !== null ? collect(json_decode($json))->toArray() : []; + // } + /** - * @param null|string $json + * @param null|string $param * @return array */ - public function deserializeFilters(?string $json): array { + public function deserializeFilters($param): array { + if(gettype($param) == "array"){ + $json = implode(',', $param); + } + else{ + $json = $param; + } return $json !== null ? collect(json_decode($json))->toArray() : []; } @@ -50,9 +64,9 @@ abstract class AbstractGetRecord * @param array $filters * @return mixed */ - public function handler(array $filters){ + public function handler(array $filters, array $params = []){ $this->filters = collect($filters); - return $this->getResults($this->applyFiltersToQuery()); + return $this->getResults($this->applyFiltersToQuery(), $params); } @@ -65,6 +79,6 @@ abstract class AbstractGetRecord * @param Builder $query * @return mixed */ - abstract function getResults(Builder $query); + abstract function getResults(Builder $query, array $params = []); -} \ No newline at end of file +} diff --git a/app/Classes/General/Eloquent/AbstractListRecord.php b/app/Classes/General/Eloquent/AbstractListRecord.php index 7b7d0df9..f898f108 100644 --- a/app/Classes/General/Eloquent/AbstractListRecord.php +++ b/app/Classes/General/Eloquent/AbstractListRecord.php @@ -17,11 +17,11 @@ abstract class AbstractListRecord extends AbstractGetRecord * @return mixed * @throws MalformedRequestException */ - public function execute(array $filters = []){ + public function execute(array $filters = [], array $param = []){ try{ - return $this->handler($filters); + return $this->handler($filters, $param); } catch (QueryException $exception){ log::error($exception); @@ -30,18 +30,24 @@ abstract class AbstractListRecord extends AbstractGetRecord } + /** * @param Builder $query * @return mixed */ - public function getResults(Builder $query) { + public function getResults(Builder $query, array $param = []) { $filters = $this->getDecorationFilters(); if($filters->has('order_by')){ $query = $query->orderBy($filters->get('order_by')->column, $filters->get('order_by')->DESC ? 'DESC': 'ASC'); } - return $filters->has('per_page') ? $query->paginate($filters->get('per_page')) : $query->get(); + if(!empty($param)){ + return $filters->has('per_page') ? $query->paginate($filters->get('per_page'), ['*'], 'page', $param['page']) : $query->get(); //page data from query parameters e.g ?page=1 + } + else{ + return $filters->has('per_page') ? $query->paginate($filters->get('per_page')) : $query->get(); + } } diff --git a/app/Classes/General/Eloquent/Filters/JobId.php b/app/Classes/General/Eloquent/Filters/JobId.php new file mode 100644 index 00000000..42ac51a4 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/JobId.php @@ -0,0 +1,20 @@ +where('job_id', $value); + } + +} diff --git a/app/Classes/General/Eloquent/Filters/OrderByIdDesc.php b/app/Classes/General/Eloquent/Filters/OrderByIdDesc.php new file mode 100644 index 00000000..547ec9bd --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/OrderByIdDesc.php @@ -0,0 +1,20 @@ +orderBy('id', 'desc'); + } + +} diff --git a/app/Classes/General/Eloquent/Filters/RequestSignature.php b/app/Classes/General/Eloquent/Filters/RequestSignature.php new file mode 100644 index 00000000..67dde0a3 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/RequestSignature.php @@ -0,0 +1,19 @@ +where('request_signature', $value); + } + +} diff --git a/app/Classes/General/Eloquent/Filters/ResultNotNull.php b/app/Classes/General/Eloquent/Filters/ResultNotNull.php new file mode 100644 index 00000000..3f6a0341 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/ResultNotNull.php @@ -0,0 +1,18 @@ +whereNotNull('result'); + } +} diff --git a/app/Classes/General/Helper.php b/app/Classes/General/Helper.php index ac89540b..45c72f53 100644 --- a/app/Classes/General/Helper.php +++ b/app/Classes/General/Helper.php @@ -2,6 +2,7 @@ namespace App\Classes\General; +use Illuminate\Http\Resources\Json\ResourceCollection; use Illuminate\Support\Facades\Log; use Illuminate\Support\Str; @@ -42,4 +43,27 @@ class Helper } } } + + /** + * @param null|string $param + * @return array + */ + static function deserializeFilters($param): array { + if(gettype($param) == "array"){ + $json = implode(',', $param); + } + else{ + $json = $param; + } + return $json !== null ? collect(json_decode($json))->toArray() : []; + } + + /** + * @param ResourceCollection $collection + * @return array + */ + static function collectionResponse(ResourceCollection $collection){ + return json_decode($collection->response()->getContent(), true); + } + } diff --git a/app/Classes/Jobs/ListBookingsJob.php b/app/Classes/Jobs/ListBookingsJob.php new file mode 100644 index 00000000..b021b71d --- /dev/null +++ b/app/Classes/Jobs/ListBookingsJob.php @@ -0,0 +1,52 @@ +listGenericJobObject = $listGenericJobObject; + } + + public function handle() + { + $rawPayload = $this->job->payload(); + if(isset($rawPayload['data']['commandName'])){ + $this->listGenericJobObject->setJobCommandName($rawPayload['data']['commandName']); + } + + if(isset($rawPayload['data']['command'])){ + $this->listGenericJobObject->setJobCommand($rawPayload['data']['command']); + } + + $result = (App()->make(ListBookingsJobProcessor::class))->execute($this->listGenericJobObject); + } + + public function getJobId(){ + return $this->job->getJobId(); + } +} diff --git a/app/Classes/Jobs/ListDocumentsJob.php b/app/Classes/Jobs/ListDocumentsJob.php new file mode 100644 index 00000000..6e93062b --- /dev/null +++ b/app/Classes/Jobs/ListDocumentsJob.php @@ -0,0 +1,63 @@ +listGenericJobObject = $listGenericJobObject; + } + + public function handle() + { + $rawPayload = $this->job->payload(); + if(isset($rawPayload['data']['commandName'])){ + $this->listGenericJobObject->setJobCommandName($rawPayload['data']['commandName']); + } + + if(isset($rawPayload['data']['command'])){ + $this->listGenericJobObject->setJobCommand($rawPayload['data']['command']); + } + + $result = (App()->make(ListDocumentsJobProcessor::class))->execute($this->listGenericJobObject); + + //cief todo: Insert into DB: job id, query result, timestamp + // Store the result in the job_results table + + //cief todo: why cannot save data in table like this + // $model = new JobResult(); + // $model->job_id = $this->job->getJobId(); + // $model->result = json_encode($result); + // $model->save(); + + // Log::error(json_encode($model->id)); + } + + public function getJobId(){ + return $this->job->getJobId(); + } +} diff --git a/app/Classes/Jobs/ListTransactionsJob.php b/app/Classes/Jobs/ListTransactionsJob.php new file mode 100644 index 00000000..a2b28656 --- /dev/null +++ b/app/Classes/Jobs/ListTransactionsJob.php @@ -0,0 +1,52 @@ +listGenericJobObject = $listGenericJobObject; + } + + public function handle() + { + $rawPayload = $this->job->payload(); + if(isset($rawPayload['data']['commandName'])){ + $this->listGenericJobObject->setJobCommandName($rawPayload['data']['commandName']); + } + + if(isset($rawPayload['data']['command'])){ + $this->listGenericJobObject->setJobCommand($rawPayload['data']['command']); + } + + $result = (App()->make(ListTransactionsJobProcessor::class))->execute($this->listGenericJobObject); + } + + public function getJobId(){ + return $this->job->getJobId(); + } +} diff --git a/app/Classes/Modules/Bookings/ControllersLogic/ListBookingJobLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/ListBookingJobLogic.php new file mode 100644 index 00000000..ef3570f7 --- /dev/null +++ b/app/Classes/Modules/Bookings/ControllersLogic/ListBookingJobLogic.php @@ -0,0 +1,75 @@ + 'List Booking Job', + 'message' => 'You have successfully submit a job to list bookings' + ]; + } + + /** @var CreatesJobResult */ + private $createsJobResult; + + /** + * ListPackingListsJobLogic constructor. + * @param CreatesJobResult $createsJobResult + */ + public function __construct(CreatesJobResult $createsJobResult) + { + $this->createsJobResult = $createsJobResult; + } + + + /** + * @param Request $request + * @return JsonResponse + */ + public function logic(Request $request) : JsonResponse + { + $jobId = uniqid(); + + $user = Auth::user(); + $userInfo = (object) [ + 'type' => $user->type, + ]; + + $userInfoJson = json_encode($userInfo); + $requestSignature = md5($userInfoJson . $request->fullUrl()); + + $listGenericJobObject = new ListGenericJobObject( + $request->fullUrl(), + $request->all(), + $requestSignature, + null, + $jobId, + $userInfo + ); + + ListBookingsJob::dispatch($listGenericJobObject); + + $result = []; + $result['job_id'] = $jobId; + + $this->createsJobResult->execute($listGenericJobObject); + + return $this->response(['data' => $result]); + } + +} diff --git a/app/Classes/Modules/Bookings/Processors/ListBookingsJobProcessor.php b/app/Classes/Modules/Bookings/Processors/ListBookingsJobProcessor.php new file mode 100644 index 00000000..2a09eb12 --- /dev/null +++ b/app/Classes/Modules/Bookings/Processors/ListBookingsJobProcessor.php @@ -0,0 +1,46 @@ +listsBookings = $listsBookings; + $this->updateJobResultProcessor = $updateJobResultProcessor; + } + + /** + * @param ListGenericJobObject $listGenericJobObject + * @return void + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\JobResourceNotFoundException + */ + public function execute(ListGenericJobObject $listGenericJobObject) { + + $query = $this->listsBookings->execute($this->listsBookings->deserializeFilters($listGenericJobObject->getPayload()['filters']), ['page' => $listGenericJobObject->getPayload()['page']]); + foreach ($query->items() as &$item) { + $item['userInfo'] = $listGenericJobObject->getUserInfo(); + } + $resultCurrent = Helper::collectionResponse(ListBookingJobResource::collection($query)); + $this->updateJobResultProcessor->execute($listGenericJobObject, $resultCurrent); + } +} diff --git a/app/Classes/Modules/Documents/ControllersLogic/ListDocumentJobLogic.php b/app/Classes/Modules/Documents/ControllersLogic/ListDocumentJobLogic.php new file mode 100644 index 00000000..5e895ad8 --- /dev/null +++ b/app/Classes/Modules/Documents/ControllersLogic/ListDocumentJobLogic.php @@ -0,0 +1,75 @@ + 'List Document Job', + 'message' => 'You have successfully submit a job to list documents' + ]; + } + + /** @var CreatesJobResult */ + private $createsJobResult; + + /** + * ListDocumentJobLogic constructor. + * @param CreatesJobResult $createsJobResult + */ + public function __construct(CreatesJobResult $createsJobResult) + { + $this->createsJobResult = $createsJobResult; + } + + + /** + * @param Request $request + * @return JsonResponse + */ + public function logic(Request $request) : JsonResponse + { + $jobId = uniqid(); + + $user = Auth::user(); + $userInfo = (object) [ + 'email' => $user->email, + 'type' => $user->type, + ]; + + $userInfoJson = json_encode($userInfo); + $requestSignature = md5($userInfoJson . $request->fullUrl()); + + $listGenericJobObject = new ListGenericJobObject( + $request->fullUrl(), + $request->all(), + $requestSignature, + null, + $jobId, + $userInfo + ); + + ListDocumentsJob::dispatch($listGenericJobObject); + + $result = []; + $result['job_id'] = $jobId; + + $this->createsJobResult->execute($listGenericJobObject); + + return $this->response(['data' => $result]); + } +} diff --git a/app/Classes/Modules/Documents/Processors/ListDocumentsJobProcessor.php b/app/Classes/Modules/Documents/Processors/ListDocumentsJobProcessor.php new file mode 100644 index 00000000..70777f0c --- /dev/null +++ b/app/Classes/Modules/Documents/Processors/ListDocumentsJobProcessor.php @@ -0,0 +1,47 @@ +listsDocuments = $listsDocuments; + $this->updateJobResultProcessor = $updateJobResultProcessor; + } + + /** + * @param ListGenericJobObject $listGenericJobObject + * @return void + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\JobResourceNotFoundException + */ + public function execute(ListGenericJobObject $listGenericJobObject) { + + $query = $this->listsDocuments->execute($this->listsDocuments->deserializeFilters($listGenericJobObject->getPayload()['filters']), ['page' => $listGenericJobObject->getPayload()['page']]); + foreach ($query->items() as &$item) { + $item['userInfo'] = $listGenericJobObject->getUserInfo(); + } + $resultCurrent = Helper::collectionResponse(ListDocumentJobResource::collection($query)); + $this->updateJobResultProcessor->execute($listGenericJobObject, $resultCurrent); + } +} + diff --git a/app/Classes/Modules/Jobs/ControllersLogic/FetchJobResultLogic.php b/app/Classes/Modules/Jobs/ControllersLogic/FetchJobResultLogic.php new file mode 100644 index 00000000..c4b72cf0 --- /dev/null +++ b/app/Classes/Modules/Jobs/ControllersLogic/FetchJobResultLogic.php @@ -0,0 +1,51 @@ + 'Retrieved Data', + 'message' => 'You have successfully retrieved data' + ]; + } + + /** @var FetchesJobResultProcessor */ + private $fetchesJobResultProcessor; + + /** + * FetchJobResultLogic constructor. + * @param FetchesJobResultProcessor $fetchesJobResultProcessor + */ + public function __construct(FetchesJobResultProcessor $fetchesJobResultProcessor) + { + $this->fetchesJobResultProcessor = $fetchesJobResultProcessor; + } + + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\RequestValidationException + */ + public function logic(Request $request) : JsonResponse + { + $query = $this->fetchesJobResultProcessor->execute($request); + return $this->resourceResponse(new JobResultResource($query)); + } + +} diff --git a/app/Classes/Modules/Jobs/DataTransferObjects/ListGenericJobObject.php b/app/Classes/Modules/Jobs/DataTransferObjects/ListGenericJobObject.php new file mode 100644 index 00000000..953d77d7 --- /dev/null +++ b/app/Classes/Modules/Jobs/DataTransferObjects/ListGenericJobObject.php @@ -0,0 +1,118 @@ +name = $name; + $this->payload = $payload; + $this->jobId = $jobId; + $this->requestSignature = $requestSignature; + $this->resultSignature = $resultSignature; + $this->userInfo = $userInfo; + } + + /** + * @return string + */ + public function getName(): string + { + return $this->name; + } + + /** + * @return array + */ + public function getPayload(): array + { + return $this->payload; + } + + /** + * @return string + */ + public function getJobId(): string + { + return $this->jobId; + } + + /** + * @return string + */ + public function getRequestSignature(): string + { + return $this->requestSignature; + } + + /** + * @return string + */ + public function getResultSignature(): ?string + { + return $this->resultSignature; + } + + /** + * @return object + */ + public function getUserInfo(): object + { + return $this->userInfo; + } + + /** + * @return string + */ + public function getJobCommandName(): string + { + return $this->jobCommandName; + } + + /** + * @return string + */ + public function getJobCommand(): string + { + return $this->jobCommand; + } + + + public function setJobCommandName(string $jobCommandName) + { + $this->jobCommandName = $jobCommandName; + } + + public function setJobCommand(string $jobCommand) + { + $this->jobCommand = $jobCommand; + } + +} diff --git a/app/Classes/Modules/Jobs/DataTransferObjects/UpdateJobResultObject.php b/app/Classes/Modules/Jobs/DataTransferObjects/UpdateJobResultObject.php new file mode 100644 index 00000000..636c56b0 --- /dev/null +++ b/app/Classes/Modules/Jobs/DataTransferObjects/UpdateJobResultObject.php @@ -0,0 +1,60 @@ +result = $result; + $this->resultSignature = $resultSignature; + $this->jobCommandName = $jobCommandName; + $this->jobCommand = $jobCommand; + } + + /** + * @return string + */ + public function getResult(): string + { + return $this->result; + } + + /** + * @return array + */ + public function getResultSignature(): string + { + return $this->resultSignature; + } + + /** + * @return string + */ + public function getJobCommandName(): string + { + return $this->jobCommandName; + } + + /** + * @return string + */ + public function getJobCommand(): string + { + return $this->jobCommand; + } +} diff --git a/app/Classes/Modules/Jobs/Processors/FetchesJobResultProcessor.php b/app/Classes/Modules/Jobs/Processors/FetchesJobResultProcessor.php new file mode 100644 index 00000000..89783fe8 --- /dev/null +++ b/app/Classes/Modules/Jobs/Processors/FetchesJobResultProcessor.php @@ -0,0 +1,47 @@ +fetchesJobResult = $fetchesJobResult; + } + + + /** + * @param Request $request + * @return Model + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\JobResourceNotFoundException + * @throws \App\Classes\Exceptions\ResourceNotFoundException + */ + public function execute(Request $request){ + + $res1 = $this->fetchesJobResult->execute(['job_id' => $request->route('job_id')]); + if($request->route('is_last')){ + $res2 = $this->fetchesJobResult->execute(['request_signature' => $res1->request_signature, 'result_not_null' => true, 'order_by_id_desc' => true]); + return $res2; + } + + if(!$res1->result){ + throw new JobResourceNotFoundException('Unable to find any job based on the criteria provided'); + } + + return $res1; + } +} diff --git a/app/Classes/Modules/Jobs/Processors/UpdateJobResultProcessor.php b/app/Classes/Modules/Jobs/Processors/UpdateJobResultProcessor.php new file mode 100644 index 00000000..0106417d --- /dev/null +++ b/app/Classes/Modules/Jobs/Processors/UpdateJobResultProcessor.php @@ -0,0 +1,64 @@ +fetchesJobResult = $fetchesJobResult; + $this->updatesJobResult = $updatesJobResult; + } + + /** + * @param ListGenericJobObject $listGenericJobObject + * @param array $resultCurrent + * @return void + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\JobResourceNotFoundException + */ + public function execute(ListGenericJobObject $listGenericJobObject, $resultCurrent) { + $jobResultCurrent = $this->fetchesJobResult->execute(['job_id' => $listGenericJobObject->getJobId()]); + $resultCurrentJson = json_encode($resultCurrent); + $resultSignatureCurrent = md5($resultCurrentJson); + + try{ + $jobResultExisting = $this->fetchesJobResult->execute(['request_signature' => $jobResultCurrent->request_signature, 'result_not_null' => true, 'order_by_id_desc' => true]); + $resultSignatureExisting = $jobResultExisting->result_signature; + //if($resultSignatureExisting != $resultSignatureCurrent){ + $this->updateJobResult($jobResultCurrent, $resultCurrentJson, $resultSignatureCurrent, $listGenericJobObject->getJobCommandName(), $listGenericJobObject->getJobCommand()); + //} + } catch (JobResourceNotFoundException $exception){ + $this->updateJobResult($jobResultCurrent, $resultCurrentJson, $resultSignatureCurrent, $listGenericJobObject->getJobCommandName(), $listGenericJobObject->getJobCommand()); + } + } + + private function updateJobResult($jobResultCurrent, $resultCurrentJson, $resultSignatureCurrent, $jobCommandName, $jobCommand){ + $updateJobResultObject = new UpdateJobResultObject( + $resultCurrentJson, + $resultSignatureCurrent, + $jobCommandName, + $jobCommand + ); + $create = $this->updatesJobResult->execute($jobResultCurrent, $updateJobResultObject); + } +} diff --git a/app/Classes/Modules/Jobs/Services/CreatesJobResult.php b/app/Classes/Modules/Jobs/Services/CreatesJobResult.php new file mode 100644 index 00000000..e70e0e6a --- /dev/null +++ b/app/Classes/Modules/Jobs/Services/CreatesJobResult.php @@ -0,0 +1,26 @@ +job_id = $listGenericJobObject->getJobId(); + $model->request_signature = $listGenericJobObject->getRequestSignature(); + $model->result_signature = $listGenericJobObject->getResultSignature(); + $model->url = $listGenericJobObject->getName(); + + return $this->handler($model); + } +} diff --git a/app/Classes/Modules/Jobs/Services/FetchesJobResult.php b/app/Classes/Modules/Jobs/Services/FetchesJobResult.php new file mode 100644 index 00000000..1cc99cb6 --- /dev/null +++ b/app/Classes/Modules/Jobs/Services/FetchesJobResult.php @@ -0,0 +1,33 @@ +repository = $repository; + } + + + /** + * @return Builder + */ + public function getRepository(): Builder + { + return $this->repository->newQuery(); + } +} diff --git a/app/Classes/Modules/Jobs/Services/ListsJobResult.php b/app/Classes/Modules/Jobs/Services/ListsJobResult.php new file mode 100644 index 00000000..55f3b267 --- /dev/null +++ b/app/Classes/Modules/Jobs/Services/ListsJobResult.php @@ -0,0 +1,33 @@ +repository = $repository; + } + + + /** + * @return Builder + */ + function getRepository(): Builder + { + return $this->repository->newQuery(); + } +} diff --git a/app/Classes/Modules/Jobs/Services/UpdatesJobResult.php b/app/Classes/Modules/Jobs/Services/UpdatesJobResult.php new file mode 100644 index 00000000..ab3d9385 --- /dev/null +++ b/app/Classes/Modules/Jobs/Services/UpdatesJobResult.php @@ -0,0 +1,28 @@ +result = $updateJobResultObject->getResult(); + $model->result_signature = $updateJobResultObject->getResultSignature(); + $model->job_command_name = $updateJobResultObject->getJobCommandName(); + $model->job_command = $updateJobResultObject->getJobCommand(); + + return $this->handler($model); + + } +} diff --git a/app/Classes/Modules/Transactions/ControllersLogic/ListTransactionsJobLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/ListTransactionsJobLogic.php new file mode 100644 index 00000000..654a360f --- /dev/null +++ b/app/Classes/Modules/Transactions/ControllersLogic/ListTransactionsJobLogic.php @@ -0,0 +1,74 @@ + 'List Transaction Job', + 'message' => 'You have successfully submit a job to list transactions' + ]; + } + + /** @var CreatesJobResult */ + private $createsJobResult; + + /** + * ListTransactionsJobLogic constructor. + * @param CreatesJobResult $createsJobResult + */ + public function __construct(CreatesJobResult $createsJobResult) + { + $this->createsJobResult = $createsJobResult; + } + + + /** + * @param Request $request + * @return JsonResponse + */ + public function logic(Request $request) : JsonResponse + { + $jobId = uniqid(); + + $user = Auth::user(); + $userInfo = (object) [ + 'type' => $user->type, + ]; + + $userInfoJson = json_encode($userInfo); + $requestSignature = md5($userInfoJson . $request->fullUrl()); + + $listGenericJobObject = new ListGenericJobObject( + $request->fullUrl(), + $request->all(), + $requestSignature, + null, + $jobId, + $userInfo + ); + + ListTransactionsJob::dispatch($listGenericJobObject); + + $result = []; + $result['job_id'] = $jobId; + + $this->createsJobResult->execute($listGenericJobObject); + + return $this->response(['data' => $result]); + } + +} diff --git a/app/Classes/Modules/Transactions/Processors/ListTransactionsJobProcessor.php b/app/Classes/Modules/Transactions/Processors/ListTransactionsJobProcessor.php new file mode 100644 index 00000000..475d4715 --- /dev/null +++ b/app/Classes/Modules/Transactions/Processors/ListTransactionsJobProcessor.php @@ -0,0 +1,45 @@ +listsTransactions = $listsTransactions; + $this->updateJobResultProcessor = $updateJobResultProcessor; + } + + /** + * @param ListGenericJobObject $listGenericJobObject + * @return void + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\JobResourceNotFoundException + */ + public function execute(ListGenericJobObject $listGenericJobObject) { + + $query = $this->listsTransactions->execute($this->listsTransactions->deserializeFilters($listGenericJobObject->getPayload()['filters']), ['page' => $listGenericJobObject->getPayload()['page']]); + + $resultCurrent = Helper::collectionResponse(ListTransactionJobResource::collection($query)); + $this->updateJobResultProcessor->execute($listGenericJobObject, $resultCurrent); + } +} + diff --git a/app/Http/Controllers/Bookings/ListBookingsJobController.php b/app/Http/Controllers/Bookings/ListBookingsJobController.php new file mode 100644 index 00000000..9b32fc77 --- /dev/null +++ b/app/Http/Controllers/Bookings/ListBookingsJobController.php @@ -0,0 +1,22 @@ +execute($request); + } +} diff --git a/app/Http/Controllers/Documents/ListDocumentsJobController.php b/app/Http/Controllers/Documents/ListDocumentsJobController.php new file mode 100644 index 00000000..8b763085 --- /dev/null +++ b/app/Http/Controllers/Documents/ListDocumentsJobController.php @@ -0,0 +1,19 @@ +execute($request); + } +} diff --git a/app/Http/Controllers/Jobs/FetchJobResultController.php b/app/Http/Controllers/Jobs/FetchJobResultController.php new file mode 100644 index 00000000..cfef2f5c --- /dev/null +++ b/app/Http/Controllers/Jobs/FetchJobResultController.php @@ -0,0 +1,19 @@ +execute($request); + } +} diff --git a/app/Http/Controllers/Transactions/ListTransactionsJobController.php b/app/Http/Controllers/Transactions/ListTransactionsJobController.php new file mode 100644 index 00000000..fb341d5d --- /dev/null +++ b/app/Http/Controllers/Transactions/ListTransactionsJobController.php @@ -0,0 +1,21 @@ +execute($request); + } +} diff --git a/app/Http/Resources/BookingResource.php b/app/Http/Resources/BookingResource.php index f3a7881d..70fbc95c 100644 --- a/app/Http/Resources/BookingResource.php +++ b/app/Http/Resources/BookingResource.php @@ -11,11 +11,9 @@ use App\Classes\ValueObjects\Constants\TransactionType; use App\Classes\ValueObjects\Constants\DocumentType; use Carbon\Carbon; use Illuminate\Http\Resources\Json\JsonResource; -use Illuminate\Support\Facades\Log; class BookingResource extends JsonResource { - /** * Transform the resource into an array. * diff --git a/app/Http/Resources/CompanyResource.php b/app/Http/Resources/CompanyResource.php index 85ecee16..eff2bd1b 100644 --- a/app/Http/Resources/CompanyResource.php +++ b/app/Http/Resources/CompanyResource.php @@ -15,7 +15,6 @@ use App\Models\SegmentConstant; use Carbon\Carbon; use Illuminate\Http\Resources\Json\JsonResource; use Illuminate\Support\Facades\Auth; -use Illuminate\Support\Facades\Log; class CompanyResource extends JsonResource { diff --git a/app/Http/Resources/DocumentResource.php b/app/Http/Resources/DocumentResource.php index 59933a67..c0f801bb 100644 --- a/app/Http/Resources/DocumentResource.php +++ b/app/Http/Resources/DocumentResource.php @@ -3,10 +3,7 @@ namespace App\Http\Resources; use App\Models\Booking; -use App\Models\Company; -use App\Models\Document; use Carbon\Carbon; -use Illuminate\Database\Eloquent\Model; use Illuminate\Http\Resources\Json\JsonResource; class DocumentResource extends JsonResource diff --git a/app/Http/Resources/JobResultResource.php b/app/Http/Resources/JobResultResource.php new file mode 100644 index 00000000..51bc1898 --- /dev/null +++ b/app/Http/Resources/JobResultResource.php @@ -0,0 +1,22 @@ + $this->job_id, + 'result' => $this->result, + ]; + } +} diff --git a/app/Http/Resources/ListBookingJobResource.php b/app/Http/Resources/ListBookingJobResource.php new file mode 100644 index 00000000..06f8c38d --- /dev/null +++ b/app/Http/Resources/ListBookingJobResource.php @@ -0,0 +1,81 @@ +userInfo = $userInfo ?? ($resource->userInfo ?? null); + } + + /** + * Transform the resource into an array. + * + * @param \Illuminate\Http\Request $request + * @return array + * @throws \Illuminate\Contracts\Container\BindingResolutionException + */ + public function toArray($request) + { + return [ + 'id' => $this->id, + 'company' => new CompanyResource($this->company, $this->userInfo), + 'bank' => new BankResource($this->bank), + 'service' => new ServiceTypeResource($this->service), + 'marking' => $this->marking, + 'amount' => $this->fix_amount, + 'floating_amount' => floatval((App()->make(CalculatesBookingFloatingAmount::class))->execute($this->resource, $this->fix_currency_id)), + 'paid_amount' => floatval((App()->make(CalculatesBookingPayableAmount::class))->execute($this->resource, $this->fix_currency_id)) - floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)), + 'outstanding_amount' => floatval((App()->make(CalculatesBookingOutstanding::class))->execute($this->resource)) - floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)), + 'fixed_currency' => new CurrencyResource($this->fixedCurrency), + '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()), + '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()), + ], + 'status' => $this->status, + 'created_at' => Carbon::parse($this->created_at)->format('d-m-Y'), + 'created_at_with_time' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A'), + $this->mergeWhen($this->relationLoaded('transactions'), [ + 'purchase_order' => new TransactionResource($this->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first()), + 'payment_attempts' => TransactionResource::collection( + $this->transactions() + ->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION) + ->whereDate('expires_on', '>=', Carbon::now()) + ->get() + ), + 'expired_payment_attempts' => TransactionResource::collection($this->transactions()->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION)->whereDate('expires_on', '>=', Carbon::now())->where('expires_on', '>', Carbon::now()->toTimeString())->get()), + 'payment_history' => TransactionResource::collection($this->transactions()->where(function($query){ + $query->where(function($query){ + $query->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::COMPLETED, ApprovalStatus::REJECTED]); + })->orWhere(function($query){ + $query->where(function($query){ + $query->where('type', TransactionType::REFUND)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::REJECTED, ApprovalStatus::COMPLETED]); + })->orWhere(function($query){ + $query->where('type', TransactionType::CREDIT_NOTE)->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); + }); + }); + })->latest()->get()) + ]) + ]; + } +} diff --git a/app/Http/Resources/ListDocumentJobResource.php b/app/Http/Resources/ListDocumentJobResource.php new file mode 100644 index 00000000..edf549ef --- /dev/null +++ b/app/Http/Resources/ListDocumentJobResource.php @@ -0,0 +1,31 @@ + $this->id, + 'reference' => $this->reference, + 'status' => (int) $this->status, + 'document_type' => $this->document_type, + 'owner' => $this->relationLoaded('owner') ? ($this->owner instanceof Booking ? new BookingV2Resource($this->owner, $this->userInfo) : new CompanyV2Resource($this->owner, $this->userInfo)) : null, + 'files' => FileResource::collection($this->files), + 'created_at' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A') + ]; + } +} diff --git a/app/Http/Resources/ListTransactionJobResource.php b/app/Http/Resources/ListTransactionJobResource.php new file mode 100644 index 00000000..6c4c0ece --- /dev/null +++ b/app/Http/Resources/ListTransactionJobResource.php @@ -0,0 +1,54 @@ +type, [TransactionType::BILL, TransactionType::REFUND])? $this->owner->owner : $this->owner; + $days = $this->created_at->endOfDay()->addWeekdays($booking->service_id === 3 ? 3 : 1); + + return [ + 'id' => $this->id, + 'booking' => new BookingResource($booking), + 'type' => (int) $this->type, + 'bill_no' => $this->bill_no, + 'payment_reference' => $this->payment_reference, + 'payment_method' => (float) $this->payment_method, + 'recipient_bank_account' => new BankResource($booking->bank), + 'issuer_name' => $this->issuerCompany->name, + 'issuer_id' => $this->issuerCompany->id, + 'amount' => (double) $this->amount, + 'original_amount' => (double) $this->original_amount, + 'currency' => new CurrencyResource($this->currency), + 'original_currency' => new CurrencyResource($this->original_currency), + 'service_charge' => (double) $this->service_charge, + 'tax' => (double) $this->tax, + 'currency_rate' => (double) $this->currency_rate, + 'status' => (int) $this->status, + 'details' => TransactionDetailResource::collection($this->transactionDetails), + 'documents' => new DocumentResource($this->documents()->first()), + 'transaction_bill' => new TransactionResource($this->when((int) $this->type === TransactionType::PAYMENT, $this->transactions()->bills()->first())), + 'transaction_refunds' => TransactionResource::collection($this->when((int) $this->type === TransactionType::PAYMENT, $this->transactions()->refunds()->get())), + 'expires_on' => Carbon::parse($this->expires_on)->format('d-m-Y h:i:s A'), + 'updated_at' => Carbon::parse($this->updated_at)->format('d-m-Y h:i:s A'), + 'interval' => [ + 'value' => $days->gt(Carbon::now()) ? '+' : '-', + 'duration' => $days->diff(Carbon::now())->format('%d'), + ], + 'redemption' => new VoucherRedemptionResource($this->voucherRedemption) + ]; + } +} diff --git a/app/Http/Resources/V2/BookingV2Resource.php b/app/Http/Resources/V2/BookingV2Resource.php new file mode 100644 index 00000000..ee17181e --- /dev/null +++ b/app/Http/Resources/V2/BookingV2Resource.php @@ -0,0 +1,82 @@ +userInfo = $userInfo ?? ($resource->userInfo ?? null); + } + + /** + * Transform the resource into an array. + * + * @param \Illuminate\Http\Request $request + * @return array + * @throws \Illuminate\Contracts\Container\BindingResolutionException + */ + public function toArray($request) + { + return [ + 'id' => $this->id, + 'company' => new CompanyV2Resource($this->company, $this->userInfo), + 'bank' => new V1\BankResource($this->bank), + 'service' => new V1\ServiceTypeResource($this->service), + 'marking' => $this->marking, + 'amount' => $this->fix_amount, + 'floating_amount' => floatval((App()->make(CalculatesBookingFloatingAmount::class))->execute($this->resource, $this->fix_currency_id)), + 'paid_amount' => floatval((App()->make(CalculatesBookingPayableAmount::class))->execute($this->resource, $this->fix_currency_id)) - floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)), + 'outstanding_amount' => floatval((App()->make(CalculatesBookingOutstanding::class))->execute($this->resource)) - floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)), + 'fixed_currency' => new V1\CurrencyResource($this->fixedCurrency), + 'convertible_currency' => new V1\CurrencyResource($this->convertibleCurrency), + 'conversion_currency' => new V1\CurrencyResource($this->conversionCurrency), + 'documents' => [ + 'purchase_order' => new V1\DocumentResource($this->documents()->where('document_type', DocumentType::PURCHASE_ORDER)->first()), + 'delivery_order' => new V1\DocumentResource($this->documents()->where('document_type', DocumentType::DELIVER_ORDER)->first()), + 'invoice' => new V1\DocumentResource($this->documents()->where('document_type', DocumentType::INVOICE)->first()), + 'supplier_delivery_order' => new V1\DocumentResource($this->documents()->where('document_type', DocumentType::SUPPLIER_DELIVER_ORDER)->first()), + 'proforma_invoice' => new V1\DocumentResource($this->documents()->where('document_type', DocumentType::PROFORMA_INVOICE)->whereNotIn('status', [ApprovalStatus::REJECTED, ApprovalStatus::EXPIRED])->orderByDesc('id')->first()), + 'ecommerce_purchase_order' => new V1\DocumentResource($this->documents()->where('document_type', DocumentType::ECOMMERCE_PURCHASE_ORDER)->first()), + ], + 'status' => $this->status, + 'created_at' => Carbon::parse($this->created_at)->format('d-m-Y'), + 'created_at_with_time' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A'), + $this->mergeWhen($this->relationLoaded('transactions'), [ + 'purchase_order' => new V1\TransactionResource($this->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first()), + 'payment_attempts' => V1\TransactionResource::collection( + $this->transactions() + ->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION) + ->whereDate('expires_on', '>=', Carbon::now()) + ->get() + ), + 'expired_payment_attempts' => V1\TransactionResource::collection($this->transactions()->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION)->whereDate('expires_on', '>=', Carbon::now())->where('expires_on', '>', Carbon::now()->toTimeString())->get()), + 'payment_history' => V1\TransactionResource::collection($this->transactions()->where(function($query){ + $query->where(function($query){ + $query->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::COMPLETED, ApprovalStatus::REJECTED]); + })->orWhere(function($query){ + $query->where(function($query){ + $query->where('type', TransactionType::REFUND)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::REJECTED, ApprovalStatus::COMPLETED]); + })->orWhere(function($query){ + $query->where('type', TransactionType::CREDIT_NOTE)->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); + }); + }); + })->latest()->get()) + ]) + ]; + } +} diff --git a/app/Http/Resources/V2/CompanyV2Resource.php b/app/Http/Resources/V2/CompanyV2Resource.php new file mode 100644 index 00000000..64fca7c7 --- /dev/null +++ b/app/Http/Resources/V2/CompanyV2Resource.php @@ -0,0 +1,100 @@ +userInfo = $userInfo; + } + + /** + * Transform the resource into an array. + * + * @param \Illuminate\Http\Request $request + * @return array + */ + public function toArray($request) + { + $lastPayment = $this->transactions()->where('transactions.type', TransactionType::PAYMENT)->whereIn('transactions.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->orderBy('id', 'DESC')->first(); + $totalPayments = $this->transactions()->where('transactions.type', TransactionType::PAYMENT)->whereIn('transactions.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->sum('amount'); + + $segment = SegmentConstant::where('reference', SegmentConstants::SUPPLIER_CURRENCIES)->where('detail->id', $this->id)->first(); + $serviceCharge = SegmentConstant::where('reference', SegmentConstants::SERVICE_CHARGE)->where('detail->id', $this->id)->first(); + + $userResource = null; + + $userInfoEmail = $this->userInfo && isset($this->userInfo->email) ? $this->userInfo->email : null; + $userInfoType = $this->userInfo && isset($this->userInfo->type) ? $this->userInfo->type : null; + + if(!$userInfoEmail && Auth::user()){ + $userInfoEmail = Auth::user()->email; + } + if(!$userInfoType && Auth::user()){ + $userInfoType = Auth::user()->type; + } + + if(!is_null($userInfoEmail) && !is_null($userInfoType)){ + $userResource = new V1\UserResource($userInfoType === RoleTypes::USER ? $this->employees()->where('email', '=', $userInfoEmail)->first() : $this->employees()->orderBy('id', 'DESC')->first()); + } + + return [ + 'id' => $this->id, + 'name' => $this->name, + 'reference' => $this->reference, + 'debtor' => $this->debtor, + 'type' => (int) $this->type, + 'business_type' => (int) $this->business_type, + 'status' => (int) $this->status, + 'contact' => new V1\ContactResource ($this->when($this->has('contacts'), $this->contacts->first())), + 'address' => new V1\AddressResource($this->when($this->has('addresses'), $this->addresses->where('billing', true)->first())), + 'employee' => $userResource, + 'identification' => new V1\DocumentResource($this->documents->whereIn('document_type', DocumentType::IDENTIFICATION_DOCUMENTS)->first()), + 'bookings' => $this->whenLoaded('bookings', $this->bookings()->orderBy('id', 'DESC')->get(), []), + 'confirmed_bookings' => $this->bookings()->whereHas('transactions', function ($query){ + $query->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); + })->count(), + 'total_payments' => (float) $totalPayments, + 'average_spending_per_day' => (float) $totalPayments / ($this->created_at->diff(Carbon::now())->days === 0 ? 1 : $this->created_at->diff(Carbon::now())->days), + 'average_spending_per_booking' => (float) $totalPayments > 0 ? $totalPayments / $this->bookings()->whereHas('transactions', function ($query){ + $query->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); + })->count() : $totalPayments, + 'last_payment' => $lastPayment ? $lastPayment->created_at->diffForHumans() : 'No Payments', + 'personal_banks' => V1\BankResource::collection($this->banks->where('type', BankAccountType::PERSONAL)), + 'recipient_banks' => [ + 'accounts' => V1\BankResource::collection($this->banks->where('type', BankAccountType::EXTERNAL)), + 'default' => new V1\BankResource($this->banks->where('type', BankAccountType::EXTERNAL)->where('default', true)->first()) + ], + 'segments' => V1\SegmentResource::collection($this->segments), + 'seasonalSegment' => $this->whenLoaded('seasonalSegments', V1\SeasonalSegmentResource::collection($this->seasonalSegments)), + 'services' => (new FetchesCompanyServices())->getServices($this->servicesConfigurations()), + 'wallet' => $this->whenLoaded('wallets', new V1\WalletResource($this->wallets()->with('transactions')->first()), new V1\WalletResource($this->wallets()->first())), + 'created_at' => $this->created_at->format('d-m-Y'), + $this->mergeWhen($this->business_type === BusinessType::CURRENCY_VENDOR, [ + 'currencies' => $segment ? V1\CurrencyResource::collection(Currency::whereIn('id', $segment->detail->currencies)->get()) : [], + 'service_charge' => $serviceCharge + ]) + + ]; + } +} diff --git a/app/Models/JobResult.php b/app/Models/JobResult.php new file mode 100644 index 00000000..f30b5076 --- /dev/null +++ b/app/Models/JobResult.php @@ -0,0 +1,13 @@ +id(); + $table->string('job_id', 50); + $table->longText('result')->nullable(); + $table->timestamps(); + + // $table->foreign('job_id')->references('id')->on('jobs')->onDelete('cascade'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('job_results'); + } +} diff --git a/database/migrations/2023_08_29_063531_add_new_column_to_job_results_table.php b/database/migrations/2023_08_29_063531_add_new_column_to_job_results_table.php new file mode 100644 index 00000000..8e6b8342 --- /dev/null +++ b/database/migrations/2023_08_29_063531_add_new_column_to_job_results_table.php @@ -0,0 +1,36 @@ +longText('url')->after('result')->nullable(); + $table->string('job_command_name')->after('url')->nullable(); + $table->longText('job_command')->after('job_command_name')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('job_results', function (Blueprint $table) { + $table->dropColumn('url'); + $table->dropColumn('job_command_name'); + $table->dropColumn('job_command'); + }); + } +} diff --git a/database/migrations/2023_12_11_193200_add_new_column_2_to_job_results_table.php b/database/migrations/2023_12_11_193200_add_new_column_2_to_job_results_table.php new file mode 100644 index 00000000..12c6d57f --- /dev/null +++ b/database/migrations/2023_12_11_193200_add_new_column_2_to_job_results_table.php @@ -0,0 +1,34 @@ +string('request_signature')->after('job_id')->nullable(); + $table->string('result_signature')->after('request_signature')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('job_results', function (Blueprint $table) { + $table->dropColumn('request_signature'); + $table->dropColumn('result_signature'); + }); + } +} diff --git a/resources/assets/vue/components/bookings/sections/AdminPaymentsBillingSectionComponent.vue b/resources/assets/vue/components/bookings/sections/AdminPaymentsBillingSectionComponent.vue new file mode 100644 index 00000000..966ccbbc --- /dev/null +++ b/resources/assets/vue/components/bookings/sections/AdminPaymentsBillingSectionComponent.vue @@ -0,0 +1,136 @@ + + diff --git a/resources/assets/vue/components/bookings/sections/AdminPaymentsBillingSectionPollingComponent.vue b/resources/assets/vue/components/bookings/sections/AdminPaymentsBillingSectionPollingComponent.vue new file mode 100644 index 00000000..47d14857 --- /dev/null +++ b/resources/assets/vue/components/bookings/sections/AdminPaymentsBillingSectionPollingComponent.vue @@ -0,0 +1,136 @@ + + diff --git a/resources/assets/vue/components/bookings/sections/SupplierPendingOrdersSectionComponent.vue b/resources/assets/vue/components/bookings/sections/SupplierPendingOrdersSectionComponent.vue index 7df9c125..d2b69080 100644 --- a/resources/assets/vue/components/bookings/sections/SupplierPendingOrdersSectionComponent.vue +++ b/resources/assets/vue/components/bookings/sections/SupplierPendingOrdersSectionComponent.vue @@ -117,11 +117,17 @@
+ +
@@ -165,7 +171,7 @@ } }, created(){ - this.submit(route('api.company.list') + '?filters=' + JSON.stringify({'business_type': 3, 'status_in': [1, 2, 0]}), 'get', 'pendingOrdersSection', false, false) + this.submit(route('api.company.list') + '?filters=' + JSON.stringify({'business_type': 3, 'status_in': [1, 2, 0]}), 'get', 'pendingOrdersSection', false, false); //cief todo: Uncaught (in promise) null }, methods: { successHandler(response){ @@ -210,4 +216,4 @@ } - \ No newline at end of file + diff --git a/resources/assets/vue/components/general/elements/ListPollingComponent.vue b/resources/assets/vue/components/general/elements/ListPollingComponent.vue new file mode 100644 index 00000000..fcd3b8b8 --- /dev/null +++ b/resources/assets/vue/components/general/elements/ListPollingComponent.vue @@ -0,0 +1,213 @@ + + + diff --git a/resources/assets/vue/general/mixins/aws/requestV2.js b/resources/assets/vue/general/mixins/aws/requestV2.js new file mode 100644 index 00000000..12b27542 --- /dev/null +++ b/resources/assets/vue/general/mixins/aws/requestV2.js @@ -0,0 +1,49 @@ +export default { + methods: { + poll(url, method, section, successNotification = true, errorNotification = true){ + if(!this.validate()){ return; } + if (section) { + this.$store.dispatch('toggleLoading', {name: section, status: true}) + } + this.$store.dispatch('crudRequestV2', { + endpoint: url, + method: method, + parameters: this.parameters + }).then(response => { + let statusCode = response.status, + success = response.ok; + + response.json().then(response => { + + if(!success){ + this.openModal(); + errorNotification ? this.$store.dispatch('createNotification', {title: response.title, message: response.message, type: 'error'}): null; + this.errorHandler(response, statusCode); return; + } + + successNotification ? this.$store.dispatch('createNotification', {title: response.title, message: response.message, type: 'success'}): null; + this.successHandler(response) + + + }); + }).catch((error) => { + this.$store.dispatch('createNotification', {title: 'Unexpected Error', message: 'An unexpected error has occurred. Try again!', type: 'error'}); + }).then(() => { + if (section) { + this.$store.dispatch('toggleLoading', {name: section, status: false}) + } + }) + + }, + validate() { + if(this.$v){ + this.$v.$touch(); + return !this.$v.$invalid; + } + return true; + }, + successHandler(response){}, + errorHandler(response){} + } + +} diff --git a/resources/assets/vue/general/mixins/tabHandler.js b/resources/assets/vue/general/mixins/tabHandler.js new file mode 100644 index 00000000..81790ed0 --- /dev/null +++ b/resources/assets/vue/general/mixins/tabHandler.js @@ -0,0 +1,24 @@ +export default { + data() { + return { + activeTab: null, + displayedTabs: [], + }; + }, + methods: { + setActiveTab(event) { + const tabName = event.currentTarget.getAttribute('tab-name'); + // console.log(`Tab "${tabName}" clicked`); + this.activeTab = tabName; + if (!this.displayedTabs.includes(tabName)) { + this.displayedTabs.push(tabName); + } + }, + isActiveTab(tabName) { + return this.activeTab === tabName; + }, + showTabContent(tabName) { + return this.displayedTabs.includes(tabName); + }, + }, +} diff --git a/resources/assets/vue/vuex/modules/crudRequestV2.js b/resources/assets/vue/vuex/modules/crudRequestV2.js new file mode 100644 index 00000000..355b1edb --- /dev/null +++ b/resources/assets/vue/vuex/modules/crudRequestV2.js @@ -0,0 +1,51 @@ +export default { + actions: { + crudRequestV2({getters, dispatch}, {endpoint, method, parameters}){ + return dispatch('ensureReCaptchaIsSet').then(function () { + const queryDomain = endpoint.split('?')[0]; + let encodedParams = endpoint.split('?')[1]; + let decodedParams = fullyDecodeURI(encodedParams); + const queryParams = encodeURIComponent(decodedParams); + encodedParams = queryParams.toString(); + let filteredEncodedParams = encodedParams.replace(/%3D/g,'='); + filteredEncodedParams = filteredEncodedParams.replace(/%26/g,'&'); + let combinedAbsoluteUrl = queryDomain; + if(filteredEncodedParams !== undefined && filteredEncodedParams !== 'undefined'){ + combinedAbsoluteUrl = queryDomain + '?' + filteredEncodedParams; + } + + // return fetch(endpoint, { + return fetch(combinedAbsoluteUrl, { + method: method, + responseType: 'json', + body: parameters ? JSON.stringify(parameters):null, + headers: { + 'content-type': 'application/json', + 'Authorization': 'Bearer '+getters.getAccessToken, + 'captcha-token': getters.getReCaptcha + } + }).then(response => { + + if(response.status === 401 && window.location.href !== route('login')){ + dispatch('userAuthentication', {access_token: '', redirect_url: '/'}); + } + + return response; + + }) + }); + } + } +} + +function isEncoded(uri) { + uri = uri || ''; + return uri !== decodeURIComponent(uri); +} + +function fullyDecodeURI(uri){ + while (isEncoded(uri)){ + uri = decodeURIComponent(uri); + } + return uri; +} diff --git a/resources/assets/vue/vuex/store.js b/resources/assets/vue/vuex/store.js index 2c3d911b..ff10c673 100644 --- a/resources/assets/vue/vuex/store.js +++ b/resources/assets/vue/vuex/store.js @@ -4,6 +4,7 @@ import toggleSection from './modules/toggleSection' import toggleLoading from './modules/toggleLoading' import createNotification from './modules/createNotification' import crudRequest from './modules/crudRequest' +import crudRequestV2 from './modules/crudRequestV2' import authentication from './modules/authentication' import loadRequestQueue from './modules/loadRequestQueue' @@ -16,6 +17,7 @@ export default new Vuex.Store({ loadRequestQueue, createNotification, crudRequest, + crudRequestV2, authentication } -}) \ No newline at end of file +}) diff --git a/resources/views/pages/billings.blade.php b/resources/views/pages/billings.blade.php index 4bc012d5..da84f8b9 100644 --- a/resources/views/pages/billings.blade.php +++ b/resources/views/pages/billings.blade.php @@ -3,129 +3,7 @@
- -
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
Invoice
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
Purchase Order
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
Delivery Order
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
Supplier Delivery Order
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - -
-
- - - -
-
- - - -
-
- - - -
-
-
-
-
+
-@endsection \ No newline at end of file +@endsection diff --git a/resources/views/pages/billings_experiment.blade.php b/resources/views/pages/billings_experiment.blade.php new file mode 100644 index 00000000..d1caee2d --- /dev/null +++ b/resources/views/pages/billings_experiment.blade.php @@ -0,0 +1,9 @@ +@extends('layouts.base_portal') +@section('inner_content') +
+
+ + +
+
+@endsection diff --git a/routes/api.php b/routes/api.php index 8b4bada0..460bd772 100644 --- a/routes/api.php +++ b/routes/api.php @@ -67,6 +67,10 @@ Route::group(['middleware' => 'api', 'prefix' => 'v1', 'as' => 'api.'], function require __DIR__ . '/milestone.php'; + // require __DIR__ . '/accounting.php'; //cief todo: To check if this is needed + + require __DIR__ . '/job.php'; + // require __DIR__ . '/rate.php'; // require __DIR__ . '/receipt.php'; diff --git a/routes/currency.php b/routes/currency.php index b621aad6..ba55c9a2 100644 --- a/routes/currency.php +++ b/routes/currency.php @@ -1,4 +1,4 @@ - 'document', 'as' => 'document.', 'namespace' => 'Documents'], function () { Route::get('/list', 'ListDocumentsController@list')->name('list'); + Route::get('/list/job', 'ListDocumentsJobController@list')->name('list.job'); Route::delete('/{id}/delete', 'DeleteDocumentController@delete')->name('delete'); Route::put('/{id}/approve', 'ApproveDocumentController@approve')->name('status.approve'); Route::put('/{id}/reject', 'RejectDocumentController@reject')->name('status.reject'); Route::put('/{id}/reference/update', 'UpdateDocumentReferenceController@update')->name('reference.update'); -}); \ No newline at end of file +}); diff --git a/routes/job.php b/routes/job.php new file mode 100644 index 00000000..028e9468 --- /dev/null +++ b/routes/job.php @@ -0,0 +1,8 @@ + 'job', 'as' => 'job.', 'namespace' => 'Jobs'], function () { + Route::get('/fetch/{job_id}', 'FetchJobResultController@fetch')->name('fetch'); + Route::get('/fetch/{job_id}/{is_last}', 'FetchJobResultController@fetch')->name('fetch.last.attempt'); +}); diff --git a/routes/web.php b/routes/web.php index bf2892bb..a6590c17 100644 --- a/routes/web.php +++ b/routes/web.php @@ -92,6 +92,12 @@ Route::get('/billings', function () { return view('pages.billings'); })->name('billings'); +/* Vue Polling Experiment - Starts */ +Route::get('/billings-experiment', function () { + return view('pages.billings_experiment'); +})->name('billings.experiment'); +/* Vue Polling Experiment - Ends */ + Route::get('/currency_orders', function () { return view('pages.currency_orders'); })->name('currency_orders'); @@ -830,13 +836,13 @@ Route::get('/invoice/{marking}/{started_at}/{ended_at}/fix', function($marking, ->withTrashed() ->orderBy('created_at', 'asc') ->first(); - + // get the first bill_no $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(); $currentInvoice->bill_no = $currentInvoice->bill_no ."-deleted-" . Str::random(10); @@ -859,4 +865,4 @@ Route::get('/invoice/{marking}/{started_at}/{ended_at}/fix', function($marking, } } ); -})->name('invoice.fix.byCustomerMarking'); \ No newline at end of file +})->name('invoice.fix.byCustomerMarking'); From f08343439052ff23e122217e123cd3d314b5a7f6 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Fri, 16 Feb 2024 14:59:11 +0800 Subject: [PATCH 103/434] update refund ui and logic --- .../CreateBookingPaymentLogic.php | 10 +- .../CreateBookingRefundLogic.php | 8 +- .../ControllersLogic/FetchBookingLogic.php | 2 +- .../FetchBookingPaymentQuotationLogic.php | 9 +- .../CalculatesBookingRefundAmount.php | 27 ++- .../UpdateRefundTransactionStatusLogic.php | 21 ++- app/Http/Resources/BookingResource.php | 4 +- app/Http/Resources/TransactionResource.php | 1 + .../elements/PaymentHistoryComponent.vue | 105 ++++++++---- .../elements/RefundConfirmationComponent.vue | 157 ++++++++---------- .../elements/RefundVerificationComponent.vue | 2 +- .../forms/PurchaseOrderFormComponent.vue | 6 +- routes/transaction.php | 2 +- 13 files changed, 208 insertions(+), 146 deletions(-) diff --git a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php index c429d91d..ab654675 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php @@ -19,6 +19,7 @@ use App\Classes\ValueObjects\Constants\PaymentMethodType; use App\Classes\ValueObjects\Constants\TransactionType; use App\Classes\Modules\Currencies\DataTransferObjects\CurrencyConversionObject; use App\Http\Resources\TransactionResource; +use App\Classes\Modules\Bookings\Services\CalculatesBookingRefundAmount; use App\Classes\Modules\Transactions\Processors\CreateCashBackTransactionProcessor; use App\Classes\Modules\Vouchers\Processors\Voucherify\BookingToVoucherifyProcessor; @@ -77,6 +78,9 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic /** @var BookingToVoucherifyProcessor */ private $bookingToVoucherifyProcessor; + /** @var CalculatesBookingRefundAmount */ + private $calculatesBookingRefundAmount; + /** * CreateBookingPaymentLogic constructor. * @param FetchesBookingQuotation $fetchBookingQuotation @@ -90,8 +94,9 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic * @param CreateCashBackTransactionProcessor $createCashBackTransactionProcessor * @param RecalculatesWalletBalance $recalculatesWalletBalance * @param BookingToVoucherifyProcessor $bookingToVoucherifyProcessor + * @param CalculatesBookingRefundAmount $calculatesBookingRefundAmount */ - public function __construct(FetchesBookingQuotation $fetchBookingQuotation, FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatesTransaction $createsTransaction, CalculatesBookingOutstanding $calculatesBookingOutstanding, CreatesBillplzBill $createsBillplzBill, UpdatesWalletBalance $updatesWalletBalance, UpdatesTransactionStatus $updatesTransactionStatus, CreateCashBackTransactionProcessor $createCashBackTransactionProcessor, RecalculatesWalletBalance $recalculatesWalletBalance, BookingToVoucherifyProcessor $bookingToVoucherifyProcessor) + public function __construct(FetchesBookingQuotation $fetchBookingQuotation, FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatesTransaction $createsTransaction, CalculatesBookingOutstanding $calculatesBookingOutstanding, CreatesBillplzBill $createsBillplzBill, UpdatesWalletBalance $updatesWalletBalance, UpdatesTransactionStatus $updatesTransactionStatus, CreateCashBackTransactionProcessor $createCashBackTransactionProcessor, RecalculatesWalletBalance $recalculatesWalletBalance, BookingToVoucherifyProcessor $bookingToVoucherifyProcessor, CalculatesBookingRefundAmount $calculatesBookingRefundAmount) { $this->fetchBookingQuotation = $fetchBookingQuotation; $this->fetchesCompanyPaymentAttemptLimit = $fetchesCompanyPaymentAttemptLimit; @@ -104,6 +109,7 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic $this->createCashBackTransactionProcessor = $createCashBackTransactionProcessor; $this->recalculatesWalletBalance = $recalculatesWalletBalance; $this->bookingToVoucherifyProcessor = $bookingToVoucherifyProcessor; + $this->calculatesBookingRefundAmount = $calculatesBookingRefundAmount; } /** @@ -119,7 +125,7 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic $conversionObject = new CurrencyConversionObject(floatval(str_replace(',', '', $request->input('amount'))), $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')]); - $outstanding = $this->calculatesBookingOutstanding->execute($booking); + $outstanding = $this->calculatesBookingOutstanding->execute($booking) + $this->calculatesBookingRefundAmount->execute($booking, $booking->fix_currency_id); if($conversionObject->getAmount() > round($outstanding, 2)) throw new MalformedRequestException('Your payment must not be greater than '. $outstanding .'.'); diff --git a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php index 7455e689..0648629e 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php @@ -15,7 +15,6 @@ use App\Classes\Modules\Transactions\Services\CreatesTransaction; use App\Classes\Modules\Transactions\Services\FetchesTransaction; use App\Classes\Modules\Bookings\Services\FetchesBookingQuotation; use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus; -use App\Classes\Modules\Bookings\Services\CalculatesBookingRefundAmount; use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject; use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber; use App\Classes\Modules\Transactions\DataTransferObjects\TransactionRefundCalculationObject; @@ -49,9 +48,6 @@ class CreateBookingRefundLogic extends AbstractControllerLogic /** @var CreatesTransaction */ private $createsTransaction; - /** @var CalculatesBookingRefundAmount */ - private $calculatesBookingRefundAmount; - /** * CreateBookingPaymentLogic constructor. * @param FetchesBookingQuotation $fetchBookingQuotation @@ -59,16 +55,14 @@ class CreateBookingRefundLogic extends AbstractControllerLogic * @param UpdatesTransactionStatus $updatesTransactionStatus * @param GeneratesTransactionBillNumber $generatesTransactionBillNumber * @param CreatesTransaction $createsTransaction - * @param CalculatesBookingRefundAmount $calculatesBookingRefundAmount */ - public function __construct(FetchesBookingQuotation $fetchBookingQuotation, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatesTransaction $createsTransaction, CalculatesBookingRefundAmount $calculatesBookingRefundAmount) + public function __construct(FetchesBookingQuotation $fetchBookingQuotation, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatesTransaction $createsTransaction) { $this->fetchBookingQuotation = $fetchBookingQuotation; $this->fetchesTransaction = $fetchesTransaction; $this->updatesTransactionStatus = $updatesTransactionStatus; $this->generatesTransactionBillNumber = $generatesTransactionBillNumber; $this->createsTransaction = $createsTransaction; - $this->calculatesBookingRefundAmount = $calculatesBookingRefundAmount; } /** diff --git a/app/Classes/Modules/Bookings/ControllersLogic/FetchBookingLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/FetchBookingLogic.php index d9857548..d1f2286e 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/FetchBookingLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/FetchBookingLogic.php @@ -18,7 +18,7 @@ class FetchBookingLogic extends AbstractControllerLogic */ protected function notification():array { return [ - 'title' => 'Retrieved Address', + 'title' => 'Retrieved Booking', 'message' => 'You have successfully retrieved a Address' ]; } diff --git a/app/Classes/Modules/Bookings/ControllersLogic/FetchBookingPaymentQuotationLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/FetchBookingPaymentQuotationLogic.php index 8effdb2f..e9a42101 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/FetchBookingPaymentQuotationLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/FetchBookingPaymentQuotationLogic.php @@ -14,6 +14,7 @@ use App\Classes\ValueObjects\Constants\PaymentMethodType; use App\Models\Booking; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; +use App\Classes\Modules\Bookings\Services\CalculatesBookingRefundAmount; class FetchBookingPaymentQuotationLogic extends AbstractControllerLogic { @@ -40,6 +41,9 @@ class FetchBookingPaymentQuotationLogic extends AbstractControllerLogic /** @var CalculatesBookingOutstanding */ private $calculatesBookingOutstanding; + /** @var CalculatesBookingRefundAmount */ + private $calculatesBookingRefundAmount; + /** * FetchBookingPaymentQuotationLogic constructor. * @param FetchesBookingQuotation $fetchBookingQuotation @@ -47,12 +51,13 @@ class FetchBookingPaymentQuotationLogic extends AbstractControllerLogic * @param FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit * @param CalculatesBookingOutstanding $calculatesBookingOutstanding */ - public function __construct(FetchesBookingQuotation $fetchBookingQuotation, GeneratesBookingQuotation $generatesBookingQuotation, FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit, CalculatesBookingOutstanding $calculatesBookingOutstanding) + public function __construct(FetchesBookingQuotation $fetchBookingQuotation, GeneratesBookingQuotation $generatesBookingQuotation, FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit, CalculatesBookingOutstanding $calculatesBookingOutstanding, CalculatesBookingRefundAmount $calculatesBookingRefundAmount) { $this->fetchBookingQuotation = $fetchBookingQuotation; $this->generatesBookingQuotation = $generatesBookingQuotation; $this->fetchesCompanyPaymentAttemptLimit = $fetchesCompanyPaymentAttemptLimit; $this->calculatesBookingOutstanding = $calculatesBookingOutstanding; + $this->calculatesBookingRefundAmount = $calculatesBookingRefundAmount; } /** @@ -66,7 +71,7 @@ class FetchBookingPaymentQuotationLogic extends AbstractControllerLogic $conversionObject = new CurrencyConversionObject(floatval(str_replace(',', '', $request->input('amount'))), $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')]); - $outstanding = $this->calculatesBookingOutstanding->execute($booking); + $outstanding = $this->calculatesBookingOutstanding->execute($booking) + $this->calculatesBookingRefundAmount->execute($booking, $booking->fix_currency_id); if($conversionObject->getAmount() > round($outstanding, 2)) throw new MalformedRequestException('Your payment must not be greater than '.$booking->fixedCurrency->short_code.' '. number_format((float)$outstanding, 2, '.', ',')); //Voucherify diff --git a/app/Classes/Modules/Bookings/Services/CalculatesBookingRefundAmount.php b/app/Classes/Modules/Bookings/Services/CalculatesBookingRefundAmount.php index 14a4a9ef..f6dab1f4 100644 --- a/app/Classes/Modules/Bookings/Services/CalculatesBookingRefundAmount.php +++ b/app/Classes/Modules/Bookings/Services/CalculatesBookingRefundAmount.php @@ -2,19 +2,30 @@ namespace App\Classes\Modules\Bookings\Services; - use App\Classes\ValueObjects\Constants\ApprovalStatus; -use App\Classes\ValueObjects\Constants\TransactionType; use App\Models\Booking; -use Carbon\Carbon; class CalculatesBookingRefundAmount { + public function execute(Booking $booking, int $type, ?string $payment_reference = null): float + { + $refundAmounts = $booking->transactions()->payments()->get()->map(function ($payment) use ($type) { + return $this->calculateRefundAmount($payment, $type); + }); - public function execute(Booking $booking, int $type, ?string $payment_reference = NULL){ - return $type === 1 ? - $booking->transactions()->refunds($payment_reference) - ->selectRaw('sum(amount - service_charge - tax) as sub_total')->get()->sum('sub_total') : $booking->transactions()->refunds($payment_reference)->sum('original_amount'); + $totalRefundAmount = $refundAmounts->sum(); + + return $totalRefundAmount; } -} \ No newline at end of file + private function calculateRefundAmount($payment, int $type): float + { + $refundTransactions = $payment->transactions()->refunds()->whereIn('status', [ApprovalStatus::APPROVED]); + + if ($type === 1) { + return $refundTransactions->selectRaw('sum(amount - service_charge - tax) as sub_total')->get()->sum('sub_total'); + } + + return $refundTransactions->sum('original_amount'); + } +} diff --git a/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php index bf704359..04fa5e6a 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php @@ -13,6 +13,8 @@ use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use App\Classes\Modules\Wallets\Processors\CreditWalletProcessor; +use App\Classes\Modules\Bookings\Services\CalculatesBookingPayableAmount; +use App\Classes\Modules\Bookings\Services\CalculatesBookingRefundAmount; class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic @@ -43,6 +45,12 @@ class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic /** @var CreditWalletProcessor */ private $creditWalletProcessor; + /** @var CalculatesBookingPayableAmount */ + private $calculatesBookingPayableAmount; + + /** @var CalculatesBookingRefundAmount */ + private $calculatesBookingRefundAmount; + /** * CreatePaymentVerificationDocumentLogic constructor. * @param FetchesCompany $fetchesCompany @@ -50,14 +58,18 @@ class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic * @param UpdatesTransactionStatus $updatesTransactionStatus * @param DeletesDocument $deletesDocument * @param CreditWalletProcessor $creditWalletProcessor + * @param CalculatesBookingPayableAmount $calculatesBookingPayableAmount + * @param CalculatesBookingRefundAmount $calculatesBookingRefundAmount */ - public function __construct(FetchesCompany $fetchesCompany, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, DeletesDocument $deletesDocument, CreditWalletProcessor $creditWalletProcessor) + public function __construct(FetchesCompany $fetchesCompany, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, DeletesDocument $deletesDocument, CreditWalletProcessor $creditWalletProcessor, CalculatesBookingPayableAmount $calculatesBookingPayableAmount, CalculatesBookingRefundAmount $calculatesBookingRefundAmount) { $this->fetchesCompany = $fetchesCompany; $this->fetchesTransaction = $fetchesTransaction; $this->updatesTransactionStatus = $updatesTransactionStatus; $this->deletesDocument = $deletesDocument; $this->creditWalletProcessor = $creditWalletProcessor; + $this->calculatesBookingPayableAmount = $calculatesBookingPayableAmount; + $this->calculatesBookingRefundAmount = $calculatesBookingRefundAmount; } /** @@ -69,7 +81,7 @@ class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic { $transaction = $this->fetchesTransaction->execute(['id' => $request->route('id')]); - $transaction = $this->updatesTransactionStatus->execute($transaction, $request->input('status')); + $transaction = $this->updatesTransactionStatus->execute($transaction, $request->route('status')); $booking = $transaction->owner->owner; @@ -81,7 +93,10 @@ class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic $this->creditWalletProcessor->execute($booking->company, $transaction->type, $transaction->amount, $reference); } - + $paidAmount = $this->calculatesBookingPayableAmount->execute($booking, $booking->fix_currency_id) - $this->calculatesBookingRefundAmount->execute($booking, $booking->fix_currency_id); + if (!$paidAmount > 0) { + $this->updatesTransactionStatus->execute($paymentTransaction, ApprovalStatus::REFUNDED); + } return $this->response([]); } diff --git a/app/Http/Resources/BookingResource.php b/app/Http/Resources/BookingResource.php index f3a7881d..ea3278c4 100644 --- a/app/Http/Resources/BookingResource.php +++ b/app/Http/Resources/BookingResource.php @@ -34,7 +34,7 @@ class BookingResource extends JsonResource 'amount' => $this->fix_amount, 'floating_amount' => floatval((App()->make(CalculatesBookingFloatingAmount::class))->execute($this->resource, $this->fix_currency_id)), 'paid_amount' => floatval((App()->make(CalculatesBookingPayableAmount::class))->execute($this->resource, $this->fix_currency_id)) - floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)), - 'outstanding_amount' => floatval((App()->make(CalculatesBookingOutstanding::class))->execute($this->resource)) - floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)), + 'outstanding_amount' => floatval((App()->make(CalculatesBookingOutstanding::class))->execute($this->resource)) + floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)), 'fixed_currency' => new CurrencyResource($this->fixedCurrency), 'convertible_currency' => new CurrencyResource($this->convertibleCurrency), 'conversion_currency' => new CurrencyResource($this->conversionCurrency), @@ -60,7 +60,7 @@ class BookingResource extends JsonResource 'expired_payment_attempts' => TransactionResource::collection($this->transactions()->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION)->whereDate('expires_on', '>=', Carbon::now())->where('expires_on', '>', Carbon::now()->toTimeString())->get()), 'payment_history' => TransactionResource::collection($this->transactions()->where(function($query){ $query->where(function($query){ - $query->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::COMPLETED, ApprovalStatus::REJECTED]); + $query->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::COMPLETED, ApprovalStatus::REJECTED, ApprovalStatus::REFUNDED]); })->orWhere(function($query){ $query->where(function($query){ $query->where('type', TransactionType::REFUND)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::REJECTED, ApprovalStatus::COMPLETED]); diff --git a/app/Http/Resources/TransactionResource.php b/app/Http/Resources/TransactionResource.php index 27fd17ab..9e743042 100644 --- a/app/Http/Resources/TransactionResource.php +++ b/app/Http/Resources/TransactionResource.php @@ -45,6 +45,7 @@ class TransactionResource extends JsonResource 'transaction_refunds' => TransactionResource::collection($this->when((int) $this->type === TransactionType::PAYMENT, $this->transactions()->refunds()->get())), 'expires_on' => Carbon::parse($this->expires_on)->format('d-m-Y h:i:s A'), 'updated_at' => Carbon::parse($this->updated_at)->format('d-m-Y h:i:s A'), + 'created_at' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A'), 'interval' => [ 'value' => $days->gt(Carbon::now()) ? '+' : '-', 'duration' => $days->diff(Carbon::now())->format('%d'), diff --git a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue index 43e2e96d..00d51f06 100644 --- a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue +++ b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue @@ -4,12 +4,12 @@
-
+
Status
-
- {{ item.status === 1 ? 'Pending Verification' : item.status === 4 ? 'Rejected' : 'Processing Payment'}} +
+ {{ item.status === 7 ? 'Refunded' : (item.status === 1 ? 'Processing Payment' : 'Transferred')}}
{{ item.status === 1 ? 'Pending Verification' : item.status === 4 ? 'Rejected' : 'Processing Payment'}} @@ -39,7 +39,7 @@
-
+
@@ -147,13 +147,13 @@
Refunded Amount
-
{{item.original_currency.short_code}} {{(Math.round((totalRefunds + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
+
{{item.original_currency.short_code}} {{(Math.round((totalRefunds + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
-
{{item.currency.short_code}} {{(Math.round((totalConvertRefunds + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
+
{{item.currency.short_code}} {{(Math.round((totalConvertRefunds + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
@@ -292,7 +292,7 @@
-
+
@@ -301,42 +301,83 @@
- +
-
-
-
-
{{ index + 1 }}. Refund updated on
+
+
+
+
Created At
+
+ {{ refund.created_at }} +
+
+
+
Status
+
+
{{ refund.status === 1 ? 'Pending Verification' : refund.status === 2 ? 'Approved' : 'Rejected'}}
+
+
+
+
Amount
+
+
{{refund.currency.short_code}} {{(Math.round((refund.amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
+
-
{{ refund.updated_at }}
+
Amount
+
+
{{refund.original_currency.short_code}} {{(Math.round((refund.original_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
+
-
+
-
    Refund status
-
-
-
{{ refund.status === 1 ? 'Pending Verification' : refund.status === 2 ? 'Approved' : 'Rejected'}}
-
-
-
-
-
    Requested Refund Amount
-
-
-
{{refund.original_currency.short_code}} {{(Math.round((refund.original_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
-
-
-
-
-
-
{{refund.currency.short_code}} {{(Math.round((refund.amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
+ + + + + + + + + + +
diff --git a/resources/assets/vue/components/bookings/elements/RefundConfirmationComponent.vue b/resources/assets/vue/components/bookings/elements/RefundConfirmationComponent.vue index de2cd48f..ec5f1ac6 100644 --- a/resources/assets/vue/components/bookings/elements/RefundConfirmationComponent.vue +++ b/resources/assets/vue/components/bookings/elements/RefundConfirmationComponent.vue @@ -3,64 +3,42 @@
-
-
-
Request Refund
+
Request Refund
+
+
+
+
+
Refund Type:
+
+
+ {{ method.name }}
-
+
-
+ + + + +
+
+
-
-
-
-
-
-
-
-
-
Refund Type:
-
-
- Full Refund -
-
- Partial Refund -
-
-
-
-
-
- - - - -
-
-
-
-
{{data.booking.fixed_currency.short_code}}
-
-
-
-
-
-
-
-
-
-
+
{{ data.booking.fixed_currency.short_code }}
- +
@@ -71,47 +49,54 @@ \ No newline at end of file + }, + mixins: [FormHandler, ModalFormHandler] +} + diff --git a/resources/assets/vue/components/bookings/elements/RefundVerificationComponent.vue b/resources/assets/vue/components/bookings/elements/RefundVerificationComponent.vue index 42d5682e..24ec68a6 100644 --- a/resources/assets/vue/components/bookings/elements/RefundVerificationComponent.vue +++ b/resources/assets/vue/components/bookings/elements/RefundVerificationComponent.vue @@ -115,7 +115,7 @@ approveRefund(status){ this.isLoading = true; this.parameters.status = status; - this.submit(this.route('api.transaction.refund.status.update', this.data.id), 'put', 'listRefundTransactionSection', true, true); + this.submit(this.route('api.transaction.refund.status.update', this.data.id, status), 'put', 'listRefundTransactionSection', true, true); }, }, mixins: [componentHandler, staticFormHandler] diff --git a/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue b/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue index 9a1bf774..9b8045f9 100644 --- a/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue +++ b/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue @@ -240,7 +240,11 @@ }, watch: { 'data': function () { - this.products = this.data.purchase_order.details + if (this.data && this.data.purchase_order && this.data.purchase_order.details) { + this.products = this.data.purchase_order.details; + } else { + this.products = []; + } } }, methods: { diff --git a/routes/transaction.php b/routes/transaction.php index e714d6b7..f2f4a630 100644 --- a/routes/transaction.php +++ b/routes/transaction.php @@ -11,7 +11,7 @@ Route::group(['prefix' => 'transactions', 'namespace' => 'Transactions', 'as' => route::post('{id}/bill/verification', 'CreatePaymentProofDocumentController@verify')->name('bill.verification'); route::post('{id}/bill/pay', 'CreatePaymentProofDocumentController@pay')->name('bill.pay'); Route::put('/{id}/bill/{status}', 'UpdatePaymentTransactionStatusController@update')->where('status', 'pending|complete')->name('bill.status'); - Route::put('/{id}/refund/status/update', 'UpdateRefundTransactionStatusController@update')->name('refund.status.update'); + Route::put('/{id}/refund/status/update/{status}', 'UpdateRefundTransactionStatusController@update')->name('refund.status.update'); route::delete('{id}/bill/delete', 'DeletePaymentProofDocumentController@delete')->name('bill.delete'); From 609b71f549e5062640d464b673bce6842f2603b6 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Mon, 19 Feb 2024 00:57:42 +0800 Subject: [PATCH 104/434] code upfate for refund booking --- .../Services/CalculatesBookingRefundAmount.php | 2 +- .../UpdateRefundTransactionStatusLogic.php | 14 +++++++------- app/Http/Resources/TransactionResource.php | 2 ++ .../elements/PaymentHistoryComponent.vue | 2 +- .../elements/RefundConfirmationComponent.vue | 16 +++++++++++++--- 5 files changed, 24 insertions(+), 12 deletions(-) diff --git a/app/Classes/Modules/Bookings/Services/CalculatesBookingRefundAmount.php b/app/Classes/Modules/Bookings/Services/CalculatesBookingRefundAmount.php index f6dab1f4..239545af 100644 --- a/app/Classes/Modules/Bookings/Services/CalculatesBookingRefundAmount.php +++ b/app/Classes/Modules/Bookings/Services/CalculatesBookingRefundAmount.php @@ -18,7 +18,7 @@ class CalculatesBookingRefundAmount return $totalRefundAmount; } - private function calculateRefundAmount($payment, int $type): float + public function calculateRefundAmount($payment, int $type): float { $refundTransactions = $payment->transactions()->refunds()->whereIn('status', [ApprovalStatus::APPROVED]); diff --git a/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php index 04fa5e6a..d0e5802a 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php @@ -79,18 +79,18 @@ class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic */ public function logic(Request $request) : JsonResponse { - $transaction = $this->fetchesTransaction->execute(['id' => $request->route('id')]); + $refundTransaction = $this->fetchesTransaction->execute(['id' => $request->route('id')]); - $transaction = $this->updatesTransactionStatus->execute($transaction, $request->route('status')); + $refundTransaction = $this->updatesTransactionStatus->execute($refundTransaction, $request->route('status')); - $booking = $transaction->owner->owner; + $paymentTransaction = $refundTransaction->owner; - $paymentTransaction = $transaction->owner; + $booking = $paymentTransaction->owner; - $reference = $transaction->amount == $paymentTransaction->amount ? 'Fully Refund for Ref. ' . $booking->marking : 'Partially Refund for Ref. ' . $booking->marking; + $reference = $refundTransaction->amount == $paymentTransaction->amount ? 'Fully Refund for Ref. ' . $booking->marking : 'Partially Refund for Ref. ' . $booking->marking; - if ($transaction->status == ApprovalStatus::APPROVED) { - $this->creditWalletProcessor->execute($booking->company, $transaction->type, $transaction->amount, $reference); + if ($refundTransaction->status == ApprovalStatus::APPROVED) { + $this->creditWalletProcessor->execute($booking->company, $refundTransaction->type, $refundTransaction->amount, $reference); } $paidAmount = $this->calculatesBookingPayableAmount->execute($booking, $booking->fix_currency_id) - $this->calculatesBookingRefundAmount->execute($booking, $booking->fix_currency_id); diff --git a/app/Http/Resources/TransactionResource.php b/app/Http/Resources/TransactionResource.php index 9e743042..09967f4c 100644 --- a/app/Http/Resources/TransactionResource.php +++ b/app/Http/Resources/TransactionResource.php @@ -2,6 +2,7 @@ namespace App\Http\Resources; +use App\Classes\Modules\Bookings\Services\CalculatesBookingRefundAmount; use App\Classes\ValueObjects\Constants\TransactionType; use App\Models\Booking; use Carbon\Carbon; @@ -43,6 +44,7 @@ class TransactionResource extends JsonResource 'documents' => new DocumentResource($this->documents()->first()), 'transaction_bill' => new TransactionResource($this->when((int) $this->type === TransactionType::PAYMENT, $this->transactions()->bills()->first())), 'transaction_refunds' => TransactionResource::collection($this->when((int) $this->type === TransactionType::PAYMENT, $this->transactions()->refunds()->get())), + 'refunded_amount' => $this->booking ? floatval((App()->make(CalculatesBookingRefundAmount::class))->calculateRefundAmount($this->resource, $this->booking->fix_currency_id)) : null, 'expires_on' => Carbon::parse($this->expires_on)->format('d-m-Y h:i:s A'), 'updated_at' => Carbon::parse($this->updated_at)->format('d-m-Y h:i:s A'), 'created_at' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A'), diff --git a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue index 00d51f06..877ec248 100644 --- a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue +++ b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue @@ -291,7 +291,7 @@
-
+
diff --git a/resources/assets/vue/components/bookings/elements/RefundConfirmationComponent.vue b/resources/assets/vue/components/bookings/elements/RefundConfirmationComponent.vue index ec5f1ac6..75253aaa 100644 --- a/resources/assets/vue/components/bookings/elements/RefundConfirmationComponent.vue +++ b/resources/assets/vue/components/bookings/elements/RefundConfirmationComponent.vue @@ -35,13 +35,20 @@
+
+
+
Paid Amount: {{ paidAmount }}
+
Refund Amount: {{ refundAmount }}
+
+
- +
@@ -78,11 +85,15 @@ export default { }, computed: { refundAmount() { - return (Math.round((this.data.booking.amount - this.totalRefunds + Number.EPSILON) * 100) / 100).toFixed(2); + // return (Math.round((this.data.booking.amount - this.totalRefunds + Number.EPSILON) * 100) / 100).toFixed(2); + return (Math.round((this.data.original_amount - this.data.refunded_amount + Number.EPSILON) * 100) / 100).toFixed(2); }, refundMaxValue() { return this.refundAmount; }, + paidAmount() { + return this.data.original_amount; + }, }, methods: { submitForm() { @@ -94,7 +105,6 @@ export default { if (this.refundMethod.name === 'Fully Refund') { this.refundAmount = this.refundMaxValue; } - console.log(this.refundAmount); }, }, mixins: [FormHandler, ModalFormHandler] From 9e3c34eb7383e9c2bb6855487e336bfe9de34bc6 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Tue, 20 Feb 2024 22:41:28 +0800 Subject: [PATCH 105/434] change payment status when it has been fully refunded --- .../ControllersLogic/UpdateRefundTransactionStatusLogic.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php index d0e5802a..09e4b102 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php @@ -93,7 +93,7 @@ class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic $this->creditWalletProcessor->execute($booking->company, $refundTransaction->type, $refundTransaction->amount, $reference); } - $paidAmount = $this->calculatesBookingPayableAmount->execute($booking, $booking->fix_currency_id) - $this->calculatesBookingRefundAmount->execute($booking, $booking->fix_currency_id); + $paidAmount = $paymentTransaction->original_amount - $this->calculatesBookingRefundAmount->calculateRefundAmount($paymentTransaction, $booking->fix_currency_id); if (!$paidAmount > 0) { $this->updatesTransactionStatus->execute($paymentTransaction, ApprovalStatus::REFUNDED); } From 9aa75630ff3dbff177816678db84d5609b5a4099 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Wed, 21 Feb 2024 00:20:45 +0800 Subject: [PATCH 106/434] update code for refund booking --- app/Http/Resources/BookingResource.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Http/Resources/BookingResource.php b/app/Http/Resources/BookingResource.php index 04204a37..6803eec9 100644 --- a/app/Http/Resources/BookingResource.php +++ b/app/Http/Resources/BookingResource.php @@ -32,7 +32,8 @@ class BookingResource extends JsonResource 'amount' => $this->fix_amount, 'floating_amount' => floatval((App()->make(CalculatesBookingFloatingAmount::class))->execute($this->resource, $this->fix_currency_id)), 'paid_amount' => floatval((App()->make(CalculatesBookingPayableAmount::class))->execute($this->resource, $this->fix_currency_id)) - floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)), - 'outstanding_amount' => floatval((App()->make(CalculatesBookingOutstanding::class))->execute($this->resource)) + floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)), + // 'outstanding_amount' => floatval((App()->make(CalculatesBookingOutstanding::class))->execute($this->resource)) + floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)), + 'outstanding_amount' => floatval((App()->make(CalculatesBookingOutstanding::class))->execute($this->resource)), 'fixed_currency' => new CurrencyResource($this->fixedCurrency), 'convertible_currency' => new CurrencyResource($this->convertibleCurrency), 'conversion_currency' => new CurrencyResource($this->conversionCurrency), From df17a8497ddc98fcc7ca39ffd1b2bdbd45b0e811 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Wed, 21 Feb 2024 00:33:08 +0800 Subject: [PATCH 107/434] comment partial refund function --- .../ControllersLogic/CreateSupplierTransactionLogic.php | 1 + .../sections/SupplierPendingOrdersSectionComponent.vue | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/Classes/Modules/Transactions/ControllersLogic/CreateSupplierTransactionLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/CreateSupplierTransactionLogic.php index fb324267..4c407cf5 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/CreateSupplierTransactionLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/CreateSupplierTransactionLogic.php @@ -82,6 +82,7 @@ class CreateSupplierTransactionLogic extends AbstractControllerLogic $payments = $request->input('payments'); + // todo-refund: activate this for partial refund foreach($payments as $payment){ $payment = $this->fetchesTransaction->execute(['id' => $payment['id']]); diff --git a/resources/assets/vue/components/bookings/sections/SupplierPendingOrdersSectionComponent.vue b/resources/assets/vue/components/bookings/sections/SupplierPendingOrdersSectionComponent.vue index aee9ab40..fa345d58 100644 --- a/resources/assets/vue/components/bookings/sections/SupplierPendingOrdersSectionComponent.vue +++ b/resources/assets/vue/components/bookings/sections/SupplierPendingOrdersSectionComponent.vue @@ -200,7 +200,9 @@ }, updateList(){ - this.$refs.pendingOrdersList.updateFilters({per_page: 10000, status: 2, type: 1, is_not_fully_refunded: true, original_currency_id_in: [this.selectedCurrency.id], transaction_service_id: this.selectedService.id}); + // todo-refund: activate this for partial refund + // this.$refs.pendingOrdersList.updateFilters({per_page: 10000, status: 2, type: 1, original_currency_id_in: [this.selectedCurrency.id], transaction_service_id: this.selectedService.id, is_not_fully_refunded: true}); + this.$refs.pendingOrdersList.updateFilters({per_page: 10000, status: 2, type: 1, original_currency_id_in: [this.selectedCurrency.id], transaction_service_id: this.selectedService.id}); this.selectedSupplier.status = false; this.currencyDropdownLaunch.status = false; From 25de31ea2e2bb0e653f5ad7091a635ce043d18c3 Mon Sep 17 00:00:00 2001 From: Sai0224 Date: Sat, 24 Feb 2024 12:15:26 +0800 Subject: [PATCH 108/434] supplier bill payment refund module --- .../Eloquent/Filters/BelongsToSupplierId.php | 24 ++++++ ...CreateBillGroupPaymentTransactionLogic.php | 6 ++ .../CreateSupplierBillGroupLogic.php | 57 ++++++++++++- .../ControllersLogic/DeleteBillGroupLogic.php | 17 +++- .../CalculatesBillGroupPaymentAmount.php | 4 +- .../Constants/TransactionType.php | 5 ++ .../ExpiredRefundedBookingCommand.php | 16 ++++ app/Http/Resources/BillGroupResource.php | 19 +++++ app/Http/Resources/TransactionResource.php | 7 +- app/Models/BillGroup.php | 8 ++ app/Models/BillGroupRefund.php | 27 +++++++ app/Models/Transaction.php | 14 ++++ ...222130_create_bill_group_refunds_table.php | 22 +++++ .../bookings/elements/BillGroupComponent.vue | 36 +++++++++ .../BillGroupPaymentSummaryComponent.vue | 13 ++- .../elements/SupplierRefundComponent.vue | 80 +++++++++++++++++++ .../TransactionGroupPaymentComponent.vue | 8 -- ...pplierWhiteFormPlaceOrderFormComponent.vue | 58 +++++++++++++- 18 files changed, 403 insertions(+), 18 deletions(-) create mode 100644 app/Classes/General/Eloquent/Filters/BelongsToSupplierId.php create mode 100644 app/Models/BillGroupRefund.php create mode 100644 database/migrations/2024_02_22_222130_create_bill_group_refunds_table.php create mode 100644 resources/assets/vue/components/bookings/elements/SupplierRefundComponent.vue diff --git a/app/Classes/General/Eloquent/Filters/BelongsToSupplierId.php b/app/Classes/General/Eloquent/Filters/BelongsToSupplierId.php new file mode 100644 index 00000000..63536412 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/BelongsToSupplierId.php @@ -0,0 +1,24 @@ +whereHas('owner', function ($q) use ($value) { + $q->whereHas('transactions', function ($q2) use ($value) { + $q2->where('type', TransactionType::BILL)->where('issuer', $value); + }); + }); + } +} diff --git a/app/Classes/Modules/Transactions/ControllersLogic/CreateBillGroupPaymentTransactionLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/CreateBillGroupPaymentTransactionLogic.php index 5c1ae1bf..92a6343d 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/CreateBillGroupPaymentTransactionLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/CreateBillGroupPaymentTransactionLogic.php @@ -68,6 +68,12 @@ class CreateBillGroupPaymentTransactionLogic extends AbstractControllerLogic $billGroupPayment = $this->calculatesBillGroupPaymentAmount->execute($billGroup); $outstanding_amount = $billGroupPayment['outstanding_amount']; + if ($billGroupPayment['outstanding_amount'] == 0) { + if ($billGroup->transactions()->whereIn('status', [ApprovalStatus::PENDING_SUBMISSION, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->count() !== 0) { + throw new MalformedRequestException('Invalid bill group, payment transaction already exist.'); + } + } + $payAmount = floatval(str_replace(',', '', $request->input('payAmount'))); if($payAmount > round($outstanding_amount, 2)) throw new MalformedRequestException('Your payment must not be greater than '. $outstanding_amount .'.'); diff --git a/app/Classes/Modules/Transactions/ControllersLogic/CreateSupplierBillGroupLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/CreateSupplierBillGroupLogic.php index f89af62c..b67db312 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/CreateSupplierBillGroupLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/CreateSupplierBillGroupLogic.php @@ -21,9 +21,11 @@ use App\Classes\Modules\Documents\Services\CreatesDocument; use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject; use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject; use App\Classes\Modules\Transactions\Services\CreatesTransaction; +use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus; use App\Classes\ValueObjects\Constants\PaymentMethodType; use App\Classes\ValueObjects\Constants\TransactionType; use App\Models\BillGroup; +use App\Models\Transaction; class CreateSupplierBillGroupLogic extends AbstractControllerLogic { @@ -57,6 +59,9 @@ class CreateSupplierBillGroupLogic extends AbstractControllerLogic /** @var UpdateGroupLogic */ private $updateGroupLogic; + /** @var UpdatesTransactionStatus */ + private $updatesTransactionStatus; + /** * CreateSupplierBillGroupLogic constructor. @@ -66,8 +71,9 @@ class CreateSupplierBillGroupLogic extends AbstractControllerLogic * @param CreatesFiles $createsFile * @param GeneratesTransactionBillNumber $generatesTransactionBillNumber * @param UpdateGroupLogic $updateGroupLogic + * @param UpdatesTransactionStatus $updatesTransactionStatus */ - public function __construct(FetchesCompany $fetchesCompany, CreatesTransaction $createsTransaction, CreatesDocument $createsDocument, CreatesFiles $createsFile, GeneratesTransactionBillNumber $generatesTransactionBillNumber, UpdateGroupLogic $updateGroupLogic) + public function __construct(FetchesCompany $fetchesCompany, CreatesTransaction $createsTransaction, CreatesDocument $createsDocument, CreatesFiles $createsFile, GeneratesTransactionBillNumber $generatesTransactionBillNumber, UpdateGroupLogic $updateGroupLogic, UpdatesTransactionStatus $updatesTransactionStatus) { $this->fetchesCompany = $fetchesCompany; $this->createsTransaction = $createsTransaction; @@ -75,6 +81,7 @@ class CreateSupplierBillGroupLogic extends AbstractControllerLogic $this->createsFile = $createsFile; $this->generatesTransactionBillNumber = $generatesTransactionBillNumber; $this->updateGroupLogic = $updateGroupLogic; + $this->updatesTransactionStatus = $updatesTransactionStatus; } public function logic(Request $request) : JsonResponse @@ -83,6 +90,19 @@ class CreateSupplierBillGroupLogic extends AbstractControllerLogic $supplier = $this->fetchesCompany->execute(['id' => $request->route('id')]); $payments = $request->input('payments'); + $supplierRefunds = $request->input('supplierRefunds'); + + foreach ($supplierRefunds as $supplierRefund) { + $refund = Transaction::find($supplierRefund['id']); + + if ($refund->owner->transactions()->where('type', TransactionType::BILL)->first()->issuer !== $supplier->id) { + throw new MalformedRequestException('The supplier refund and bill group does not belongs to same supplier.'); + } + + if ($refund->type !== TransactionType::SUPPLIER_REFUND) { + throw new MalformedRequestException('Only transaction type supplier refund can be used for bill refund.'); + } + } $amount = 0; $original_amount = 0; @@ -129,6 +149,41 @@ class CreateSupplierBillGroupLogic extends AbstractControllerLogic $billGroup->groups()->sync($payment['id'], false); } + //create bill refund + foreach ($supplierRefunds as $supplierRefund) { + $refund = Transaction::find($supplierRefund['id']); + $deductedRefunds = $refund->transactions()->where('type', TransactionType::BILL_REFUND)->where('status', ApprovalStatus::APPROVED)->get(); + $refundDeductableAmount = $refund->amount - $deductedRefunds->sum('amount'); + $refundDeductableOriginalAmount = $refund->original_amount - $deductedRefunds->sum('original_amount'); + + $amount -= round($refundDeductableAmount, 2); + $original_amount -= round($refundDeductableOriginalAmount, 2); + + if ($amount > 0) { + $deductedRefundAmount = $refundDeductableAmount; + $deductedRefundOriginalAmount = $refundDeductableOriginalAmount; + + $this->updatesTransactionStatus->execute($refund, ApprovalStatus::COMPLETED); + } + + if ($amount < 0) { + $deductedRefundAmount = $refundDeductableAmount + $amount; + $deductedRefundOriginalAmount = $refundDeductableOriginalAmount + $original_amount; + } + + $billNumber = $this->generatesTransactionBillNumber->execute('BRFD-'); + + $object = new TransactionObject($billNumber, TransactionType::BILL_REFUND, $supplier->id, 1, + 1, PaymentMethodType::CASH, + $deductedRefundAmount, $deductedRefundOriginalAmount, $refund->currency_id, + $refund->original_currency_id, $deductedRefundOriginalAmount / $deductedRefundAmount, + 0, 0, null, ApprovalStatus::APPROVED, []); + + $transaction = $this->createsTransaction->execute($refund, $object); + + $billGroup->billRefunds()->sync($transaction->id, false); + } + return $this->response([]); } } diff --git a/app/Classes/Modules/Transactions/ControllersLogic/DeleteBillGroupLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/DeleteBillGroupLogic.php index 56464409..1122c111 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/DeleteBillGroupLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/DeleteBillGroupLogic.php @@ -5,6 +5,8 @@ namespace App\Classes\Modules\Transactions\ControllersLogic; use App\Classes\General\Abstracts\AbstractControllerLogic; use App\Classes\Modules\Transactions\Services\FetchesBillGroup; use App\Classes\Modules\Transactions\Services\DeletesTransaction; +use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus; +use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Http\Resources\BillGroupResource; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -28,15 +30,20 @@ class DeleteBillGroupLogic extends AbstractControllerLogic /** @var DeletesTransaction */ private $deletesTransaction; + /** @var UpdatesTransactionStatus */ + private $updatesTransactionStatus; + /** * DeleteBillGroupLogic constructor. * @param FetchesBillGroup $fetchesBillGroup * @param DeletesTransaction $deletesTransaction + * @param UpdatesTransactionStatus $updatesTransactionStatus */ - public function __construct(FetchesBillGroup $fetchesBillGroup, DeletesTransaction $deletesTransaction) + public function __construct(FetchesBillGroup $fetchesBillGroup, DeletesTransaction $deletesTransaction, UpdatesTransactionStatus $updatesTransactionStatus) { $this->fetchesBillGroup = $fetchesBillGroup; $this->deletesTransaction = $deletesTransaction; + $this->updatesTransactionStatus = $updatesTransactionStatus; } /** @@ -59,7 +66,15 @@ class DeleteBillGroupLogic extends AbstractControllerLogic foreach($groups as $group) { $billGroup->groups()->detach($group->id); } + + $billRefunds = $billGroup->billRefunds()->get(); + foreach($billRefunds as $billRefund) { + $billGroup->billRefunds()->detach($billRefund->id); + $this->deletesTransaction->execute($billRefund); + $this->updatesTransactionStatus->execute($billRefund->owner, ApprovalStatus::APPROVED); + } + $billGroup->delete(); return $this->resourceResponse(new BillGroupResource($billGroup)); diff --git a/app/Classes/Modules/Transactions/Services/CalculatesBillGroupPaymentAmount.php b/app/Classes/Modules/Transactions/Services/CalculatesBillGroupPaymentAmount.php index 812f8a3c..1a130b41 100644 --- a/app/Classes/Modules/Transactions/Services/CalculatesBillGroupPaymentAmount.php +++ b/app/Classes/Modules/Transactions/Services/CalculatesBillGroupPaymentAmount.php @@ -8,11 +8,13 @@ use App\Models\BillGroup; class CalculatesBillGroupPaymentAmount { public function execute(BillGroup $billGroup){ + $bill_refund_amount = floatval($billGroup->billRefunds->sum('amount')); $floating_amount = floatval($billGroup->transactions()->whereIn('status', [ApprovalStatus::PENDING_SUBMISSION, ApprovalStatus::PENDING_VERIFICATION])->sum('amount')); $paid_amount = floatval($billGroup->transactions()->where('status', ApprovalStatus::APPROVED)->sum('amount')); - $outstanding_amount = $billGroup->amount - $paid_amount - $floating_amount + $billGroup->service_charge; + $outstanding_amount = $billGroup->amount - $bill_refund_amount - $paid_amount - $floating_amount + $billGroup->service_charge; return [ + 'bill_refund_amount' => $bill_refund_amount, 'floating_amount' => $floating_amount, 'paid_amount' => $paid_amount, 'outstanding_amount' => $outstanding_amount, diff --git a/app/Classes/ValueObjects/Constants/TransactionType.php b/app/Classes/ValueObjects/Constants/TransactionType.php index fbab3119..e14930b0 100644 --- a/app/Classes/ValueObjects/Constants/TransactionType.php +++ b/app/Classes/ValueObjects/Constants/TransactionType.php @@ -33,4 +33,9 @@ final class TransactionType { public const CASH_BACK = 13; public const SUPPLIER_PAYMENT = 14; + + public const SUPPLIER_REFUND = 15; + + public const BILL_REFUND = 16; + } diff --git a/app/Console/Commands/ExpiredRefundedBookingCommand.php b/app/Console/Commands/ExpiredRefundedBookingCommand.php index db7e00a7..0fcbd87b 100644 --- a/app/Console/Commands/ExpiredRefundedBookingCommand.php +++ b/app/Console/Commands/ExpiredRefundedBookingCommand.php @@ -151,6 +151,22 @@ class ExpiredRefundedBookingCommand extends Command $transaction = $this->createsTransaction->execute($bookingPayment, $object); } + + if ($bookingInWhiteForm) { + $refund = $bookingPayment->transactions()->supplierRefunds()->where('amount', $transaction->amount)->where('status', ApprovalStatus::APPROVED)->first(); + + if (!$refund) { + $billNumber = $this->generatesTransactionBillNumber->execute('SRFD-'); + + $object = new TransactionObject($billNumber, TransactionType::SUPPLIER_REFUND, 1, $booking->company->id, + 1, PaymentMethodType::CASH, + $transaction->amount, $transaction->amount * $bookingPayment->currency_rate, 1, + $bookingPayment->original_currency_id, $bookingPayment->currency_rate, + 0, 0, null, ApprovalStatus::APPROVED, [], $bookingPayment->bill_no); + + $transaction = $this->createsTransaction->execute($bookingPayment, $object); + } + } } else { Log::info("Credit note transaction id: {$transaction->id}, booking marking not found, the payment reference is: {$transaction->payment_reference}"); } diff --git a/app/Http/Resources/BillGroupResource.php b/app/Http/Resources/BillGroupResource.php index 6f61aeb7..23c8050e 100644 --- a/app/Http/Resources/BillGroupResource.php +++ b/app/Http/Resources/BillGroupResource.php @@ -18,6 +18,7 @@ class BillGroupResource extends JsonResource public function toArray($request) { $billGroupPayment = (App()->make(CalculatesBillGroupPaymentAmount::class))->execute($this->resource); + $bill_refund_amount = $billGroupPayment['bill_refund_amount']; $floating_amount = $billGroupPayment['floating_amount']; $paid_amount = $billGroupPayment['paid_amount']; $outstanding_amount = $billGroupPayment['outstanding_amount']; @@ -37,6 +38,7 @@ class BillGroupResource extends JsonResource 'currency_rate' => (float) $this->currency_rate, 'status' => $this->status, 'groups' => GroupResource::collection($this->groups), + 'bill_refund_amount' => $bill_refund_amount, 'floating_amount' => $floating_amount, 'paid_amount' => $paid_amount, 'outstanding_amount' => $outstanding_amount, @@ -58,6 +60,23 @@ class BillGroupResource extends JsonResource 'updated_at' => Carbon::parse($transaction->updated_at)->format('d-m-Y h:i:s A'), ]; }), + 'bill_refunds' => $this->billRefunds->map(function ($transaction) { + return [ + 'id' => $transaction->id, + 'type' => (int) $transaction->type, + 'bill_no' => $transaction->bill_no, + 'payment_method' => (float) $transaction->payment_method, + 'amount' => (double) $transaction->amount, + 'original_amount' => (double) $transaction->original_amount, + 'currency' => new CurrencyResource($transaction->currency), + 'original_currency' => new CurrencyResource($transaction->original_currency), + 'service_charge' => (double) $transaction->service_charge, + 'tax' => (double) $transaction->tax, + 'status' => (int) $transaction->status, + 'statusText' => ApprovalStatus::APPROVAL_STATUS_ID[(int) $transaction->status], + 'updated_at' => Carbon::parse($transaction->updated_at)->format('d-m-Y h:i:s A'), + ]; + }), ]; } } diff --git a/app/Http/Resources/TransactionResource.php b/app/Http/Resources/TransactionResource.php index 09967f4c..b431c854 100644 --- a/app/Http/Resources/TransactionResource.php +++ b/app/Http/Resources/TransactionResource.php @@ -3,6 +3,7 @@ namespace App\Http\Resources; use App\Classes\Modules\Bookings\Services\CalculatesBookingRefundAmount; +use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\TransactionType; use App\Models\Booking; use Carbon\Carbon; @@ -19,7 +20,7 @@ class TransactionResource extends JsonResource public function toArray($request) { - $booking = in_array((int)$this->type, [TransactionType::BILL, TransactionType::REFUND])? $this->owner->owner : $this->owner; + $booking = in_array((int)$this->type, [TransactionType::BILL, TransactionType::REFUND, TransactionType::SUPPLIER_REFUND])? $this->owner->owner : $this->owner; $days = $this->created_at->endOfDay()->addWeekdays($booking->service_id === 3 ? 3 : 1); return [ @@ -32,8 +33,8 @@ class TransactionResource extends JsonResource 'recipient_bank_account' => new BankResource($booking->bank), 'issuer_name' => $this->issuerCompany->name, 'issuer_id' => $this->issuerCompany->id, - 'amount' => (double) $this->amount, - 'original_amount' => (double) $this->original_amount, + 'amount' => (double) ($this->type === TransactionType::SUPPLIER_REFUND ? $this->amount - $this->transactions()->where('type', TransactionType::BILL_REFUND)->where('status', ApprovalStatus::APPROVED)->sum('amount') : $this->amount), + 'original_amount' => (double) ($this->type === TransactionType::SUPPLIER_REFUND ? $this->original_amount - $this->transactions()->where('type', TransactionType::BILL_REFUND)->where('status', ApprovalStatus::APPROVED)->sum('original_amount') : $this->original_amount), 'currency' => new CurrencyResource($this->currency), 'original_currency' => new CurrencyResource($this->original_currency), 'service_charge' => (double) $this->service_charge, diff --git a/app/Models/BillGroup.php b/app/Models/BillGroup.php index 6986ee52..9270d8e8 100644 --- a/app/Models/BillGroup.php +++ b/app/Models/BillGroup.php @@ -29,6 +29,14 @@ class BillGroup extends Model implements Documentable, Transactionable return $this->MorphMany(Transaction::class, 'owner'); } + use HasRelationships; + use \Staudenmeir\EloquentHasManyDeep\HasTableAlias; + + public function billRefunds() + { + return $this->belongsToMany(Transaction::class, BillGroupRefund::class); + } + /** * @return MorphMany */ diff --git a/app/Models/BillGroupRefund.php b/app/Models/BillGroupRefund.php new file mode 100644 index 00000000..aa430873 --- /dev/null +++ b/app/Models/BillGroupRefund.php @@ -0,0 +1,27 @@ +BelongsTo(BillGroup::class, 'bill_group_id', 'id'); + } + + /** + * @return BelongsTo + */ + public function transaction(): BelongsTo + { + return $this->BelongsTo(Transaction::class, 'transaction_id', 'id'); + } +} diff --git a/app/Models/Transaction.php b/app/Models/Transaction.php index 185fdb36..4161632b 100644 --- a/app/Models/Transaction.php +++ b/app/Models/Transaction.php @@ -186,6 +186,20 @@ class Transaction extends AbstractModel implements Documentable, Transactionable return $query->where('type', TransactionType::REFUND); } + /** + * @param Builder $query + * @param string $payment_reference + * @return Builder + */ + public function scopeSupplierRefunds(Builder $query, ?string $payment_reference = NULL) + { + if($payment_reference){ + $query->where('payment_reference', $payment_reference); + } + + return $query->where('type', TransactionType::SUPPLIER_REFUND); + } + /** * @param Builder $query diff --git a/database/migrations/2024_02_22_222130_create_bill_group_refunds_table.php b/database/migrations/2024_02_22_222130_create_bill_group_refunds_table.php new file mode 100644 index 00000000..f7b278b1 --- /dev/null +++ b/database/migrations/2024_02_22_222130_create_bill_group_refunds_table.php @@ -0,0 +1,22 @@ +id(); + $table->foreignId('bill_group_id')->unsigned()->on('bill_groups'); + $table->foreignId('transaction_id')->unsigned()->on('transactions'); + }); + } + + public function down() + { + Schema::dropIfExists('bill_group_refunds'); + } +} diff --git a/resources/assets/vue/components/bookings/elements/BillGroupComponent.vue b/resources/assets/vue/components/bookings/elements/BillGroupComponent.vue index 42727055..e93eb1ad 100644 --- a/resources/assets/vue/components/bookings/elements/BillGroupComponent.vue +++ b/resources/assets/vue/components/bookings/elements/BillGroupComponent.vue @@ -58,6 +58,42 @@
+
+
+
Bill Refunds
+
+
+
+
Date
+
+ {{refund.updated_at}} +
+
+
+
Reference
+
+ {{refund.bill_no}} +
+
+
+
Amount
+
+ {{ refund.currency.short_code }} {{ formatAmount(refund.amount) }} +
+
+
+
Status
+
+ {{ refund.statusText }} +
+
+
+
+
+
No Selected Refunds
+
+
+
Payment History
diff --git a/resources/assets/vue/components/bookings/elements/BillGroupPaymentSummaryComponent.vue b/resources/assets/vue/components/bookings/elements/BillGroupPaymentSummaryComponent.vue index 9ad4f1d3..c826f154 100644 --- a/resources/assets/vue/components/bookings/elements/BillGroupPaymentSummaryComponent.vue +++ b/resources/assets/vue/components/bookings/elements/BillGroupPaymentSummaryComponent.vue @@ -36,6 +36,17 @@
MYR 0.00
+
+
+
Bill Refund Total:
+
+
+
- {{selectedBillGroup.currency.short_code}} {{formatAmount(selectedBillGroup.bill_refund_amount)}}
+
+
+
MYR 0.00
+
+
Paid Total:
@@ -69,7 +80,7 @@
MYR 0.00
-
+
diff --git a/resources/assets/vue/components/bookings/elements/SupplierRefundComponent.vue b/resources/assets/vue/components/bookings/elements/SupplierRefundComponent.vue new file mode 100644 index 00000000..6626ce56 --- /dev/null +++ b/resources/assets/vue/components/bookings/elements/SupplierRefundComponent.vue @@ -0,0 +1,80 @@ + + + diff --git a/resources/assets/vue/components/bookings/elements/TransactionGroupPaymentComponent.vue b/resources/assets/vue/components/bookings/elements/TransactionGroupPaymentComponent.vue index b86cdce7..7fdd579f 100644 --- a/resources/assets/vue/components/bookings/elements/TransactionGroupPaymentComponent.vue +++ b/resources/assets/vue/components/bookings/elements/TransactionGroupPaymentComponent.vue @@ -117,14 +117,6 @@ this.active = this.payments.some(payment => payment.id === this.item.id); }, methods: { - deleteGroupTransaction() { - this.isLoading = true; - this.submit(this.route('api.transaction.group.delete', this.item.id), 'delete', this.section, true, true); - }, - updateDo() { - this.isLoading = true; - this.submit(this.route('api.transaction.group.bulk.po'), 'post', this.section, true, true); - }, activate(){ this.active = !this.active; this.$emit('input', this.item) diff --git a/resources/assets/vue/components/bookings/forms/SupplierWhiteFormPlaceOrderFormComponent.vue b/resources/assets/vue/components/bookings/forms/SupplierWhiteFormPlaceOrderFormComponent.vue index 2ba56062..5b28e017 100644 --- a/resources/assets/vue/components/bookings/forms/SupplierWhiteFormPlaceOrderFormComponent.vue +++ b/resources/assets/vue/components/bookings/forms/SupplierWhiteFormPlaceOrderFormComponent.vue @@ -16,7 +16,7 @@
Order Total:
-
{{ this.payments.length > 0 ? this.payments[0].original_currency.short_code : "CNY"}} {{(Math.round((this.originalTotal + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
+
{{ this.payments.length > 0 ? this.payments[0].original_currency.short_code : "CNY"}} {{ formatNumber(this.originalTotal) }}
@@ -24,7 +24,7 @@
-
MYR {{(Math.round((this.total + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
+
MYR {{ formatNumber(this.total) }}
@@ -43,6 +43,17 @@
{{ billGroupCurrencyRate }}
+
+
+
Bill Refund Total:
+
+
+
- CNY {{ parameters.payment_total }}
+
+
+
- MYR {{ formatNumber(refundTotal > paymentTotal ? paymentTotal : refundTotal) }}
+
+
Payment Total:
@@ -51,7 +62,7 @@
MYR {{ parameters.payment_total }}
-
MYR {{(Math.round((paymentTotal + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
+
MYR {{ formatNumber(paymentTotal) }}
@@ -84,6 +95,18 @@
+
+
+
+ Supplier Refund +
+ + + +
+
@@ -108,8 +131,16 @@ required: true }, }, + watch: { + 'supplier': function() { + this.supplierRefundListKey ++; + this.supplierRefunds = [] + }, + }, data(){ return { + supplierRefunds: [], + supplierRefundListKey: 1, parameters: { service_charges: '0', payment_total: '0', @@ -150,6 +181,16 @@ paymentTotal(){ return this.total ? this.total + parseFloat(this.parameters.service_charges.replaceAll(',', '')) : 0; }, + refundOriginalTotal(){ + return this.supplierRefunds.reduce(function (total, currentValue) { + return total + currentValue.original_amount; + }, 0); + }, + refundTotal(){ + return this.supplierRefunds.reduce(function (total, currentValue) { + return total + currentValue.amount; + }, 0); + }, billGroupCurrencyRate(){ const paymentTotal = parseFloat(this.parameters.payment_total.replaceAll(',', '')); return this.originalTotal && paymentTotal > 0 ? (this.originalTotal / paymentTotal).toFixed(5) : 1; @@ -162,6 +203,9 @@ submitForm(){ this.parameters = { payments: this.payments, + supplierRefunds: this.supplierRefunds.sort((a, b) => { + return a.amount - b.amount; + }), service_charges: this.is1688Supplier ? '0' : this.parameters.service_charges, payment_total: this.is1688Supplier ? this.parameters.payment_total : '0', }; @@ -170,6 +214,8 @@ }, successHandler(){ this.refreshList(); + this.supplierRefunds = [] + this.supplierRefundListKey ++; this.$store.dispatch('toggleSection', {name: 'paymentInProgressBillGroupList', status: !this.$store.getters.isShowing('paymentInProgressBillGroupList')}); this.parameters = { payments: [], @@ -177,6 +223,12 @@ payment_total: '0', }; }, + refundOrder(supplierRefund){ + this.supplierRefunds.some(item => item.id === supplierRefund.id) ? this.supplierRefunds = this.supplierRefunds.filter(item => item.id !== supplierRefund.id) : this.supplierRefunds.push(supplierRefund); + }, + formatNumber(value) { + return (Math.round((value + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") + } }, mixins: [FormHandler] } From 767d6c84fee67eb6065e5d2ee931c24d76ce98f0 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Sun, 25 Feb 2024 20:43:01 +0800 Subject: [PATCH 109/434] update to bill refund for 1688 supplier --- .../CreateSupplierBillGroupLogic.php | 4 +++- .../elements/SupplierRefundComponent.vue | 7 ++++++ ...pplierWhiteFormPlaceOrderFormComponent.vue | 23 ++++++++++++++----- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/app/Classes/Modules/Transactions/ControllersLogic/CreateSupplierBillGroupLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/CreateSupplierBillGroupLogic.php index b67db312..ef0560e7 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/CreateSupplierBillGroupLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/CreateSupplierBillGroupLogic.php @@ -150,7 +150,9 @@ class CreateSupplierBillGroupLogic extends AbstractControllerLogic } //create bill refund - foreach ($supplierRefunds as $supplierRefund) { + $amount += $service_charges; + + foreach ($supplierRefunds as $supplierRefund) { $refund = Transaction::find($supplierRefund['id']); $deductedRefunds = $refund->transactions()->where('type', TransactionType::BILL_REFUND)->where('status', ApprovalStatus::APPROVED)->get(); $refundDeductableAmount = $refund->amount - $deductedRefunds->sum('amount'); diff --git a/resources/assets/vue/components/bookings/elements/SupplierRefundComponent.vue b/resources/assets/vue/components/bookings/elements/SupplierRefundComponent.vue index 6626ce56..1a42fe6c 100644 --- a/resources/assets/vue/components/bookings/elements/SupplierRefundComponent.vue +++ b/resources/assets/vue/components/bookings/elements/SupplierRefundComponent.vue @@ -19,6 +19,9 @@
Amount
+
{{item.currency.short_code}} {{((Math.round(( item.amount + Number.EPSILON) * 100) / 100)).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
@@ -39,6 +42,10 @@ type: String, required: true }, + is1688Supplier:{ + type: Boolean, + required: true + }, payments:{ type: Array, required: true diff --git a/resources/assets/vue/components/bookings/forms/SupplierWhiteFormPlaceOrderFormComponent.vue b/resources/assets/vue/components/bookings/forms/SupplierWhiteFormPlaceOrderFormComponent.vue index 5b28e017..9b7f8eb1 100644 --- a/resources/assets/vue/components/bookings/forms/SupplierWhiteFormPlaceOrderFormComponent.vue +++ b/resources/assets/vue/components/bookings/forms/SupplierWhiteFormPlaceOrderFormComponent.vue @@ -48,10 +48,10 @@
Bill Refund Total:
-
- CNY {{ parameters.payment_total }}
+
- {{ this.supplierRefunds.length > 0 ? this.supplierRefunds[0].currency.short_code : 'MYR' }} {{ this.inputPaymentTotal > 0 ? refundTotal > this.inputPaymentTotal ? this.inputPaymentTotal : formatNumber(refundTotal) : '0.00' }}
-
- MYR {{ formatNumber(refundTotal > paymentTotal ? paymentTotal : refundTotal) }}
+
- {{ this.supplierRefunds[0].currency.short_code }} {{ formatNumber(refundTotal > paymentTotal ? paymentTotal : refundTotal) }}
@@ -59,10 +59,18 @@
Payment Total:
-
MYR {{ parameters.payment_total }}
+
MYR {{ formatNumber(this.inputPaymentTotal) }}
-
MYR {{ formatNumber(paymentTotal) }}
+
MYR {{ formatNumber(paymentTotal - refundTotal > 0 ? (paymentTotal - refundTotal) : 0) }}
+
+
+
+
+
Payment Total After Refund:
+
+
+
{{ this.supplierRefunds.length > 0 ? this.supplierRefunds[0].currency.short_code : 'MYR' }} {{ refundTotal > this.inputPaymentTotal ? '0.00' : formatNumber(this.inputPaymentTotal - refundTotal) }}
@@ -102,7 +110,7 @@
@@ -166,6 +174,9 @@ } }, computed: { + inputPaymentTotal(){ + return parseFloat(this.parameters.payment_total.replaceAll(',', '')); + }, originalTotal(){ return this.payments.reduce(function (total, currentValue) { return total + currentValue.original_amount; @@ -192,7 +203,7 @@ }, 0); }, billGroupCurrencyRate(){ - const paymentTotal = parseFloat(this.parameters.payment_total.replaceAll(',', '')); + const paymentTotal = this.inputPaymentTotal; return this.originalTotal && paymentTotal > 0 ? (this.originalTotal / paymentTotal).toFixed(5) : 1; }, is1688Supplier(){ From 28c0aeff77b7b4cf7ca0985be4f431b2832616c1 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Mon, 26 Feb 2024 00:38:25 +0800 Subject: [PATCH 110/434] dont show payment on homepage if it is in refund process --- .../Filters/DoesNotHaveRefundInProgress.php | 24 +++++++++++++++++++ .../SupplierPendingOrdersSectionComponent.vue | 4 ++-- 2 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 app/Classes/General/Eloquent/Filters/DoesNotHaveRefundInProgress.php diff --git a/app/Classes/General/Eloquent/Filters/DoesNotHaveRefundInProgress.php b/app/Classes/General/Eloquent/Filters/DoesNotHaveRefundInProgress.php new file mode 100644 index 00000000..60618626 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/DoesNotHaveRefundInProgress.php @@ -0,0 +1,24 @@ +whereDoesntHave('transactions', function ($query) { + return $query->where('type', TransactionType::REFUND)->whereIn('status', [ApprovalStatus::PENDING_SUBMISSION, ApprovalStatus::PENDING_VERIFICATION]); + }); + } +} diff --git a/resources/assets/vue/components/bookings/sections/SupplierPendingOrdersSectionComponent.vue b/resources/assets/vue/components/bookings/sections/SupplierPendingOrdersSectionComponent.vue index fa345d58..8f6fb8c7 100644 --- a/resources/assets/vue/components/bookings/sections/SupplierPendingOrdersSectionComponent.vue +++ b/resources/assets/vue/components/bookings/sections/SupplierPendingOrdersSectionComponent.vue @@ -117,7 +117,7 @@
- + @@ -202,7 +202,7 @@ // todo-refund: activate this for partial refund // this.$refs.pendingOrdersList.updateFilters({per_page: 10000, status: 2, type: 1, original_currency_id_in: [this.selectedCurrency.id], transaction_service_id: this.selectedService.id, is_not_fully_refunded: true}); - this.$refs.pendingOrdersList.updateFilters({per_page: 10000, status: 2, type: 1, original_currency_id_in: [this.selectedCurrency.id], transaction_service_id: this.selectedService.id}); + this.$refs.pendingOrdersList.updateFilters({per_page: 10, status: 2, type: 1, original_currency_id_in: [this.selectedCurrency.id], transaction_service_id: this.selectedService.id, does_not_have_refund_in_progress: true}); this.selectedSupplier.status = false; this.currencyDropdownLaunch.status = false; From f84b04c26caa336abad90a87e66991c21f44532c Mon Sep 17 00:00:00 2001 From: edmondlang Date: Tue, 27 Feb 2024 01:08:16 +0800 Subject: [PATCH 111/434] update logging and indentation --- app/Console/Commands/ExpiredBookingCommand.php | 6 ++++-- app/Console/Kernel.php | 8 ++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/app/Console/Commands/ExpiredBookingCommand.php b/app/Console/Commands/ExpiredBookingCommand.php index ca690c67..5779a9e9 100644 --- a/app/Console/Commands/ExpiredBookingCommand.php +++ b/app/Console/Commands/ExpiredBookingCommand.php @@ -66,9 +66,10 @@ class ExpiredBookingCommand extends Command $transactions = $booking->transactions; foreach ($transactions as $transaction) { + $prevStatus = $transaction->status; $transaction->status = ApprovalStatus::EXPIRED; $transaction->save(); - Log::info("Expired Transaction id: {$transaction->id} from Booking id: {$booking->id}"); + Log::info("Expired Transaction id: {$transaction->id} from Booking id: {$booking->id}. Status before update: {$prevStatus}"); } } @@ -89,9 +90,10 @@ class ExpiredBookingCommand extends Command $transactions = $booking->transactions; foreach ($transactions as $transaction) { + $prevStatus = $transaction->status; $transaction->status = ApprovalStatus::EXPIRED; $transaction->save(); - Log::info("Expired Transaction id: {$transaction->id} from Booking id: {$booking->id}"); + Log::info("Expired Transaction id: {$transaction->id} from Booking id: {$booking->id}. Status before update: {$prevStatus}"); } } } diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 412ed70f..5e9aa8a8 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -45,12 +45,12 @@ class Kernel extends ConsoleKernel ->withoutOverlapping(); $schedule->command('booking:expired') - ->dailyAt('02:00') - ->withoutOverlapping(); + ->dailyAt('02:00') + ->withoutOverlapping(); $schedule->command('purchaseOrder:autoFill') - ->dailyAt('03:00') - ->withoutOverlapping(); + ->dailyAt('03:00') + ->withoutOverlapping(); } /** From 5fd2f6ef7f709a5e676bfd8ecfed9660a6dd0784 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Wed, 28 Feb 2024 01:34:39 +0800 Subject: [PATCH 112/434] -complete supplier bill group when oustanding is 0 -create refund and supplier refund if the request refund order is in white form --- .../CreateBookingRefundLogic.php | 20 +++++++++++++------ ...CreateBillGroupPaymentTransactionLogic.php | 19 +++++++++++------- .../UpdateRefundTransactionStatusLogic.php | 6 ++++++ .../CalculatesBillGroupPaymentAmount.php | 13 ++++++------ .../ExpiredRefundedBookingCommand.php | 4 ++-- .../BillGroupPaymentSummaryComponent.vue | 7 ++++++- .../elements/PaymentHistoryComponent.vue | 2 +- .../elements/SupplierRefundComponent.vue | 10 +++++++++- ...pplierWhiteFormPlaceOrderFormComponent.vue | 2 +- 9 files changed, 58 insertions(+), 25 deletions(-) diff --git a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php index 0648629e..c99f42df 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php @@ -75,10 +75,6 @@ class CreateBookingRefundLogic extends AbstractControllerLogic $transaction = $this->fetchesTransaction->execute(['id' => $request->route('payment_id')]); - if ($transaction->transactions()->bills()->first()) { - throw new MalformedRequestException('Booking under white form cannot request for refund'); - } - $booking = $transaction->owner; $billNumber = $this->generatesTransactionBillNumber->execute('RFD-'); @@ -100,9 +96,21 @@ class CreateBookingRefundLogic extends AbstractControllerLogic $transaction->original_currency_id, $transaction->currency_rate, 0, 0, null, ApprovalStatus::PENDING_VERIFICATION, [], $transaction->bill_no); - $transaction = $this->createsTransaction->execute($transaction, $object); + $refund_transaction = $this->createsTransaction->execute($transaction, $object); - return $this->resourceResponse(new TransactionResource($transaction)); + // create supplier refund + if ($transaction->transactions()->bills()->first()) { + $billNumber = $this->generatesTransactionBillNumber->execute('SRFD-'); + $object = new TransactionObject($billNumber, TransactionType::SUPPLIER_REFUND, 1, $booking->company->id, + 1, PaymentMethodType::CASH, + $refundTotal, $request->input('amount'), 1, + $transaction->original_currency_id, $transaction->currency_rate, + 0, 0, null, ApprovalStatus::PENDING_VERIFICATION, [], $transaction->bill_no); + + $transaction = $this->createsTransaction->execute($transaction, $object); + } + + return $this->resourceResponse(new TransactionResource($refund_transaction)); } diff --git a/app/Classes/Modules/Transactions/ControllersLogic/CreateBillGroupPaymentTransactionLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/CreateBillGroupPaymentTransactionLogic.php index 92a6343d..e2fc6dc1 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/CreateBillGroupPaymentTransactionLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/CreateBillGroupPaymentTransactionLogic.php @@ -77,13 +77,18 @@ class CreateBillGroupPaymentTransactionLogic extends AbstractControllerLogic $payAmount = floatval(str_replace(',', '', $request->input('payAmount'))); if($payAmount > round($outstanding_amount, 2)) throw new MalformedRequestException('Your payment must not be greater than '. $outstanding_amount .'.'); - $billNumber = $this->generatesTransactionBillNumber->execute('SPLR-PYMT-'); - $transaction_object = new TransactionObject($billNumber, TransactionType::SUPPLIER_PAYMENT, $billGroup->issuer, - $billGroup->receiver, $billGroup->issuerCompany->banks()->where('default', true)->first()->id, PaymentMethodType::CASH, - $payAmount, $payAmount, 1, 1, 1, - 0, 0, null, ApprovalStatus::PENDING_SUBMISSION, [], ''); - $this->createsTransaction->execute($billGroup, $transaction_object); - + if ($billGroupPayment['outstanding_amount'] == 0 && $payAmount == 0) { + $billGroup->status = ApprovalStatus::APPROVED; + $billGroup->save(); + } else { + $billNumber = $this->generatesTransactionBillNumber->execute('SPLR-PYMT-'); + $transaction_object = new TransactionObject($billNumber, TransactionType::SUPPLIER_PAYMENT, $billGroup->issuer, + $billGroup->receiver, $billGroup->issuerCompany->banks()->where('default', true)->first()->id, PaymentMethodType::CASH, + $payAmount, $payAmount, 1, 1, 1, + 0, 0, null, ApprovalStatus::PENDING_SUBMISSION, [], ''); + $this->createsTransaction->execute($billGroup, $transaction_object); + } + return $this->resourceResponse(new BillGroupResource($billGroup)); } diff --git a/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php index 09e4b102..02107a77 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php @@ -85,6 +85,8 @@ class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic $paymentTransaction = $refundTransaction->owner; + $supplierRefundTransaction = $paymentTransaction->transactions()->supplierRefunds()->where('status', [ApprovalStatus::PENDING_VERIFICATION])->first(); + $booking = $paymentTransaction->owner; $reference = $refundTransaction->amount == $paymentTransaction->amount ? 'Fully Refund for Ref. ' . $booking->marking : 'Partially Refund for Ref. ' . $booking->marking; @@ -93,6 +95,10 @@ class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic $this->creditWalletProcessor->execute($booking->company, $refundTransaction->type, $refundTransaction->amount, $reference); } + if ($supplierRefundTransaction) { + $this->updatesTransactionStatus->execute($supplierRefundTransaction, $request->route('status')); + } + $paidAmount = $paymentTransaction->original_amount - $this->calculatesBookingRefundAmount->calculateRefundAmount($paymentTransaction, $booking->fix_currency_id); if (!$paidAmount > 0) { $this->updatesTransactionStatus->execute($paymentTransaction, ApprovalStatus::REFUNDED); diff --git a/app/Classes/Modules/Transactions/Services/CalculatesBillGroupPaymentAmount.php b/app/Classes/Modules/Transactions/Services/CalculatesBillGroupPaymentAmount.php index 1a130b41..f41de813 100644 --- a/app/Classes/Modules/Transactions/Services/CalculatesBillGroupPaymentAmount.php +++ b/app/Classes/Modules/Transactions/Services/CalculatesBillGroupPaymentAmount.php @@ -7,11 +7,13 @@ use App\Models\BillGroup; class CalculatesBillGroupPaymentAmount { - public function execute(BillGroup $billGroup){ - $bill_refund_amount = floatval($billGroup->billRefunds->sum('amount')); - $floating_amount = floatval($billGroup->transactions()->whereIn('status', [ApprovalStatus::PENDING_SUBMISSION, ApprovalStatus::PENDING_VERIFICATION])->sum('amount')); - $paid_amount = floatval($billGroup->transactions()->where('status', ApprovalStatus::APPROVED)->sum('amount')); + public function execute(BillGroup $billGroup) + { + $bill_refund_amount = round(floatval($billGroup->billRefunds->sum('amount')), 7); + $floating_amount = round(floatval($billGroup->transactions()->whereIn('status', [ApprovalStatus::PENDING_SUBMISSION, ApprovalStatus::PENDING_VERIFICATION])->sum('amount')), 7); + $paid_amount = round(floatval($billGroup->transactions()->where('status', ApprovalStatus::APPROVED)->sum('amount')), 7); $outstanding_amount = $billGroup->amount - $bill_refund_amount - $paid_amount - $floating_amount + $billGroup->service_charge; + $outstanding_amount = round($outstanding_amount, 7); return [ 'bill_refund_amount' => $bill_refund_amount, @@ -20,5 +22,4 @@ class CalculatesBillGroupPaymentAmount 'outstanding_amount' => $outstanding_amount, ]; } - -} \ No newline at end of file +} diff --git a/app/Console/Commands/ExpiredRefundedBookingCommand.php b/app/Console/Commands/ExpiredRefundedBookingCommand.php index 0fcbd87b..6cc24e28 100644 --- a/app/Console/Commands/ExpiredRefundedBookingCommand.php +++ b/app/Console/Commands/ExpiredRefundedBookingCommand.php @@ -140,7 +140,7 @@ class ExpiredRefundedBookingCommand extends Command Log::info("Credit note transaction id: {$transaction->id}, booking is in white form"); } - if (!$refund && !$bookingInWhiteForm) { + if (!$refund) { $billNumber = $this->generatesTransactionBillNumber->execute('RFD-'); $object = new TransactionObject($billNumber, TransactionType::REFUND, 1, $booking->company->id, @@ -153,7 +153,7 @@ class ExpiredRefundedBookingCommand extends Command } if ($bookingInWhiteForm) { - $refund = $bookingPayment->transactions()->supplierRefunds()->where('amount', $transaction->amount)->where('status', ApprovalStatus::APPROVED)->first(); + $refund = $bookingPayment->transactions()->supplierRefunds()->where('amount', $transaction->amount)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->first(); if (!$refund) { $billNumber = $this->generatesTransactionBillNumber->execute('SRFD-'); diff --git a/resources/assets/vue/components/bookings/elements/BillGroupPaymentSummaryComponent.vue b/resources/assets/vue/components/bookings/elements/BillGroupPaymentSummaryComponent.vue index c826f154..284f681d 100644 --- a/resources/assets/vue/components/bookings/elements/BillGroupPaymentSummaryComponent.vue +++ b/resources/assets/vue/components/bookings/elements/BillGroupPaymentSummaryComponent.vue @@ -96,11 +96,16 @@
-
+
+
+
+ +
+
diff --git a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue index 877ec248..82dfcfc5 100644 --- a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue +++ b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue @@ -292,7 +292,7 @@
-
+
diff --git a/resources/assets/vue/components/bookings/elements/SupplierRefundComponent.vue b/resources/assets/vue/components/bookings/elements/SupplierRefundComponent.vue index 1a42fe6c..872ebef4 100644 --- a/resources/assets/vue/components/bookings/elements/SupplierRefundComponent.vue +++ b/resources/assets/vue/components/bookings/elements/SupplierRefundComponent.vue @@ -54,6 +54,10 @@ type: Number, required: true }, + inputPaymentTotal: { + type: Number, + required: true + }, refundTotal: { type: Number, required: true @@ -65,7 +69,11 @@ }, computed: { clickable(){ - return this.refundTotal < this.paymentTotal || this.supplierRefunds.some((i) => this.item.id === i.id ); + if (this.is1688Supplier) { + return this.refundTotal < this.inputPaymentTotal || this.supplierRefunds.some((i) => this.item.id === i.id ); + } else { + return this.refundTotal < this.paymentTotal || this.supplierRefunds.some((i) => this.item.id === i.id ); + } } }, data(){ diff --git a/resources/assets/vue/components/bookings/forms/SupplierWhiteFormPlaceOrderFormComponent.vue b/resources/assets/vue/components/bookings/forms/SupplierWhiteFormPlaceOrderFormComponent.vue index 9b7f8eb1..4ca36c2e 100644 --- a/resources/assets/vue/components/bookings/forms/SupplierWhiteFormPlaceOrderFormComponent.vue +++ b/resources/assets/vue/components/bookings/forms/SupplierWhiteFormPlaceOrderFormComponent.vue @@ -110,7 +110,7 @@
From 5c105398246dcef286210d70ace5a99463a0ff5b Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Wed, 28 Feb 2024 20:53:20 +0800 Subject: [PATCH 113/434] resolve supplier refund amount to follow white form rate --- .../Eloquent/Filters/BelongsToSupplierId.php | 24 -------------- .../Filters/CurrencyRateIsNotEqual.php | 20 ++++++++++++ .../General/Eloquent/Filters/ReceiverIn.php | 20 ++++++++++++ .../CreateBookingRefundLogic.php | 15 ++++++--- .../CreateSupplierBillGroupLogic.php | 4 +++ .../ControllersLogic/UpdateGroupLogic.php | 12 +++++++ .../ExpiredRefundedBookingCommand.php | 31 ++++++++++++------- ...pplierWhiteFormPlaceOrderFormComponent.vue | 2 +- 8 files changed, 86 insertions(+), 42 deletions(-) delete mode 100644 app/Classes/General/Eloquent/Filters/BelongsToSupplierId.php create mode 100644 app/Classes/General/Eloquent/Filters/CurrencyRateIsNotEqual.php create mode 100644 app/Classes/General/Eloquent/Filters/ReceiverIn.php diff --git a/app/Classes/General/Eloquent/Filters/BelongsToSupplierId.php b/app/Classes/General/Eloquent/Filters/BelongsToSupplierId.php deleted file mode 100644 index 63536412..00000000 --- a/app/Classes/General/Eloquent/Filters/BelongsToSupplierId.php +++ /dev/null @@ -1,24 +0,0 @@ -whereHas('owner', function ($q) use ($value) { - $q->whereHas('transactions', function ($q2) use ($value) { - $q2->where('type', TransactionType::BILL)->where('issuer', $value); - }); - }); - } -} diff --git a/app/Classes/General/Eloquent/Filters/CurrencyRateIsNotEqual.php b/app/Classes/General/Eloquent/Filters/CurrencyRateIsNotEqual.php new file mode 100644 index 00000000..0372e760 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/CurrencyRateIsNotEqual.php @@ -0,0 +1,20 @@ +where('currency_rate', '!=', $value); + } + +} \ No newline at end of file diff --git a/app/Classes/General/Eloquent/Filters/ReceiverIn.php b/app/Classes/General/Eloquent/Filters/ReceiverIn.php new file mode 100644 index 00000000..3ce91559 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/ReceiverIn.php @@ -0,0 +1,20 @@ +whereIn('receiver', $value); + } + +} \ No newline at end of file diff --git a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php index c99f42df..75ad76a1 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php @@ -88,7 +88,8 @@ class CreateBookingRefundLogic extends AbstractControllerLogic $refundAmount = bcdiv($request->input('amount'), $transaction->currency_rate, 7); // refund service charges if is fully refund - $refundTotal = ($refund + $request->input('amount')) == $transaction->original_amount ? $refundAmount + $transaction->service_charge + $transaction->tax : $refundAmount; + $isFullyRefund = ($refund + $request->input('amount')) == $transaction->original_amount; + $refundTotal = $isFullyRefund ? $refundAmount + $transaction->service_charge + $transaction->tax : $refundAmount; $object = new TransactionObject($billNumber, TransactionType::REFUND, 1, $booking->company->id, 1, PaymentMethodType::CASH, @@ -98,13 +99,17 @@ class CreateBookingRefundLogic extends AbstractControllerLogic $refund_transaction = $this->createsTransaction->execute($transaction, $object); + $bookingInWhiteForm = $transaction->transactions()->bills()->first(); + // create supplier refund - if ($transaction->transactions()->bills()->first()) { + if ($bookingInWhiteForm) { $billNumber = $this->generatesTransactionBillNumber->execute('SRFD-'); - $object = new TransactionObject($billNumber, TransactionType::SUPPLIER_REFUND, 1, $booking->company->id, + $supplierRefundTotal = bcdiv($request->input('amount'), $bookingInWhiteForm->currency_rate, 7); + + $object = new TransactionObject($billNumber, TransactionType::SUPPLIER_REFUND, 1, $bookingInWhiteForm->issuer, 1, PaymentMethodType::CASH, - $refundTotal, $request->input('amount'), 1, - $transaction->original_currency_id, $transaction->currency_rate, + $supplierRefundTotal, $request->input('amount'), 1, + $transaction->original_currency_id, $bookingInWhiteForm->currency_rate, 0, 0, null, ApprovalStatus::PENDING_VERIFICATION, [], $transaction->bill_no); $transaction = $this->createsTransaction->execute($transaction, $object); diff --git a/app/Classes/Modules/Transactions/ControllersLogic/CreateSupplierBillGroupLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/CreateSupplierBillGroupLogic.php index ef0560e7..33284726 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/CreateSupplierBillGroupLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/CreateSupplierBillGroupLogic.php @@ -102,6 +102,10 @@ class CreateSupplierBillGroupLogic extends AbstractControllerLogic if ($refund->type !== TransactionType::SUPPLIER_REFUND) { throw new MalformedRequestException('Only transaction type supplier refund can be used for bill refund.'); } + + if ($refund->currency_rate == 1) { + throw new MalformedRequestException('Supplier refund with currecy rate 1 cannot be used for bill refund.'); + } } $amount = 0; diff --git a/app/Classes/Modules/Transactions/ControllersLogic/UpdateGroupLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/UpdateGroupLogic.php index aa432aea..f29db055 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/UpdateGroupLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/UpdateGroupLogic.php @@ -125,6 +125,18 @@ class UpdateGroupLogic extends AbstractControllerLogic $billTransaction = $this->updatesTransaction->execute($transaction, $object); + $supplierRefundTransactions = $transaction->owner->transactions()->supplierRefunds()->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED])->get(); + + foreach ($supplierRefundTransactions as $supplierRefundTransaction) { + $claimBefore = $supplierRefundTransaction->transactions()->where('type', TransactionType::BILL_REFUND)->where('status', ApprovalStatus::APPROVED)->exists(); + + if (!$claimBefore) { + $supplierRefundTransaction->currency_rate = $rate; + $supplierRefundTransaction->amount = $supplierRefundTransaction->original_amount / $rate; + $supplierRefundTransaction->save(); + } + } + $transferTransaction = $transaction->transactions()->where('type', TransactionType::TRANSFER_FEE)->first(); $transferFee = $this->calculatesTransactionTransferFee->execute($billTransaction->original_amount, $constant); diff --git a/app/Console/Commands/ExpiredRefundedBookingCommand.php b/app/Console/Commands/ExpiredRefundedBookingCommand.php index 6cc24e28..d64cf385 100644 --- a/app/Console/Commands/ExpiredRefundedBookingCommand.php +++ b/app/Console/Commands/ExpiredRefundedBookingCommand.php @@ -114,10 +114,12 @@ class ExpiredRefundedBookingCommand extends Command // check if the booking is fully refund $amountDifference = bcsub($transaction->amount, $bookingPaymentAmount, 7); + $isFullyRefund = false; if (abs($amountDifference) < 0.01) { - // rejecting booking payment transaction - // $bookingPayment->status = ApprovalStatus::REJECTED; - // $bookingPayment->save(); + $isFullyRefund = true; + // update fully refunded booking payment transaction + $bookingPayment->status = ApprovalStatus::REFUNDED; + $bookingPayment->save(); //expired booking // $this->updatesBookingStatus->execute($booking, ApprovalStatus::EXPIRED); @@ -136,16 +138,12 @@ class ExpiredRefundedBookingCommand extends Command Log::info("Credit note transaction id: {$transaction->id}, already created same amount of refund transaction for same booking payment transaction"); } - if ($bookingInWhiteForm) { - Log::info("Credit note transaction id: {$transaction->id}, booking is in white form"); - } - if (!$refund) { $billNumber = $this->generatesTransactionBillNumber->execute('RFD-'); $object = new TransactionObject($billNumber, TransactionType::REFUND, 1, $booking->company->id, 1, PaymentMethodType::CASH, - $transaction->amount, $transaction->amount * $bookingPayment->currency_rate, 1, + $transaction->amount, $isFullyRefund ? $bookingPayment->original_amount : $transaction->amount * $bookingPayment->currency_rate, 1, $bookingPayment->original_currency_id, $bookingPayment->currency_rate, 0, 0, null, ApprovalStatus::APPROVED, [], $bookingPayment->bill_no); @@ -153,15 +151,24 @@ class ExpiredRefundedBookingCommand extends Command } if ($bookingInWhiteForm) { - $refund = $bookingPayment->transactions()->supplierRefunds()->where('amount', $transaction->amount)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->first(); + $original_amount = $isFullyRefund ? $bookingPayment->original_amount : bcmul($transaction->amount, $bookingPayment->currency_rate, 7); + $supplier_refund_amount = bcdiv($original_amount, $bookingInWhiteForm->currency_rate, 7); + + Log::info("Credit note transaction id: {$transaction->id}, booking is in white form, white form currency rate is {$bookingInWhiteForm->currency_rate}"); + + // if ($isFullyRefund && $bookingInWhiteForm->currency_rate == 1) { + // dd ($bookingInWhiteForm->owner_id); + // } + + $refund = $bookingPayment->transactions()->supplierRefunds()->where('original_amount', $original_amount)->first(); if (!$refund) { $billNumber = $this->generatesTransactionBillNumber->execute('SRFD-'); - $object = new TransactionObject($billNumber, TransactionType::SUPPLIER_REFUND, 1, $booking->company->id, + $object = new TransactionObject($billNumber, TransactionType::SUPPLIER_REFUND, 1, $bookingInWhiteForm->issuer, 1, PaymentMethodType::CASH, - $transaction->amount, $transaction->amount * $bookingPayment->currency_rate, 1, - $bookingPayment->original_currency_id, $bookingPayment->currency_rate, + $supplier_refund_amount, $original_amount, 1, + $bookingPayment->original_currency_id, $bookingInWhiteForm->currency_rate, 0, 0, null, ApprovalStatus::APPROVED, [], $bookingPayment->bill_no); $transaction = $this->createsTransaction->execute($bookingPayment, $object); diff --git a/resources/assets/vue/components/bookings/forms/SupplierWhiteFormPlaceOrderFormComponent.vue b/resources/assets/vue/components/bookings/forms/SupplierWhiteFormPlaceOrderFormComponent.vue index 4ca36c2e..01c099ed 100644 --- a/resources/assets/vue/components/bookings/forms/SupplierWhiteFormPlaceOrderFormComponent.vue +++ b/resources/assets/vue/components/bookings/forms/SupplierWhiteFormPlaceOrderFormComponent.vue @@ -108,7 +108,7 @@
Supplier Refund
- + From ca2f41e95c5d61a172c9a98e10476bc6ca5827b6 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Fri, 1 Mar 2024 08:16:54 +0800 Subject: [PATCH 114/434] fix bug for payment transaction not found after status update to refunded --- .../ExpiredRefundedBookingCommand.php | 124 ++++++++++-------- 1 file changed, 68 insertions(+), 56 deletions(-) diff --git a/app/Console/Commands/ExpiredRefundedBookingCommand.php b/app/Console/Commands/ExpiredRefundedBookingCommand.php index d64cf385..87f44f81 100644 --- a/app/Console/Commands/ExpiredRefundedBookingCommand.php +++ b/app/Console/Commands/ExpiredRefundedBookingCommand.php @@ -107,72 +107,84 @@ class ExpiredRefundedBookingCommand extends Command if (!$bookingPayment) { $bookingPayment = $booking->transactions()->payments()->whereIn('status', [ApprovalStatus::SUSPENDED, ApprovalStatus::EXPIRED, ApprovalStatus::REJECTED])->orderBy('id', 'DESC')->first(); } + } + + if ($bookingPayment) { $status = ApprovalStatus::APPROVAL_STATUS_ID[$bookingPayment->status]; Log::info("Credit note transaction id: {$transaction->id}, the payment for the booking is in status {$status}"); - } - $bookingPaymentAmount = $bookingPayment->amount; - // check if the booking is fully refund - $amountDifference = bcsub($transaction->amount, $bookingPaymentAmount, 7); - $isFullyRefund = false; - if (abs($amountDifference) < 0.01) { - $isFullyRefund = true; - // update fully refunded booking payment transaction - $bookingPayment->status = ApprovalStatus::REFUNDED; - $bookingPayment->save(); - - //expired booking - // $this->updatesBookingStatus->execute($booking, ApprovalStatus::EXPIRED); - Log::info("Credit note transaction id: {$transaction->id} is fully refunded, the refunded amount was {$transaction->amount} the payment reference is: {$transaction->payment_reference}"); - // Log::info("Credit note transaction id: {$transaction->id}, Rejected Booking Transaction Payment id: {$bookingPayment->id}, the payment amount was {$bookingPayment->amount}"); - // Log::info("Credit note transaction id: {$transaction->id}, Expired Booking id: {$booking->id}"); - } else { - Log::info("Credit note transaction id: {$transaction->id} is not fully refunded, the refunded amount was {$transaction->amount}, the payment amount was {$bookingPayment->amount}, the payment reference is: {$transaction->payment_reference}"); - } - - $refund = $bookingPayment->transactions()->refunds()->where('amount', $transaction->amount)->where('status', ApprovalStatus::APPROVED)->first(); - - $bookingInWhiteForm = $bookingPayment->transactions()->bills()->first(); - - if ($refund) { - Log::info("Credit note transaction id: {$transaction->id}, already created same amount of refund transaction for same booking payment transaction"); - } - - if (!$refund) { - $billNumber = $this->generatesTransactionBillNumber->execute('RFD-'); - - $object = new TransactionObject($billNumber, TransactionType::REFUND, 1, $booking->company->id, - 1, PaymentMethodType::CASH, - $transaction->amount, $isFullyRefund ? $bookingPayment->original_amount : $transaction->amount * $bookingPayment->currency_rate, 1, - $bookingPayment->original_currency_id, $bookingPayment->currency_rate, - 0, 0, null, ApprovalStatus::APPROVED, [], $bookingPayment->bill_no); + $bookingPaymentAmount = $bookingPayment->amount; + // check if the booking is fully refund + $amountDifference = bcsub($transaction->amount, $bookingPaymentAmount, 7); + + $isFullyRefund = false; + if (abs($amountDifference) < 0.01) { + $isFullyRefund = true; + // update fully refunded booking payment transaction + $bookingPayment->status = ApprovalStatus::REFUNDED; + $bookingPayment->save(); + + //expired booking + // $this->updatesBookingStatus->execute($booking, ApprovalStatus::EXPIRED); + Log::info("Credit note transaction id: {$transaction->id} is fully refunded, the refunded amount was {$transaction->amount} the payment reference is: {$transaction->payment_reference}"); + // Log::info("Credit note transaction id: {$transaction->id}, Rejected Booking Transaction Payment id: {$bookingPayment->id}, the payment amount was {$bookingPayment->amount}"); + // Log::info("Credit note transaction id: {$transaction->id}, Expired Booking id: {$booking->id}"); + } else { + Log::info("Credit note transaction id: {$transaction->id} is not fully refunded, the refunded amount was {$transaction->amount}, the payment amount was {$bookingPayment->amount}, the payment reference is: {$transaction->payment_reference}"); + } + + $refund = $bookingPayment->transactions()->refunds()->where('amount', $transaction->amount)->where('status', ApprovalStatus::APPROVED)->first(); + + $bookingInWhiteForm = $bookingPayment->transactions()->bills()->first(); + + if ($refund) { + Log::info("Credit note transaction id: {$transaction->id}, already created same amount of refund transaction for same booking payment transaction"); + } - $transaction = $this->createsTransaction->execute($bookingPayment, $object); - } - - if ($bookingInWhiteForm) { - $original_amount = $isFullyRefund ? $bookingPayment->original_amount : bcmul($transaction->amount, $bookingPayment->currency_rate, 7); - $supplier_refund_amount = bcdiv($original_amount, $bookingInWhiteForm->currency_rate, 7); - - Log::info("Credit note transaction id: {$transaction->id}, booking is in white form, white form currency rate is {$bookingInWhiteForm->currency_rate}"); - - // if ($isFullyRefund && $bookingInWhiteForm->currency_rate == 1) { - // dd ($bookingInWhiteForm->owner_id); - // } - - $refund = $bookingPayment->transactions()->supplierRefunds()->where('original_amount', $original_amount)->first(); - if (!$refund) { - $billNumber = $this->generatesTransactionBillNumber->execute('SRFD-'); - - $object = new TransactionObject($billNumber, TransactionType::SUPPLIER_REFUND, 1, $bookingInWhiteForm->issuer, + $billNumber = $this->generatesTransactionBillNumber->execute('RFD-'); + + $object = new TransactionObject($billNumber, TransactionType::REFUND, 1, $booking->company->id, 1, PaymentMethodType::CASH, - $supplier_refund_amount, $original_amount, 1, - $bookingPayment->original_currency_id, $bookingInWhiteForm->currency_rate, + $transaction->amount, $isFullyRefund ? $bookingPayment->original_amount : $transaction->amount * $bookingPayment->currency_rate, 1, + $bookingPayment->original_currency_id, $bookingPayment->currency_rate, 0, 0, null, ApprovalStatus::APPROVED, [], $bookingPayment->bill_no); $transaction = $this->createsTransaction->execute($bookingPayment, $object); } + + if ($bookingInWhiteForm) { + $original_amount = $isFullyRefund ? $bookingPayment->original_amount : bcmul($transaction->amount, $bookingPayment->currency_rate, 7); + $supplier_refund_amount = bcdiv($original_amount, $bookingInWhiteForm->currency_rate, 7); + + Log::info("Credit note transaction id: {$transaction->id}, booking is in white form, white form currency rate is {$bookingInWhiteForm->currency_rate}"); + + // if ($isFullyRefund && $bookingInWhiteForm->currency_rate == 1) { + // dd ($bookingInWhiteForm->owner_id); + // } + + $refund = $bookingPayment->transactions()->supplierRefunds()->where('original_amount', $original_amount)->first(); + + if (!$refund) { + $billNumber = $this->generatesTransactionBillNumber->execute('SRFD-'); + + $object = new TransactionObject($billNumber, TransactionType::SUPPLIER_REFUND, 1, $bookingInWhiteForm->issuer, + 1, PaymentMethodType::CASH, + $supplier_refund_amount, $original_amount, 1, + $bookingPayment->original_currency_id, $bookingInWhiteForm->currency_rate, + 0, 0, null, ApprovalStatus::APPROVED, [], $bookingPayment->bill_no); + + $transaction = $this->createsTransaction->execute($bookingPayment, $object); + } + } + } else { + // $bookingPayment = $booking->transactions()->payments()->where('status', ApprovalStatus::REFUNDED)->orderBy('id', 'DESC')->first(); + + // if ($bookingPayment) { + // Log::info("Credit note transaction id: {$transaction->id}, booking payment refunded"); + // } else { + Log::info("Credit note transaction id: {$transaction->id}, booking payment not found, the payment reference is: {$transaction->payment_reference}"); + // } } } else { Log::info("Credit note transaction id: {$transaction->id}, booking marking not found, the payment reference is: {$transaction->payment_reference}"); From efb909555e0a3edbf15eb95083a1b5a4994400e4 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Fri, 1 Mar 2024 14:28:52 +0800 Subject: [PATCH 115/434] debug payment not showing issue --- routes/web.php | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/routes/web.php b/routes/web.php index a6590c17..1fb2878f 100644 --- a/routes/web.php +++ b/routes/web.php @@ -866,3 +866,55 @@ Route::get('/invoice/{marking}/{started_at}/{ended_at}/fix', function($marking, } ); })->name('invoice.fix.byCustomerMarking'); + +Route::get('/transfer/{marking}/payment-details', function ($marking) { + $booking = Booking::where('marking', $marking)->first(); + + $transactions = $booking->transactions()->withTrashed()->get(); + + $statusLabels = [ + 0 => 'PAYMENT_ATTEMPT', + 1 => 'PAYMENT', + 2 => 'INVOICE', + 3 => 'BILL', + 4 => 'PROFORMA', + 5 => 'TOP_UP', + 6 => 'REFUND', + 7 => 'PURCHASE_ORDER', + 8 => 'SUPPLIER_DELIVER', + 9 => 'CREDIT_NOTE', + 10 => 'WITHDRAW', + 11 => 'DEBIT_NOTE', + 12 => 'TRANSFER_FEE', + 13 => 'CASH_BACK', + ]; + + $ApprovalStatus = ApprovalStatus::APPROVAL_STATUS_ID; + + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + + foreach ($transactions as $transaction) { + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + } + + echo ''; + echo '
IDAmountTypeStatusCreated AtDeleted At
' . $transaction->id . '' . $transaction->amount . '' . $statusLabels[$transaction->type] . '' . $ApprovalStatus [$transaction->status] . '' . $transaction->created_at . '' . $transaction->deleted_at . '
'; +}); From 5cf55453fd690186aa03413add24a54d38805a3e Mon Sep 17 00:00:00 2001 From: edmondlang Date: Fri, 1 Mar 2024 21:57:06 +0800 Subject: [PATCH 116/434] show-booking-expired for debug payment not showing --- app/Console/Kernel.php | 12 ++++---- routes/web.php | 70 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 6 deletions(-) diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 5e9aa8a8..d1f54f52 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -44,13 +44,13 @@ class Kernel extends ConsoleKernel ->appendOutputTo(storage_path().'/logs/delete-bulk-download-files.log') ->withoutOverlapping(); - $schedule->command('booking:expired') - ->dailyAt('02:00') - ->withoutOverlapping(); + // $schedule->command('booking:expired') + // ->dailyAt('02:00') + // ->withoutOverlapping(); - $schedule->command('purchaseOrder:autoFill') - ->dailyAt('03:00') - ->withoutOverlapping(); + // $schedule->command('purchaseOrder:autoFill') + // ->dailyAt('03:00') + // ->withoutOverlapping(); } /** diff --git a/routes/web.php b/routes/web.php index 1fb2878f..44380046 100644 --- a/routes/web.php +++ b/routes/web.php @@ -872,6 +872,8 @@ Route::get('/transfer/{marking}/payment-details', function ($marking) { $transactions = $booking->transactions()->withTrashed()->get(); + $paymentMethods = PaymentMethodType::PAYMENT_METHODS_ID; + $statusLabels = [ 0 => 'PAYMENT_ATTEMPT', 1 => 'PAYMENT', @@ -898,6 +900,7 @@ Route::get('/transfer/{marking}/payment-details', function ($marking) { echo 'Amount'; echo 'Type'; echo 'Status'; + echo 'Payment Method'; echo 'Created At'; echo 'Deleted At'; echo ''; @@ -910,6 +913,7 @@ Route::get('/transfer/{marking}/payment-details', function ($marking) { echo '' . $transaction->amount . ''; echo '' . $statusLabels[$transaction->type] . ''; echo '' . $ApprovalStatus [$transaction->status] . ''; + echo '' . $paymentMethods [$transaction->payment_method] . ''; echo '' . $transaction->created_at . ''; echo '' . $transaction->deleted_at . ''; echo ''; @@ -917,4 +921,70 @@ Route::get('/transfer/{marking}/payment-details', function ($marking) { echo ''; echo ''; + + echo '
'; + echo 'Wallet Details'; + +})->name('booking.details.transactions'); + +Route::get('show-booking-expired', function () { + $transactions = Transaction::where('type', TransactionType::PAYMENT) + ->where('status', ApprovalStatus::EXPIRED) + ->whereDate('updated_at', '>=', '2024-02-16') + ->orderBy('updated_at', 'desc') + ->get(); + // print_r(count($transactions)); + + + $statusLabels = [ + 0 => 'PAYMENT_ATTEMPT', + 1 => 'PAYMENT', + 2 => 'INVOICE', + 3 => 'BILL', + 4 => 'PROFORMA', + 5 => 'TOP_UP', + 6 => 'REFUND', + 7 => 'PURCHASE_ORDER', + 8 => 'SUPPLIER_DELIVER', + 9 => 'CREDIT_NOTE', + 10 => 'WITHDRAW', + 11 => 'DEBIT_NOTE', + 12 => 'TRANSFER_FEE', + 13 => 'CASH_BACK', + ]; + + $ApprovalStatus = ApprovalStatus::APPROVAL_STATUS_ID; + + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + + $counter = 1; + + foreach ($transactions as $transaction) { + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + } + + echo ''; + echo '
CounterIDBookingPaymentsAmountTypeStatusUpdated At
' . $counter++ . '' . $transaction->id . '' . ''.$transaction->owner->marking.'' . '' . 'Payments' . '' . $transaction->amount . '' . $statusLabels[$transaction->type] . '' . $ApprovalStatus [$transaction->status] . '' . $transaction->updated_at . '
'; }); From dfc2ddd09b8809b5db806139d92e4ddc333c2f6f Mon Sep 17 00:00:00 2001 From: edmondlang Date: Fri, 1 Mar 2024 22:49:14 +0800 Subject: [PATCH 117/434] debug payment not showing issue --- routes/web.php | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/routes/web.php b/routes/web.php index 44380046..ddc5ae7e 100644 --- a/routes/web.php +++ b/routes/web.php @@ -922,8 +922,10 @@ Route::get('/transfer/{marking}/payment-details', function ($marking) { echo ''; echo ''; - echo '
'; - echo 'Wallet Details'; + echo '
----------------------------------------------------------------
'; + + echo 'Wallet Details'; + })->name('booking.details.transactions'); @@ -931,6 +933,7 @@ Route::get('show-booking-expired', function () { $transactions = Transaction::where('type', TransactionType::PAYMENT) ->where('status', ApprovalStatus::EXPIRED) ->whereDate('updated_at', '>=', '2024-02-16') + ->take(10) ->orderBy('updated_at', 'desc') ->get(); // print_r(count($transactions)); @@ -954,6 +957,8 @@ Route::get('show-booking-expired', function () { ]; $ApprovalStatus = ApprovalStatus::APPROVAL_STATUS_ID; + + $paymentMethods = PaymentMethodType::PAYMENT_METHODS_ID; echo ''; echo ''; @@ -965,6 +970,8 @@ Route::get('show-booking-expired', function () { echo ''; echo ''; echo ''; + echo ''; + echo ''; echo ''; echo ''; echo ''; @@ -973,6 +980,23 @@ Route::get('show-booking-expired', function () { $counter = 1; foreach ($transactions as $transaction) { + + $billplz_status = null; + + if ($transaction->payment_method == PaymentMethodType::PAYMENT_GATEWAY) { + $response = Http::withBasicAuth(config('billplz.api_key') . ':', '')->get(config('billplz.base_url') . '/api/v3/bills/' . $transaction->payment_reference); + if ($response->successful()) { + $data = $response->json(); + if ($data['paid']) { + $billplz_status = 'Paid'; + } else { + $billplz_status = $transaction->id . " => Fraud"; + } + } else { + $billplz_status = $transaction->id . " => billplz error"; + } + } + echo ''; echo ''; echo ''; @@ -981,6 +1005,8 @@ Route::get('show-booking-expired', function () { echo ''; echo ''; echo ''; + echo ''; + echo ''; echo ''; echo ''; } From b2dd34106ccfea281d1bad2a6fde0e4a2a266a57 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Fri, 1 Mar 2024 22:51:56 +0800 Subject: [PATCH 118/434] debug payment not showing issue --- routes/web.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/routes/web.php b/routes/web.php index ddc5ae7e..bc6730f5 100644 --- a/routes/web.php +++ b/routes/web.php @@ -973,6 +973,7 @@ Route::get('show-booking-expired', function () { echo ''; echo ''; echo ''; + echo ''; echo ''; echo ''; echo ''; @@ -1008,6 +1009,7 @@ Route::get('show-booking-expired', function () { echo ''; echo ''; echo ''; + echo ''; echo ''; } From 42a399999a8edb965da5b5686467ea116f45bf4c Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Fri, 1 Mar 2024 23:28:14 +0800 Subject: [PATCH 119/434] uncomment and log to specific file for booking expired command --- app/Console/Commands/ExpiredBookingCommand.php | 8 ++++---- app/Console/Kernel.php | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/Console/Commands/ExpiredBookingCommand.php b/app/Console/Commands/ExpiredBookingCommand.php index 5779a9e9..2be39c15 100644 --- a/app/Console/Commands/ExpiredBookingCommand.php +++ b/app/Console/Commands/ExpiredBookingCommand.php @@ -62,14 +62,14 @@ class ExpiredBookingCommand extends Command foreach ($bookings as $booking) { $this->updatesBookingStatus->execute($booking, ApprovalStatus::EXPIRED); - Log::info("Expired Booking without payment & purchase order, booking id: " . $booking->id); + $this->info("Expired Booking without payment & purchase order, booking id: " . $booking->id); $transactions = $booking->transactions; foreach ($transactions as $transaction) { $prevStatus = $transaction->status; $transaction->status = ApprovalStatus::EXPIRED; $transaction->save(); - Log::info("Expired Transaction id: {$transaction->id} from Booking id: {$booking->id}. Status before update: {$prevStatus}"); + $this->info("Expired Transaction id: {$transaction->id} from Booking id: {$booking->id}. Status before update: {$prevStatus}"); } } @@ -86,14 +86,14 @@ class ExpiredBookingCommand extends Command foreach ($bookings as $booking) { $this->updatesBookingStatus->execute($booking, ApprovalStatus::EXPIRED); - Log::info("Expired Booking without payment but with purchase order, booking id: " . $booking->id); + $this->info("Expired Booking without payment but with purchase order, booking id: " . $booking->id); $transactions = $booking->transactions; foreach ($transactions as $transaction) { $prevStatus = $transaction->status; $transaction->status = ApprovalStatus::EXPIRED; $transaction->save(); - Log::info("Expired Transaction id: {$transaction->id} from Booking id: {$booking->id}. Status before update: {$prevStatus}"); + $this->info("Expired Transaction id: {$transaction->id} from Booking id: {$booking->id}. Status before update: {$prevStatus}"); } } } diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index d1f54f52..e455eea1 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -44,9 +44,10 @@ class Kernel extends ConsoleKernel ->appendOutputTo(storage_path().'/logs/delete-bulk-download-files.log') ->withoutOverlapping(); - // $schedule->command('booking:expired') - // ->dailyAt('02:00') - // ->withoutOverlapping(); + $schedule->command('booking:expired') + ->dailyAt('02:00') + ->appendOutputTo(storage_path().'/logs/expire-booking.log') + ->withoutOverlapping(); // $schedule->command('purchaseOrder:autoFill') // ->dailyAt('03:00') From 8b22b49937d5b66d1d6cf0c1b39f838e97c4e7a4 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Sat, 2 Mar 2024 00:25:00 +0800 Subject: [PATCH 120/434] remove testing code --- routes/web.php | 150 ------------------------------------------------- 1 file changed, 150 deletions(-) diff --git a/routes/web.php b/routes/web.php index bc6730f5..a6590c17 100644 --- a/routes/web.php +++ b/routes/web.php @@ -866,153 +866,3 @@ Route::get('/invoice/{marking}/{started_at}/{ended_at}/fix', function($marking, } ); })->name('invoice.fix.byCustomerMarking'); - -Route::get('/transfer/{marking}/payment-details', function ($marking) { - $booking = Booking::where('marking', $marking)->first(); - - $transactions = $booking->transactions()->withTrashed()->get(); - - $paymentMethods = PaymentMethodType::PAYMENT_METHODS_ID; - - $statusLabels = [ - 0 => 'PAYMENT_ATTEMPT', - 1 => 'PAYMENT', - 2 => 'INVOICE', - 3 => 'BILL', - 4 => 'PROFORMA', - 5 => 'TOP_UP', - 6 => 'REFUND', - 7 => 'PURCHASE_ORDER', - 8 => 'SUPPLIER_DELIVER', - 9 => 'CREDIT_NOTE', - 10 => 'WITHDRAW', - 11 => 'DEBIT_NOTE', - 12 => 'TRANSFER_FEE', - 13 => 'CASH_BACK', - ]; - - $ApprovalStatus = ApprovalStatus::APPROVAL_STATUS_ID; - - echo '
AmountTypeStatusPayment MethodBillPlz ResponseUpdated At
' . $counter++ . '' . $transaction->id . '' . $transaction->amount . '' . $statusLabels[$transaction->type] . '' . $ApprovalStatus [$transaction->status] . '' . $paymentMethods [$transaction->payment_method] . '' . $billplz_status . '' . $transaction->updated_at . '
Payment MethodBillPlz ResponseUpdated AtCreated At
' . $paymentMethods [$transaction->payment_method] . '' . $billplz_status . '' . $transaction->updated_at . '' . $transaction->created_at . '
'; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - - foreach ($transactions as $transaction) { - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - } - - echo ''; - echo '
IDAmountTypeStatusPayment MethodCreated AtDeleted At
' . $transaction->id . '' . $transaction->amount . '' . $statusLabels[$transaction->type] . '' . $ApprovalStatus [$transaction->status] . '' . $paymentMethods [$transaction->payment_method] . '' . $transaction->created_at . '' . $transaction->deleted_at . '
'; - - echo '
----------------------------------------------------------------
'; - - echo 'Wallet Details'; - - -})->name('booking.details.transactions'); - -Route::get('show-booking-expired', function () { - $transactions = Transaction::where('type', TransactionType::PAYMENT) - ->where('status', ApprovalStatus::EXPIRED) - ->whereDate('updated_at', '>=', '2024-02-16') - ->take(10) - ->orderBy('updated_at', 'desc') - ->get(); - // print_r(count($transactions)); - - - $statusLabels = [ - 0 => 'PAYMENT_ATTEMPT', - 1 => 'PAYMENT', - 2 => 'INVOICE', - 3 => 'BILL', - 4 => 'PROFORMA', - 5 => 'TOP_UP', - 6 => 'REFUND', - 7 => 'PURCHASE_ORDER', - 8 => 'SUPPLIER_DELIVER', - 9 => 'CREDIT_NOTE', - 10 => 'WITHDRAW', - 11 => 'DEBIT_NOTE', - 12 => 'TRANSFER_FEE', - 13 => 'CASH_BACK', - ]; - - $ApprovalStatus = ApprovalStatus::APPROVAL_STATUS_ID; - - $paymentMethods = PaymentMethodType::PAYMENT_METHODS_ID; - - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - - $counter = 1; - - foreach ($transactions as $transaction) { - - $billplz_status = null; - - if ($transaction->payment_method == PaymentMethodType::PAYMENT_GATEWAY) { - $response = Http::withBasicAuth(config('billplz.api_key') . ':', '')->get(config('billplz.base_url') . '/api/v3/bills/' . $transaction->payment_reference); - if ($response->successful()) { - $data = $response->json(); - if ($data['paid']) { - $billplz_status = 'Paid'; - } else { - $billplz_status = $transaction->id . " => Fraud"; - } - } else { - $billplz_status = $transaction->id . " => billplz error"; - } - } - - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - } - - echo ''; - echo '
CounterIDBookingPaymentsAmountTypeStatusPayment MethodBillPlz ResponseUpdated AtCreated At
' . $counter++ . '' . $transaction->id . '' . ''.$transaction->owner->marking.'' . '' . 'Payments' . '' . $transaction->amount . '' . $statusLabels[$transaction->type] . '' . $ApprovalStatus [$transaction->status] . '' . $paymentMethods [$transaction->payment_method] . '' . $billplz_status . '' . $transaction->updated_at . '' . $transaction->created_at . '
'; -}); From 2d5bbac3b1f5d21889f3a7846ae33e7f4b32a010 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Sat, 2 Mar 2024 00:32:55 +0800 Subject: [PATCH 121/434] update ExpiredBookingCommand logging - add timestamp --- app/Console/Commands/ExpiredBookingCommand.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/Console/Commands/ExpiredBookingCommand.php b/app/Console/Commands/ExpiredBookingCommand.php index 2be39c15..fe4f260e 100644 --- a/app/Console/Commands/ExpiredBookingCommand.php +++ b/app/Console/Commands/ExpiredBookingCommand.php @@ -62,14 +62,14 @@ class ExpiredBookingCommand extends Command foreach ($bookings as $booking) { $this->updatesBookingStatus->execute($booking, ApprovalStatus::EXPIRED); - $this->info("Expired Booking without payment & purchase order, booking id: " . $booking->id); + $this->info(Carbon::now() . " : Expired Booking without payment & purchase order, booking id: " . $booking->id); $transactions = $booking->transactions; foreach ($transactions as $transaction) { $prevStatus = $transaction->status; $transaction->status = ApprovalStatus::EXPIRED; $transaction->save(); - $this->info("Expired Transaction id: {$transaction->id} from Booking id: {$booking->id}. Status before update: {$prevStatus}"); + $this->info(Carbon::now() . " : Expired Transaction id: {$transaction->id} from Booking id: {$booking->id}. Status before update: {$prevStatus}"); } } @@ -86,14 +86,14 @@ class ExpiredBookingCommand extends Command foreach ($bookings as $booking) { $this->updatesBookingStatus->execute($booking, ApprovalStatus::EXPIRED); - $this->info("Expired Booking without payment but with purchase order, booking id: " . $booking->id); + $this->info(Carbon::now() . " : Expired Booking without payment but with purchase order, booking id: " . $booking->id); $transactions = $booking->transactions; foreach ($transactions as $transaction) { $prevStatus = $transaction->status; $transaction->status = ApprovalStatus::EXPIRED; $transaction->save(); - $this->info("Expired Transaction id: {$transaction->id} from Booking id: {$booking->id}. Status before update: {$prevStatus}"); + $this->info(Carbon::now() . " : Expired Transaction id: {$transaction->id} from Booking id: {$booking->id}. Status before update: {$prevStatus}"); } } } From 73819e967e34f00996b8a069e06010d71439dbd5 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Wed, 6 Mar 2024 20:56:24 +0800 Subject: [PATCH 122/434] open partial refund, categorize refunds section in dashboard --- .../Eloquent/Filters/IsPartialRefund.php | 26 ++++++++ .../OwnerDoesNotHaveTransactionType.php | 24 ++++++++ .../Filters/OwnerHasTransactionType.php | 24 ++++++++ .../elements/RefundConfirmationComponent.vue | 10 ++- .../views/pages/dashboards/admin.blade.php | 61 ++++++++++++++++++- 5 files changed, 137 insertions(+), 8 deletions(-) create mode 100644 app/Classes/General/Eloquent/Filters/IsPartialRefund.php create mode 100644 app/Classes/General/Eloquent/Filters/OwnerDoesNotHaveTransactionType.php create mode 100644 app/Classes/General/Eloquent/Filters/OwnerHasTransactionType.php diff --git a/app/Classes/General/Eloquent/Filters/IsPartialRefund.php b/app/Classes/General/Eloquent/Filters/IsPartialRefund.php new file mode 100644 index 00000000..1378a94c --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/IsPartialRefund.php @@ -0,0 +1,26 @@ +whereHas('owner', function ($q) use ($value) { + if ($value) { + $q->where('original_amount', '!=', DB::raw('transactions.original_amount')); + } else { + $q->where('original_amount', DB::raw('transactions.original_amount')); + } + }); + } +} diff --git a/app/Classes/General/Eloquent/Filters/OwnerDoesNotHaveTransactionType.php b/app/Classes/General/Eloquent/Filters/OwnerDoesNotHaveTransactionType.php new file mode 100644 index 00000000..4dcd401c --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/OwnerDoesNotHaveTransactionType.php @@ -0,0 +1,24 @@ +whereDoesntHave('owner', function($query) use($value) { + return $query->whereHas('transactions', function($query) use($value) { + return $query->where('transactions.type', $value); + }); + }); + } +} diff --git a/app/Classes/General/Eloquent/Filters/OwnerHasTransactionType.php b/app/Classes/General/Eloquent/Filters/OwnerHasTransactionType.php new file mode 100644 index 00000000..7f96643f --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/OwnerHasTransactionType.php @@ -0,0 +1,24 @@ +whereHas('owner', function($query) use($value) { + return $query->whereHas('transactions', function($query) use($value) { + return $query->where('transactions.type', $value); + }); + }); + } +} diff --git a/resources/assets/vue/components/bookings/elements/RefundConfirmationComponent.vue b/resources/assets/vue/components/bookings/elements/RefundConfirmationComponent.vue index 75253aaa..c87122a5 100644 --- a/resources/assets/vue/components/bookings/elements/RefundConfirmationComponent.vue +++ b/resources/assets/vue/components/bookings/elements/RefundConfirmationComponent.vue @@ -38,6 +38,7 @@
Paid Amount: {{ paidAmount }}
+
Paid Amount: {{ (Math.round((this.data.refunded_amount + Number.EPSILON) * 100) / 100).toFixed(2) }}
Refund Amount: {{ refundAmount }}
@@ -69,10 +70,11 @@ export default { }, data() { return { + refundAmount: (Math.round((this.data.original_amount - this.data.refunded_amount + Number.EPSILON) * 100) / 100).toFixed(2), refundMethod: { name: 'Fully Refund', status: false }, refundMethods: [ { name: 'Fully Refund', label: 'Full Refund' }, - // { name: 'Partially Refund', label: 'Partial Refund' } + { name: 'Partially Refund', label: 'Partial Refund' } ] } }, @@ -84,12 +86,8 @@ export default { } }, computed: { - refundAmount() { - // return (Math.round((this.data.booking.amount - this.totalRefunds + Number.EPSILON) * 100) / 100).toFixed(2); - return (Math.round((this.data.original_amount - this.data.refunded_amount + Number.EPSILON) * 100) / 100).toFixed(2); - }, refundMaxValue() { - return this.refundAmount; + return (Math.round((this.data.original_amount - this.data.refunded_amount + Number.EPSILON) * 100) / 100).toFixed(2); }, paidAmount() { return this.data.original_amount; diff --git a/resources/views/pages/dashboards/admin.blade.php b/resources/views/pages/dashboards/admin.blade.php index d7223cc0..7ccdb219 100644 --- a/resources/views/pages/dashboards/admin.blade.php +++ b/resources/views/pages/dashboards/admin.blade.php @@ -81,11 +81,68 @@
+
+
+ Pre-Refund +
+
+
+
+ Fully Refund +
+
- + + +
+
+
+
+ Partial Refund +
+
+
+
+ + + +
+
+
+
+ Post-Refund +
+
+
+
+ Fully Refund +
+
+
+
+ + + +
+
+
+
+ Partial Refund +
+
+
+
+ +
From df7f9531e82ca8fcc3750318716cbd4d7f816cf1 Mon Sep 17 00:00:00 2001 From: Omair Saleh Date: Thu, 7 Mar 2024 11:38:03 +0800 Subject: [PATCH 123/434] fix payment history display transfer status --- .../elements/PaymentHistoryComponent.vue | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue index 877ec248..90270fee 100644 --- a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue +++ b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue @@ -8,8 +8,17 @@
Status
-
- {{ item.status === 7 ? 'Refunded' : (item.status === 1 ? 'Processing Payment' : 'Transferred')}} +
+ {{ item.status === 1 ? 'Pending Verification' : item.status === 4 ? 'Rejected' : 'Processing Payment'}} +
+
+ {{ item.status === 1 ? 'Pending Verification' : item.status === 4 ? 'Rejected' : 'Processing Payment'}} +
+
+
+
Status
+
+ {{ item.status === 7 ? 'Refunded' : (item.status === 1 ? 'Pending Verification' : item.status === 4 ? 'Rejected' : 'Payment Approved')}}
{{ item.status === 1 ? 'Pending Verification' : item.status === 4 ? 'Rejected' : 'Processing Payment'}} @@ -18,7 +27,7 @@
Payment Amount
- {{item.currency.short_code}} {{(Math.round((item.amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}} + {{item.original_currency.short_code}} {{(Math.round((item.original_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
@@ -61,7 +70,7 @@
Status
-
+
{{ item.transaction_bill.status === 1 ? 'Processing Payment' : 'Transferred'}}
From 32224f6803cc36185e53387794063098b12bde8e Mon Sep 17 00:00:00 2001 From: Omair Saleh Date: Thu, 7 Mar 2024 11:43:19 +0800 Subject: [PATCH 124/434] fix payment history display transfer status --- .../bookings/elements/PaymentHistoryComponent.vue | 9 --------- 1 file changed, 9 deletions(-) diff --git a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue index 90270fee..1db22609 100644 --- a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue +++ b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue @@ -6,15 +6,6 @@
-
-
Status
-
- {{ item.status === 1 ? 'Pending Verification' : item.status === 4 ? 'Rejected' : 'Processing Payment'}} -
-
- {{ item.status === 1 ? 'Pending Verification' : item.status === 4 ? 'Rejected' : 'Processing Payment'}} -
-
Status
From 70300412467eeeb9b0877c6afb34877c8def563b Mon Sep 17 00:00:00 2001 From: Omair Saleh Date: Thu, 7 Mar 2024 11:46:46 +0800 Subject: [PATCH 125/434] fix payment history display transfer status --- .../components/bookings/elements/PaymentHistoryComponent.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue index 1db22609..a6556cd2 100644 --- a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue +++ b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue @@ -61,7 +61,7 @@
Status
-
+
{{ item.transaction_bill.status === 1 ? 'Processing Payment' : 'Transferred'}}
From b0e3467fbe40bf1590a041509511eb5e7fc60412 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Thu, 7 Mar 2024 15:41:21 +0800 Subject: [PATCH 126/434] export pending order should not export order with refund in progress --- routes/web.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/routes/web.php b/routes/web.php index a6590c17..9016724c 100644 --- a/routes/web.php +++ b/routes/web.php @@ -386,7 +386,11 @@ Route::get('/segments', function (Request $request) { })->name('segments'); Route::get('/pending_orders', function(){ - $payments = Transaction::where('type', TransactionType::PAYMENT)->where('owner_type', Booking::class)->whereIn('status', [ApprovalStatus::APPROVED])->get(); + $payments = Transaction::where('type', TransactionType::PAYMENT)->where('owner_type', Booking::class)->whereIn('status', [ApprovalStatus::APPROVED]) + ->whereDoesntHave('transactions', function ($query) { + return $query->where('type', TransactionType::REFUND)->whereIn('status', [ApprovalStatus::PENDING_SUBMISSION, ApprovalStatus::PENDING_VERIFICATION]); + }) + ->get(); echo ''; $i = 0; From 4d501c8b7c3a27a9104a6947ccd6ca236bda3c90 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Thu, 7 Mar 2024 17:21:18 +0800 Subject: [PATCH 127/434] update log info --- .../ExpiredRefundedBookingCommand.php | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/app/Console/Commands/ExpiredRefundedBookingCommand.php b/app/Console/Commands/ExpiredRefundedBookingCommand.php index 87f44f81..92900a71 100644 --- a/app/Console/Commands/ExpiredRefundedBookingCommand.php +++ b/app/Console/Commands/ExpiredRefundedBookingCommand.php @@ -95,7 +95,7 @@ class ExpiredRefundedBookingCommand extends Command if (!$bookingPayment) { $bookingPaymentCount = $booking->transactions()->payments()->count(); if ($bookingPaymentCount > 1) { - Log::info("Credit note transaction id: {$transaction->id}, there are {$bookingPaymentCount} payment for the booking."); + $this->info("Credit note transaction id: {$transaction->id}, there are {$bookingPaymentCount} payment for the booking."); foreach ($booking->transactions()->payments()->get() as $bp) { if ($transaction->amount - $bp->amount < 0.01) { $bookingPayment = $bp; @@ -111,7 +111,7 @@ class ExpiredRefundedBookingCommand extends Command if ($bookingPayment) { $status = ApprovalStatus::APPROVAL_STATUS_ID[$bookingPayment->status]; - Log::info("Credit note transaction id: {$transaction->id}, the payment for the booking is in status {$status}"); + $this->info("Credit note transaction id: {$transaction->id}, the payment for the booking is in status {$status}"); $bookingPaymentAmount = $bookingPayment->amount; // check if the booking is fully refund @@ -126,11 +126,11 @@ class ExpiredRefundedBookingCommand extends Command //expired booking // $this->updatesBookingStatus->execute($booking, ApprovalStatus::EXPIRED); - Log::info("Credit note transaction id: {$transaction->id} is fully refunded, the refunded amount was {$transaction->amount} the payment reference is: {$transaction->payment_reference}"); - // Log::info("Credit note transaction id: {$transaction->id}, Rejected Booking Transaction Payment id: {$bookingPayment->id}, the payment amount was {$bookingPayment->amount}"); - // Log::info("Credit note transaction id: {$transaction->id}, Expired Booking id: {$booking->id}"); + $this->info("Credit note transaction id: {$transaction->id} is fully refunded, the refunded amount was {$transaction->amount} the payment reference is: {$transaction->payment_reference}"); + // $this->info("Credit note transaction id: {$transaction->id}, Rejected Booking Transaction Payment id: {$bookingPayment->id}, the payment amount was {$bookingPayment->amount}"); + // $this->info("Credit note transaction id: {$transaction->id}, Expired Booking id: {$booking->id}"); } else { - Log::info("Credit note transaction id: {$transaction->id} is not fully refunded, the refunded amount was {$transaction->amount}, the payment amount was {$bookingPayment->amount}, the payment reference is: {$transaction->payment_reference}"); + $this->info("Credit note transaction id: {$transaction->id} is not fully refunded, the refunded amount was {$transaction->amount}, the payment amount was {$bookingPayment->amount}, the payment reference is: {$transaction->payment_reference}"); } $refund = $bookingPayment->transactions()->refunds()->where('amount', $transaction->amount)->where('status', ApprovalStatus::APPROVED)->first(); @@ -138,7 +138,7 @@ class ExpiredRefundedBookingCommand extends Command $bookingInWhiteForm = $bookingPayment->transactions()->bills()->first(); if ($refund) { - Log::info("Credit note transaction id: {$transaction->id}, already created same amount of refund transaction for same booking payment transaction"); + $this->info("Credit note transaction id: {$transaction->id}, already created same amount of refund transaction for same booking payment transaction"); } if (!$refund) { @@ -157,7 +157,7 @@ class ExpiredRefundedBookingCommand extends Command $original_amount = $isFullyRefund ? $bookingPayment->original_amount : bcmul($transaction->amount, $bookingPayment->currency_rate, 7); $supplier_refund_amount = bcdiv($original_amount, $bookingInWhiteForm->currency_rate, 7); - Log::info("Credit note transaction id: {$transaction->id}, booking is in white form, white form currency rate is {$bookingInWhiteForm->currency_rate}"); + $this->info("Credit note transaction id: {$transaction->id}, booking is in white form, white form currency rate is {$bookingInWhiteForm->currency_rate}"); // if ($isFullyRefund && $bookingInWhiteForm->currency_rate == 1) { // dd ($bookingInWhiteForm->owner_id); @@ -181,16 +181,16 @@ class ExpiredRefundedBookingCommand extends Command // $bookingPayment = $booking->transactions()->payments()->where('status', ApprovalStatus::REFUNDED)->orderBy('id', 'DESC')->first(); // if ($bookingPayment) { - // Log::info("Credit note transaction id: {$transaction->id}, booking payment refunded"); + // $this->info("Credit note transaction id: {$transaction->id}, booking payment refunded"); // } else { - Log::info("Credit note transaction id: {$transaction->id}, booking payment not found, the payment reference is: {$transaction->payment_reference}"); + $this->info("Credit note transaction id: {$transaction->id}, booking payment not found, the payment reference is: {$transaction->payment_reference}"); // } } } else { - Log::info("Credit note transaction id: {$transaction->id}, booking marking not found, the payment reference is: {$transaction->payment_reference}"); + $this->info("Credit note transaction id: {$transaction->id}, booking marking not found, the payment reference is: {$transaction->payment_reference}"); } } else { - Log::info("Credit note transaction id: {$transaction->id} does not have booking marking, the payment reference is: {$transaction->payment_reference}"); + $this->info("Credit note transaction id: {$transaction->id} does not have booking marking, the payment reference is: {$transaction->payment_reference}"); } } } From 6d8cce464c2ee568bdeaf24a08692843b3e7d61b Mon Sep 17 00:00:00 2001 From: Omair Saleh Date: Fri, 8 Mar 2024 03:08:21 +0800 Subject: [PATCH 128/434] don't paginate the pending currency order page --- .../bookings/sections/SupplierPendingOrdersSectionComponent.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/assets/vue/components/bookings/sections/SupplierPendingOrdersSectionComponent.vue b/resources/assets/vue/components/bookings/sections/SupplierPendingOrdersSectionComponent.vue index 8f6fb8c7..fb766fe4 100644 --- a/resources/assets/vue/components/bookings/sections/SupplierPendingOrdersSectionComponent.vue +++ b/resources/assets/vue/components/bookings/sections/SupplierPendingOrdersSectionComponent.vue @@ -202,7 +202,7 @@ // todo-refund: activate this for partial refund // this.$refs.pendingOrdersList.updateFilters({per_page: 10000, status: 2, type: 1, original_currency_id_in: [this.selectedCurrency.id], transaction_service_id: this.selectedService.id, is_not_fully_refunded: true}); - this.$refs.pendingOrdersList.updateFilters({per_page: 10, status: 2, type: 1, original_currency_id_in: [this.selectedCurrency.id], transaction_service_id: this.selectedService.id, does_not_have_refund_in_progress: true}); + this.$refs.pendingOrdersList.updateFilters({per_page: 10000, status: 2, type: 1, original_currency_id_in: [this.selectedCurrency.id], transaction_service_id: this.selectedService.id, does_not_have_refund_in_progress: true}); this.selectedSupplier.status = false; this.currencyDropdownLaunch.status = false; From 2d34b157f59a2256cd7623770214634f26cfc6f5 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Mon, 11 Mar 2024 01:00:38 +0800 Subject: [PATCH 129/434] update refund section to have 2 tabs, where each tab categorized by full and partial refund --- .../views/pages/dashboards/admin.blade.php | 49 ++++++++++++------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/resources/views/pages/dashboards/admin.blade.php b/resources/views/pages/dashboards/admin.blade.php index 7ccdb219..ac5b1d08 100644 --- a/resources/views/pages/dashboards/admin.blade.php +++ b/resources/views/pages/dashboards/admin.blade.php @@ -27,7 +27,7 @@
-
+
-
Refunds
+
Pre-Refunds
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
Post-Refunds
@@ -79,15 +98,10 @@
-
+
- Pre-Refund -
-
-
-
Fully Refund
@@ -100,8 +114,8 @@
-
-
+
+
Partial Refund
@@ -114,13 +128,12 @@
-
+
+
+
+
+
- Post-Refund -
-
-
-
Fully Refund
@@ -133,8 +146,8 @@
-
-
+
+
Partial Refund
From 626bec90d2381ca7ea1b3f61bd5f739c2434a331 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Mon, 11 Mar 2024 01:14:40 +0800 Subject: [PATCH 130/434] update export pending order so that partial refund booking show correct amount --- routes/web.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/routes/web.php b/routes/web.php index 9016724c..ef5538ab 100644 --- a/routes/web.php +++ b/routes/web.php @@ -25,6 +25,7 @@ use Spatie\Activitylog\Models\Activity; 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\Bookings\Services\CalculatesBookingRefundAmount; use App\Classes\Modules\Documents\Services\DeletesDocument; use App\Classes\Modules\Transactions\Processors\CreateInvoiceTransactionWithInvoiceNoProcessor; use App\Classes\Modules\Transactions\Services\DeletesTransaction; @@ -396,6 +397,8 @@ Route::get('/pending_orders', function(){ $i = 0; foreach ($payments as $payment){ $booking = $payment->owner; + $original_refunds = floatval((App()->make(CalculatesBookingRefundAmount::class))->calculateRefundAmount($payment, $booking->fix_currency_id)); + $refunds = $original_refunds / $payment->currency_rate; if(!$booking instanceof Booking){ dd($payment); } @@ -411,11 +414,11 @@ Route::get('/pending_orders', function(){ echo '
'; echo ''; echo ''; - echo ''; + echo ''; echo ''; echo ''; echo ''; - echo ''; + echo ''; echo ''; echo ''; echo ''; From a1bbc69ec51c87695d7da30eb34bf9c91d4f4d37 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Mon, 11 Mar 2024 22:13:01 +0800 Subject: [PATCH 131/434] -update payment amount under payment history section on booking page -export approved refund payment --- .../elements/PaymentHistoryComponent.vue | 16 +++-- routes/web.php | 59 +++++++++++++++++++ 2 files changed, 66 insertions(+), 9 deletions(-) diff --git a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue index 68213ea2..f3b3fb38 100644 --- a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue +++ b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue @@ -18,13 +18,13 @@
Payment Amount
- {{item.original_currency.short_code}} {{(Math.round((item.original_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}} + {{item.original_currency.short_code}} {{(Math.round((item.original_amount - item.refunded_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
Refunded Amount
- {{item.currency.short_code}} {{(Math.round((totalConvertRefunds + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}} + {{item.original_currency.short_code}} {{(Math.round((item.refunded_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
@@ -68,15 +68,13 @@
Payment Amount
- {{item.original_currency.short_code}} {{(Math.round((item.original_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}} + {{item.original_currency.short_code}} {{(Math.round((item.original_amount - item.refunded_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
-
-
-
Refunded Amount
-
-
-
{{item.original_currency.short_code}} {{(Math.round((totalRefunds + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
+
+
Refunded Amount
+
+ {{item.original_currency.short_code}} {{(Math.round((totalRefunds + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
diff --git a/routes/web.php b/routes/web.php index bc613043..2370a7fc 100644 --- a/routes/web.php +++ b/routes/web.php @@ -433,6 +433,65 @@ Route::get('/pending_orders', function(){ echo '
'.$booking->marking.''.\App\Classes\ValueObjects\Constants\PaymentMethodType::PAYMENT_METHODS_ID[$payment->payment_method].''.$payment->currency->short_code.''.$payment->amount.''.number_format(bcsub($payment->amount, $refunds, 7), 5, '.', '').''.$booking->company->reference.''.$payment->original_currency->short_code.''.$payment->original_amount.''.number_format(bcsub($payment->original_amount, $original_refunds, 7), 5, '.', '').''.$booking->service->name.''.$payment->updated_at->diffForHumans().'
'; })->name('orders.pending'); +Route::get('/approve_refunds', function(){ + $payments = Transaction::where('type', TransactionType::PAYMENT)->where('owner_type', Booking::class)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED, ApprovalStatus::REFUNDED]) + ->whereHas('transactions', function ($query) { + return $query->where('type', TransactionType::REFUND)->where('status', ApprovalStatus::APPROVED); + }) + ->orderBy('updated_at', 'DESC') + ->get(); + + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + foreach ($payments as $index => $payment){ + $booking = $payment->owner; + $original_refunds = floatval((App()->make(CalculatesBookingRefundAmount::class))->calculateRefundAmount($payment, $booking->fix_currency_id)); + $refunds = $original_refunds / $payment->currency_rate; + if(!$booking instanceof Booking){ + dd($payment); + } + $bankType = str::length($booking->bank->holder_name) > 4 ? 'Company' : 'Personal'; + + if (!preg_match('/[^A-Za-z0-9]/', $booking->bank->holder_name)) + { + $bankType = str_word_count($booking->bank->holder_name) > 4 ? 'Company' : 'Personal'; + } + + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + } + echo '
No.Updated AtMarkingPayment MethodRefunded AmountCompany ReferenceRefunded Original AmountServiceLast Updated AtBank TypeBank Holder Name
'.($index + 1).'.'.$payment->updated_at->format('d-M-y').''.$booking->marking.''.\App\Classes\ValueObjects\Constants\PaymentMethodType::PAYMENT_METHODS_ID[$payment->payment_method].''.$payment->currency->short_code.''.number_format($refunds, 5, '.', '').''.$booking->company->reference.''.$payment->original_currency->short_code.''.number_format($original_refunds, 5, '.', '').''.$booking->service->name.''.$payment->updated_at->diffForHumans().''.$bankType.''.$booking->bank->holder_name.'
'; +})->name('orders.refunds'); + Route::get('/group/text/{id}', function($id){ $group = \App\Models\Group::where('id', $id)->first(); From 3cd2e244619ae33e537f9cc842c9194defc7e844 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Mon, 11 Mar 2024 22:18:10 +0800 Subject: [PATCH 132/434] add export refunded transactions button --- resources/views/pages/dashboards/admin.blade.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/resources/views/pages/dashboards/admin.blade.php b/resources/views/pages/dashboards/admin.blade.php index ac5b1d08..25a2500e 100644 --- a/resources/views/pages/dashboards/admin.blade.php +++ b/resources/views/pages/dashboards/admin.blade.php @@ -104,6 +104,11 @@
Fully Refund
+
@@ -136,6 +141,11 @@
Fully Refund
+
From b63cea4c09ced24e91cc21185c217c65d433d16e Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Tue, 12 Mar 2024 12:03:49 +0800 Subject: [PATCH 133/434] update purchase order amount and status upon refund approval --- .../UpdateRefundTransactionStatusLogic.php | 11 +++++++++-- .../bookings/forms/PurchaseOrderFormComponent.vue | 10 +++++----- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php index 02107a77..91b82f16 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php @@ -15,7 +15,7 @@ use Illuminate\Http\Request; use App\Classes\Modules\Wallets\Processors\CreditWalletProcessor; use App\Classes\Modules\Bookings\Services\CalculatesBookingPayableAmount; use App\Classes\Modules\Bookings\Services\CalculatesBookingRefundAmount; - +use App\Classes\ValueObjects\Constants\TransactionType; class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic { @@ -91,15 +91,22 @@ class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic $reference = $refundTransaction->amount == $paymentTransaction->amount ? 'Fully Refund for Ref. ' . $booking->marking : 'Partially Refund for Ref. ' . $booking->marking; + $refundAmount = $this->calculatesBookingRefundAmount->calculateRefundAmount($paymentTransaction, $booking->fix_currency_id); + if ($refundTransaction->status == ApprovalStatus::APPROVED) { $this->creditWalletProcessor->execute($booking->company, $refundTransaction->type, $refundTransaction->amount, $reference); + $po_transaction = $booking->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first(); + + if ($po_transaction) { + $this->updatesTransactionStatus->execute($po_transaction, (float) number_format($po_transaction->amount, 2, '.', '') === (float) number_format((float)$booking->fix_amount - $refundAmount, 2, '.', '') ? ApprovalStatus::PENDING_VERIFICATION : ApprovalStatus::PENDING_SUBMISSION); + } } if ($supplierRefundTransaction) { $this->updatesTransactionStatus->execute($supplierRefundTransaction, $request->route('status')); } - $paidAmount = $paymentTransaction->original_amount - $this->calculatesBookingRefundAmount->calculateRefundAmount($paymentTransaction, $booking->fix_currency_id); + $paidAmount = $paymentTransaction->original_amount - $refundAmount; if (!$paidAmount > 0) { $this->updatesTransactionStatus->execute($paymentTransaction, ApprovalStatus::REFUNDED); } diff --git a/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue b/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue index 9b8045f9..8df6cfe3 100644 --- a/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue +++ b/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue @@ -117,7 +117,7 @@
-
+
-
{{(Math.round(( poTotal + Number.EPSILON) * 1000) / 1000).toFixed(3)}}/{{(Math.round((data.amount + Number.EPSILON) * 1000) / 1000).toFixed(3)}} {{data.fixed_currency.short_code}}
+
{{(Math.round(( poTotal + Number.EPSILON) * 1000) / 1000).toFixed(3)}}/{{(Math.round((data.amount - data.payment_history[0].refunded_amount + Number.EPSILON) * 1000) / 1000).toFixed(3)}} {{data.fixed_currency.short_code}}
- +
-
+
** you purchase order will be saved but wont be approved until your purchase order's total matches your transfer order's total.
@@ -285,7 +285,7 @@ this.submit(route('api.transaction.po.import', this.data.id), 'post', this.section, true, true); }, successHandler(){ - if((Math.round((this.poTotal + Number.EPSILON) * 1000) / 1000).toFixed(3) === (Math.round((this.data.amount + Number.EPSILON) * 1000) / 1000).toFixed(3)){ + if((Math.round((this.poTotal + Number.EPSILON) * 1000) / 1000).toFixed(3) === (Math.round((this.data.amount - data.payment_history[0].refunded_amount + Number.EPSILON) * 1000) / 1000).toFixed(3)){ this.submitted = true; } this.updateList() From 36cde82a19ba93a70230105b2efcd9782f536ccd Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Thu, 14 Mar 2024 15:52:20 +0800 Subject: [PATCH 134/434] Send welcome email with voucher to user upon successful verification of customer email adddress --- .../General/Interfaces/KeyValueInterface.php | 12 ++++ app/Classes/Jobs/SendWelcomeVoucherEmail.php | 70 +++++++++++++++++++ .../ControllersLogic/CreateCustomerLogic.php | 3 +- .../UserEmailVerificationLogic.php | 29 +++++++- .../KeyValuePairObject.php | 44 ++++++++++++ .../Accounts/Services/CreatesKeyValuePair.php | 28 ++++++++ .../ListUserVouchersLogic.php | 7 ++ .../Notifications/WelcomeVoucherEmail.php | 43 ++++++++++++ .../ValueObjects/Constants/Vouchers.php | 8 +++ app/Http/Resources/KeyValueBasicResource.php | 24 +++++++ app/Http/Resources/UserRewardResource.php | 8 +++ app/Http/Resources/VoucherResource.php | 17 +++-- app/Models/KeyValuePair.php | 15 ++++ app/Models/User.php | 21 +++++- ...08_135259_create_key_value_pairs_table.php | 37 ++++++++++ .../SingleUserRewardItemComponent.vue | 7 ++ .../emails/accounts/welcome_voucher.blade.php | 8 +++ routes/web.php | 18 +++-- 18 files changed, 384 insertions(+), 15 deletions(-) create mode 100644 app/Classes/General/Interfaces/KeyValueInterface.php create mode 100644 app/Classes/Jobs/SendWelcomeVoucherEmail.php create mode 100644 app/Classes/Modules/Accounts/DataTransferObjects/KeyValuePairObject.php create mode 100644 app/Classes/Modules/Accounts/Services/CreatesKeyValuePair.php create mode 100644 app/Classes/Notifications/WelcomeVoucherEmail.php create mode 100644 app/Classes/ValueObjects/Constants/Vouchers.php create mode 100644 app/Http/Resources/KeyValueBasicResource.php create mode 100644 app/Models/KeyValuePair.php create mode 100644 database/migrations/2024_03_08_135259_create_key_value_pairs_table.php create mode 100644 resources/views/emails/accounts/welcome_voucher.blade.php diff --git a/app/Classes/General/Interfaces/KeyValueInterface.php b/app/Classes/General/Interfaces/KeyValueInterface.php new file mode 100644 index 00000000..fbee5265 --- /dev/null +++ b/app/Classes/General/Interfaces/KeyValueInterface.php @@ -0,0 +1,12 @@ +user = $user; + $this->voucher = $voucher; + $this->emailSentCount = $emailSentCount; + } + + + public function handle() + { + $currentDatetime = Carbon::now(); + $dateToCompare = Carbon::parse($this->voucher->end_date); + if (!$this->user->hasAttribute($this->voucher->code."_EMAIL_COUNT") + && $this->user->rewards->where('voucher_id', $this->voucher->id)->count() > 0 + && $currentDatetime->isBefore($dateToCompare)) + { + //Key #1 + $keyValuePairObject = new KeyValuePairObject( + $this->voucher->code."_EMAIL_COUNT", + $this->emailSentCount + ); + (App()->make(CreatesKeyValuePair::class))->execute($this->user, $keyValuePairObject); + + //Key #2 + $keyValuePairObject = new KeyValuePairObject( + $this->voucher->code."_EMAIL_DATE_".$this->emailSentCount, + Carbon::now() + ); + (App()->make(CreatesKeyValuePair::class))->execute($this->user, $keyValuePairObject); + + $this->user->notify(new WelcomeVoucherEmail($this->user, $this->voucher)); + } + } +} diff --git a/app/Classes/Modules/Accounts/ControllersLogic/CreateCustomerLogic.php b/app/Classes/Modules/Accounts/ControllersLogic/CreateCustomerLogic.php index fa6a9ae7..0f7bdb61 100644 --- a/app/Classes/Modules/Accounts/ControllersLogic/CreateCustomerLogic.php +++ b/app/Classes/Modules/Accounts/ControllersLogic/CreateCustomerLogic.php @@ -30,6 +30,7 @@ use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\App; use App\Classes\Modules\Segments\Services\CreatesSeasonalSegment; +use App\Classes\ValueObjects\Constants\Vouchers; class CreateCustomerLogic extends AbstractControllerLogic { @@ -159,7 +160,7 @@ class CreateCustomerLogic extends AbstractControllerLogic $this->newCustomerToVoucherifyProcessor->execute($company->id, $user, true); - $this->createVoucherProcessor->execute($user, 'WELCOME50%OFF'); + $this->createVoucherProcessor->execute($user, Vouchers::WELCOME_50_PERCENT_OFF); return $this->response($this->authenticationProcessor->execute($request, false)); diff --git a/app/Classes/Modules/Accounts/ControllersLogic/UserEmailVerificationLogic.php b/app/Classes/Modules/Accounts/ControllersLogic/UserEmailVerificationLogic.php index bae6f5eb..13a8bcc7 100644 --- a/app/Classes/Modules/Accounts/ControllersLogic/UserEmailVerificationLogic.php +++ b/app/Classes/Modules/Accounts/ControllersLogic/UserEmailVerificationLogic.php @@ -9,6 +9,9 @@ use App\Classes\Modules\Accounts\Services\CompletesEmailVerificationAttempt; use App\Classes\Modules\Accounts\Services\FetchesEmailVerificationAttempt; use App\Classes\Modules\Accounts\Services\VerifiesUser; use App\Classes\Modules\Accounts\Standards\Criteria\EmailVerificationActiveAttemptExists; +use App\Classes\Modules\Vouchers\Services\FetchesVoucher; +use App\Classes\Jobs\SendWelcomeVoucherEmail; +use App\Classes\ValueObjects\Constants\Vouchers; use App\Models\UserEmailVerification; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -36,19 +39,29 @@ class UserEmailVerificationLogic extends AbstractControllerLogic /** @var VerifiesUser */ private $verifiesUser; + /** @var SendWelcomeVoucherEmail */ + private $sendWelcomeVoucherEmail; + + /** @var FetchesVoucher */ + private $fetchesVoucher; + /** * UserEmailVerificationLogic constructor. * @param EmailVerificationActiveAttemptExists $emailVerificationActiveAttemptExists * @param CompletesEmailVerificationAttempt $completesEmailVerificationAttempt * @param FetchesEmailVerificationAttempt $fetchesEmailVerificationAttempt * @param VerifiesUser $verifiesUser + * @param SendWelcomeVoucherEmail $sendWelcomeVoucherEmail + * @param FetchesVoucher $fetchesVoucher */ - public function __construct(EmailVerificationActiveAttemptExists $emailVerificationActiveAttemptExists, CompletesEmailVerificationAttempt $completesEmailVerificationAttempt, FetchesEmailVerificationAttempt $fetchesEmailVerificationAttempt, VerifiesUser $verifiesUser) + public function __construct(EmailVerificationActiveAttemptExists $emailVerificationActiveAttemptExists, CompletesEmailVerificationAttempt $completesEmailVerificationAttempt, FetchesEmailVerificationAttempt $fetchesEmailVerificationAttempt, VerifiesUser $verifiesUser, SendWelcomeVoucherEmail $sendWelcomeVoucherEmail, FetchesVoucher $fetchesVoucher) { $this->emailVerificationActiveAttemptExists = $emailVerificationActiveAttemptExists; $this->completesEmailVerificationAttempt = $completesEmailVerificationAttempt; $this->fetchesEmailVerificationAttempt = $fetchesEmailVerificationAttempt; $this->verifiesUser = $verifiesUser; + $this->sendWelcomeVoucherEmail = $sendWelcomeVoucherEmail; + $this->fetchesVoucher = $fetchesVoucher; } /** @@ -68,9 +81,19 @@ class UserEmailVerificationLogic extends AbstractControllerLogic $this->completesEmailVerificationAttempt->execute($attempt); - $this->verifiesUser->execute($attempt->user); + $user = $attempt->user; + $this->verifiesUser->execute($user); + + // if (env('SENDING_EMAIL_WELCOME_VOUCHER_ENABLED', false)){ + if (app()->environment('production') && env('SENDING_EMAIL_WELCOME_VOUCHER_ENABLED', false)){ + try{ //In case voucher got deleted unintentionally + $voucher = $this->fetchesVoucher->execute(['code' => Vouchers::WELCOME_50_PERCENT_OFF]); + if($voucher) $this->sendWelcomeVoucherEmail::dispatch($user, $voucher, 1); + } + catch(\Exception $e){} + } return $this->response([]); } -} \ No newline at end of file +} diff --git a/app/Classes/Modules/Accounts/DataTransferObjects/KeyValuePairObject.php b/app/Classes/Modules/Accounts/DataTransferObjects/KeyValuePairObject.php new file mode 100644 index 00000000..fd1eff49 --- /dev/null +++ b/app/Classes/Modules/Accounts/DataTransferObjects/KeyValuePairObject.php @@ -0,0 +1,44 @@ +key = $key; + $this->value = $value; + } + + /** + * @return string + */ + public function getKey(): string + { + return $this->key; + } + + /** + * @return string + */ + public function getValue(): string + { + return $this->value; + } + +} diff --git a/app/Classes/Modules/Accounts/Services/CreatesKeyValuePair.php b/app/Classes/Modules/Accounts/Services/CreatesKeyValuePair.php new file mode 100644 index 00000000..c963ec4e --- /dev/null +++ b/app/Classes/Modules/Accounts/Services/CreatesKeyValuePair.php @@ -0,0 +1,28 @@ +key = $object->getKey(); + $model->value = $object->getValue(); + + return $this->handler($kv->attributes(), $model); + + } +} diff --git a/app/Classes/Modules/Vouchers/ControllersLogic/ListUserVouchersLogic.php b/app/Classes/Modules/Vouchers/ControllersLogic/ListUserVouchersLogic.php index 16356f0f..013be9d6 100644 --- a/app/Classes/Modules/Vouchers/ControllersLogic/ListUserVouchersLogic.php +++ b/app/Classes/Modules/Vouchers/ControllersLogic/ListUserVouchersLogic.php @@ -4,9 +4,11 @@ namespace App\Classes\Modules\Vouchers\ControllersLogic; use App\Classes\General\Abstracts\AbstractControllerLogic; use App\Classes\Modules\Rewards\Services\ListsUserRewards; +use App\Classes\ValueObjects\Constants\RoleTypes; use App\Http\Resources\UserRewardResource; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Auth; class ListUserVouchersLogic extends AbstractControllerLogic { @@ -40,6 +42,11 @@ class ListUserVouchersLogic extends AbstractControllerLogic public function logic(Request $request) : JsonResponse { $query = $this->listsUserRewards->execute($this->listsUserRewards->deserializeFilters($request->input('filters'))); + + if(in_array(Auth::user()->type, RoleTypes::ADMIN_ROLES)){ + $request->merge(['isAdmin' => true]); + } + return $this->collectionResponse(UserRewardResource::collection($query)); } diff --git a/app/Classes/Notifications/WelcomeVoucherEmail.php b/app/Classes/Notifications/WelcomeVoucherEmail.php new file mode 100644 index 00000000..0800b8cc --- /dev/null +++ b/app/Classes/Notifications/WelcomeVoucherEmail.php @@ -0,0 +1,43 @@ +user = $user; + $this->voucher = $voucher; + } + + + public function toMail() + { + $this->voucher->end_date = Carbon::parse($this->voucher->end_date)->format('Y-m-d'); + $mailMessage = (new MailMessage) + ->subject('Welcome Voucher') + ->view('emails.accounts.welcome_voucher', ['user' => $this->user, 'voucher' => $this->voucher]); + + return $mailMessage; + } + + +} diff --git a/app/Classes/ValueObjects/Constants/Vouchers.php b/app/Classes/ValueObjects/Constants/Vouchers.php new file mode 100644 index 00000000..d43194f9 --- /dev/null +++ b/app/Classes/ValueObjects/Constants/Vouchers.php @@ -0,0 +1,8 @@ + $this->id, + 'key' => $this->key, + 'value' => $this->value, + ]; + } +} diff --git a/app/Http/Resources/UserRewardResource.php b/app/Http/Resources/UserRewardResource.php index ed693b4c..b988a1d3 100644 --- a/app/Http/Resources/UserRewardResource.php +++ b/app/Http/Resources/UserRewardResource.php @@ -2,6 +2,7 @@ namespace App\Http\Resources; + use Illuminate\Http\Resources\Json\JsonResource; class UserRewardResource extends JsonResource @@ -14,6 +15,13 @@ class UserRewardResource extends JsonResource */ public function toArray($request) { + $emailReminder = null; + if ($request->has('isAdmin')) { + $keyValuePairs = $this->user->attributes()->get(); + $emailReminder = KeyValueBasicResource::collection($keyValuePairs); + $this->voucher->email = $emailReminder; + } + return [ 'id' => $this->id, 'user_id' => $this->user_id, diff --git a/app/Http/Resources/VoucherResource.php b/app/Http/Resources/VoucherResource.php index 54193eeb..3f3112bb 100644 --- a/app/Http/Resources/VoucherResource.php +++ b/app/Http/Resources/VoucherResource.php @@ -2,6 +2,7 @@ namespace App\Http\Resources; +use ArrayObject; use Illuminate\Http\Resources\Json\JsonResource; class VoucherResource extends JsonResource @@ -14,9 +15,16 @@ class VoucherResource extends JsonResource */ public function toArray($request) { - $filteredRedemptions = $this->redemptions->filter(function ($redemption) { - return $redemption->transaction && $redemption->transaction->owner; - }); + $filteredRedemptions = new ArrayObject([]); + if ($request->has('filters') && str_contains($request->input('filters'), "has_active_reward")) { + $filteredRedemptions = new ArrayObject([]); + } + else{ + $filteredRedemptions = $this->redemptions->filter(function ($redemption) { + return $redemption->transaction && $redemption->transaction->owner; + }); + } + return [ 'id' => $this->id, 'name' => $this->name, @@ -25,7 +33,8 @@ class VoucherResource extends JsonResource 'value' => (float) $this->value, 'start_date' => $this->start_date, 'end_date' => $this->end_date, - 'is_redeemed' => $filteredRedemptions->count() > 0 + 'is_redeemed' => $filteredRedemptions->count() > 0, + 'email' => $this->email ? new KeyValueBasicResource($this->email->where('key', $this->code.'_EMAIL_COUNT')->first()) : null, ]; } } diff --git a/app/Models/KeyValuePair.php b/app/Models/KeyValuePair.php new file mode 100644 index 00000000..3ad6d6cd --- /dev/null +++ b/app/Models/KeyValuePair.php @@ -0,0 +1,15 @@ +morphTo(); + } +} diff --git a/app/Models/User.php b/app/Models/User.php index 4bc7ec17..7e0a4aa9 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Classes\General\Interfaces\KeyValueInterface; use App\Classes\General\Interfaces\Voucherifiable; use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\HasMany; @@ -26,7 +27,8 @@ class User extends AbstractModel implements AuthenticatableContract, AuthorizableContract, CanResetPasswordContract, - Voucherifiable + Voucherifiable, + KeyValueInterface { use HasRoles, Notifiable, Authenticatable, Authorizable, CanResetPassword, MustVerifyEmail, SoftDeletes; @@ -101,4 +103,21 @@ class User extends AbstractModel implements { return $this->HasMany(UserReward::class, 'user_id', 'id'); } + + public function hasAttribute(string $key, $value = null): bool + { + $query = $this->attributes()->where('key', $key); + + if ($value !== null) { + $query->where('value', $value); + } + + return $query->exists(); + } + + + public function attributes(): MorphMany + { + return $this->morphMany(KeyValuePair::class, 'owner'); + } } diff --git a/database/migrations/2024_03_08_135259_create_key_value_pairs_table.php b/database/migrations/2024_03_08_135259_create_key_value_pairs_table.php new file mode 100644 index 00000000..b952ff56 --- /dev/null +++ b/database/migrations/2024_03_08_135259_create_key_value_pairs_table.php @@ -0,0 +1,37 @@ +id(); + $table->string('owner_type'); //'user', 'order', 'transaction' + $table->unsignedBigInteger('owner_id'); + $table->string('key'); + $table->string('value'); + $table->timestamps(); + + $table->index(['owner_type', 'owner_id']); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('key_value_pairs'); + } +} diff --git a/resources/assets/vue/components/companies/elements/SingleUserRewardItemComponent.vue b/resources/assets/vue/components/companies/elements/SingleUserRewardItemComponent.vue index 8f25ab60..9cc2409a 100644 --- a/resources/assets/vue/components/companies/elements/SingleUserRewardItemComponent.vue +++ b/resources/assets/vue/components/companies/elements/SingleUserRewardItemComponent.vue @@ -9,6 +9,10 @@

RM{{ item.voucher.value/100 }} Discount

{{ item.voucher.value }}% Discount

+
+ + +
-
+
-
{{(Math.round(( poTotal + Number.EPSILON) * 1000) / 1000).toFixed(3)}}/{{(Math.round((data.amount - data.payment_history[0].refunded_amount + Number.EPSILON) * 1000) / 1000).toFixed(3)}} {{data.fixed_currency.short_code}}
+
{{(Math.round(( poTotal + Number.EPSILON) * 1000) / 1000).toFixed(3)}}/{{(Math.round((data.paid_amount + Number.EPSILON) * 1000) / 1000).toFixed(3)}} {{data.fixed_currency.short_code}}
- +
-
+
** you purchase order will be saved but wont be approved until your purchase order's total matches your transfer order's total.
@@ -285,7 +285,7 @@ this.submit(route('api.transaction.po.import', this.data.id), 'post', this.section, true, true); }, successHandler(){ - if((Math.round((this.poTotal + Number.EPSILON) * 1000) / 1000).toFixed(3) === (Math.round((this.data.amount - data.payment_history[0].refunded_amount + Number.EPSILON) * 1000) / 1000).toFixed(3)){ + if((Math.round((this.poTotal + Number.EPSILON) * 1000) / 1000).toFixed(3) === (Math.round((this.data.paid_amount + Number.EPSILON) * 1000) / 1000).toFixed(3)){ this.submitted = true; } this.updateList() diff --git a/resources/views/pages/dashboards/admin.blade.php b/resources/views/pages/dashboards/admin.blade.php index 25a2500e..ac41424c 100644 --- a/resources/views/pages/dashboards/admin.blade.php +++ b/resources/views/pages/dashboards/admin.blade.php @@ -105,7 +105,7 @@ Fully Refund
@@ -123,6 +123,11 @@
Partial Refund
+
@@ -142,7 +147,7 @@ Fully Refund
@@ -160,6 +165,11 @@
Partial Refund
+
diff --git a/routes/web.php b/routes/web.php index 2370a7fc..ade589a5 100644 --- a/routes/web.php +++ b/routes/web.php @@ -433,13 +433,27 @@ Route::get('/pending_orders', function(){ echo ''; })->name('orders.pending'); -Route::get('/approve_refunds', function(){ +Route::get('/approve_refunds', function(Request $request){ + $type = $request->query('type'); $payments = Transaction::where('type', TransactionType::PAYMENT)->where('owner_type', Booking::class)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED, ApprovalStatus::REFUNDED]) - ->whereHas('transactions', function ($query) { - return $query->where('type', TransactionType::REFUND)->where('status', ApprovalStatus::APPROVED); - }) - ->orderBy('updated_at', 'DESC') - ->get(); + ->whereHas('transactions', function ($query) use ($type) { + $query->where('type', TransactionType::REFUND)->where('status', ApprovalStatus::APPROVED); + if (str_contains($type, 'partial')) { + $query->whereColumn('original_amount', '!=','transactions.original_amount'); + } else { + $query->whereColumn('original_amount', 'transactions.original_amount'); + } + }); + + if (str_contains($type, 'post')) { + $payments->whereHas('transactions', function($query) { + $query->where('type', TransactionType::SUPPLIER_REFUND); + }); + } else { + $payments->whereDoesntHave('transactions', function($query) { + $query->where('type', TransactionType::SUPPLIER_REFUND); + }); + } echo ''; echo ''; @@ -452,12 +466,13 @@ Route::get('/approve_refunds', function(){ echo ''; echo ''; echo ''; + echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; - foreach ($payments as $index => $payment){ + foreach ($payments->orderBy('updated_at', 'DESC')->get() as $index => $payment){ $booking = $payment->owner; $original_refunds = floatval((App()->make(CalculatesBookingRefundAmount::class))->calculateRefundAmount($payment, $booking->fix_currency_id)); $refunds = $original_refunds / $payment->currency_rate; @@ -471,6 +486,15 @@ Route::get('/approve_refunds', function(){ $bankType = str_word_count($booking->bank->holder_name) > 4 ? 'Company' : 'Personal'; } + $refundTransaction = $payment->transactions()->refunds()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->first(); + $remark = $refundTransaction->original_amount === $payment->original_amount ? 'Fully Refund' : 'Partial Refund'; + + if (str_contains($type, 'post')) { + $remark = 'Post ' . $remark; + } else { + $remark = 'Pre ' . $remark; + } + echo ''; echo ''; echo ''; @@ -483,6 +507,7 @@ Route::get('/approve_refunds', function(){ echo ''; echo ''; echo ''; + echo ''; echo ''; echo ''; echo ''; From c498aec61dcfb78314caed6b68326763bfbfa27e Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Sat, 16 Mar 2024 09:44:56 +0800 Subject: [PATCH 137/434] -fix purchase order section state issue when refund request is approved on booking page -fix supplier bill group dashboard payment issue --- .../ApproveBillGroupPaymentVerificationLogic.php | 2 +- .../CreateBillGroupPaymentProofDocumentLogic.php | 2 +- .../CreateBillGroupPaymentTransactionLogic.php | 2 +- .../ControllersLogic/CreateSupplierBillGroupLogic.php | 8 ++++---- .../elements/BillGroupPaymentSummaryComponent.vue | 4 ++-- .../bookings/forms/PurchaseOrderFormComponent.vue | 1 + 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/app/Classes/Modules/Transactions/ControllersLogic/ApproveBillGroupPaymentVerificationLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/ApproveBillGroupPaymentVerificationLogic.php index f12060b4..00117f9e 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/ApproveBillGroupPaymentVerificationLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/ApproveBillGroupPaymentVerificationLogic.php @@ -81,7 +81,7 @@ class ApproveBillGroupPaymentVerificationLogic extends AbstractControllerLogic $billGroup->status = ApprovalStatus::PENDING_SUBMISSION; $billGroup->save(); } else { - if ($billGroupPayment['outstanding_amount'] <= 0) { + if ($billGroupPayment['outstanding_amount'] <= 0 && $billGroupPayment['floating_amount'] <= 0) { $billGroup->status = ApprovalStatus::APPROVED; $billGroup->save(); } diff --git a/app/Classes/Modules/Transactions/ControllersLogic/CreateBillGroupPaymentProofDocumentLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/CreateBillGroupPaymentProofDocumentLogic.php index 79e01eb0..2563c230 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/CreateBillGroupPaymentProofDocumentLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/CreateBillGroupPaymentProofDocumentLogic.php @@ -83,7 +83,7 @@ class CreateBillGroupPaymentProofDocumentLogic extends AbstractControllerLogic $billGroup = $transaction->owner; $billGroupPayment = $this->calculatesBillGroupPaymentAmount->execute($billGroup); - if ($billGroupPayment['outstanding_amount'] <= 0) { + if ($billGroupPayment['outstanding_amount'] <= 0 && $billGroup->transactions()->where('status', ApprovalStatus::PENDING_SUBMISSION)->count() === 0) { $billGroup->status = ApprovalStatus::PENDING_VERIFICATION; $billGroup->save(); } diff --git a/app/Classes/Modules/Transactions/ControllersLogic/CreateBillGroupPaymentTransactionLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/CreateBillGroupPaymentTransactionLogic.php index e2fc6dc1..75be47d4 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/CreateBillGroupPaymentTransactionLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/CreateBillGroupPaymentTransactionLogic.php @@ -68,7 +68,7 @@ class CreateBillGroupPaymentTransactionLogic extends AbstractControllerLogic $billGroupPayment = $this->calculatesBillGroupPaymentAmount->execute($billGroup); $outstanding_amount = $billGroupPayment['outstanding_amount']; - if ($billGroupPayment['outstanding_amount'] == 0) { + if ($billGroupPayment['outstanding_amount'] <= 0) { if ($billGroup->transactions()->whereIn('status', [ApprovalStatus::PENDING_SUBMISSION, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->count() !== 0) { throw new MalformedRequestException('Invalid bill group, payment transaction already exist.'); } diff --git a/app/Classes/Modules/Transactions/ControllersLogic/CreateSupplierBillGroupLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/CreateSupplierBillGroupLogic.php index 33284726..6213f55f 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/CreateSupplierBillGroupLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/CreateSupplierBillGroupLogic.php @@ -159,11 +159,11 @@ class CreateSupplierBillGroupLogic extends AbstractControllerLogic foreach ($supplierRefunds as $supplierRefund) { $refund = Transaction::find($supplierRefund['id']); $deductedRefunds = $refund->transactions()->where('type', TransactionType::BILL_REFUND)->where('status', ApprovalStatus::APPROVED)->get(); - $refundDeductableAmount = $refund->amount - $deductedRefunds->sum('amount'); - $refundDeductableOriginalAmount = $refund->original_amount - $deductedRefunds->sum('original_amount'); + $refundDeductableAmount = round(($refund->amount - $deductedRefunds->sum('amount')), 2); + $refundDeductableOriginalAmount = round(($refund->original_amount - $deductedRefunds->sum('original_amount')), 2); - $amount -= round($refundDeductableAmount, 2); - $original_amount -= round($refundDeductableOriginalAmount, 2); + $amount -= $refundDeductableAmount; + $original_amount -= $refundDeductableOriginalAmount; if ($amount > 0) { $deductedRefundAmount = $refundDeductableAmount; diff --git a/resources/assets/vue/components/bookings/elements/BillGroupPaymentSummaryComponent.vue b/resources/assets/vue/components/bookings/elements/BillGroupPaymentSummaryComponent.vue index 284f681d..f84541d1 100644 --- a/resources/assets/vue/components/bookings/elements/BillGroupPaymentSummaryComponent.vue +++ b/resources/assets/vue/components/bookings/elements/BillGroupPaymentSummaryComponent.vue @@ -80,7 +80,7 @@
MYR 0.00
-
+
@@ -101,7 +101,7 @@
-
+
diff --git a/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue b/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue index 3e0c9ca6..ad3627ba 100644 --- a/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue +++ b/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue @@ -242,6 +242,7 @@ 'data': function () { if (this.data && this.data.purchase_order && this.data.purchase_order.details) { this.products = this.data.purchase_order.details; + this.submitted = this.data.purchase_order ? this.data.purchase_order.status === 1 || this.data.purchase_order.status === 2: false; } else { this.products = []; } From 0a12bca442e128fa05c8056bbb2395b182fbee1a Mon Sep 17 00:00:00 2001 From: edmondlang Date: Sun, 17 Mar 2024 15:03:46 +0800 Subject: [PATCH 138/434] check if have refund in progress --- .../bookings/elements/PaymentHistoryComponent.vue | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue index f3b3fb38..e3be870f 100644 --- a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue +++ b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue @@ -289,7 +289,7 @@
-
+
@@ -434,6 +434,10 @@ TotalRequestedRefund += refunds.status === 2 ? refunds.amount : 0; }); return TotalRequestedRefund; + }, + hasRefundInProgress() { + var refundTransactionsStatus = this.data.transaction_refunds.length > 0 ? this.data.transaction_refunds.map(refund => refund.status) : []; + return refundTransactionsStatus.includes(0) || refundTransactionsStatus.includes(1) } }, methods: { From 01bbb1e21a650b482ce2db52a10aedb6606c9215 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Sun, 17 Mar 2024 16:06:47 +0800 Subject: [PATCH 139/434] Amendment on welcome voocher email requested by kexin --- .../views/emails/accounts/welcome_voucher.blade.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/resources/views/emails/accounts/welcome_voucher.blade.php b/resources/views/emails/accounts/welcome_voucher.blade.php index aaf8ccdb..7cd60aa1 100644 --- a/resources/views/emails/accounts/welcome_voucher.blade.php +++ b/resources/views/emails/accounts/welcome_voucher.blade.php @@ -1,8 +1,13 @@ @extends('emails.layout.base') @section('content') -

Hello, {{$user->name}}

-

Welcome to Exchange! We're thrilled to have you onboard as a new member. To kick things off, please use the following voucher for your first purchase

-

Voucher code: {{$voucher->code}}

-

This voucher is valid until {{ $voucher->end_date}}

+ +

Hello from CIEF! Thanks for signing up with us. Thinking about using our RMB payment transfer services? Use code 【{{$voucher->code}}】 and get a 50% discount on your first order. Why not give it a try?

+

Any questions? I'm here to help. Start here: {{env('APP_URL').'/dashboard'}}

+

叮咚!非常感谢您在我们代付网站注册, 您是否对我们的代付服务感兴趣却还在犹豫或者在因为其他因素还没正式使用呢? 如果是首次下单, 不妨使用我们专门为新用户准备的独家优惠, 只需在首次下单时使用代码【{{$voucher->code}}】,就能享有5折的手续费折扣呢! 尝试了一次, 或许你会喜欢我们公司的服务,点击以下网址开始启用吧!

+

{{env('APP_URL').'/dashboard'}}

+

如果您有任何疑问或需要更多信息,随时联系我。我们期待着能为您提供物流以及代付服务!

+ +

Thanks

+

谢谢!

@endsection From 122888f39af6f98471600425cf66d2e1cc2aa5d2 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Mon, 18 Mar 2024 12:58:17 +0800 Subject: [PATCH 140/434] Vue Polling - update info log location when job is not found --- app/Classes/General/Abstracts/AbstractControllerLogic.php | 2 +- config/logging.php | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/app/Classes/General/Abstracts/AbstractControllerLogic.php b/app/Classes/General/Abstracts/AbstractControllerLogic.php index 61c70f44..f26e2ad0 100644 --- a/app/Classes/General/Abstracts/AbstractControllerLogic.php +++ b/app/Classes/General/Abstracts/AbstractControllerLogic.php @@ -69,7 +69,7 @@ abstract class AbstractControllerLogic } catch (ErrorException|GeneralExceptions $exception){ if ($exception instanceof JobResourceNotFoundException) { - Log::error(sprintf( + Log::channel('vue_polling')->info(sprintf( "Uncaught exception '%s' with message '%s' in %s:%d", get_class($exception), $exception->getMessage(), diff --git a/config/logging.php b/config/logging.php index d0d0a009..e480e00e 100644 --- a/config/logging.php +++ b/config/logging.php @@ -108,6 +108,13 @@ return [ 'driver' => 'errorlog', 'level' => 'debug', ], + + 'vue_polling' => [ + 'driver' => 'single', + 'path' => storage_path('logs/laravel_vue_plling.log'), + 'level' => 'info', + ], + ], ]; From 29d17c4f1f033455c76291df0c42fddd3922b0b4 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Mon, 18 Mar 2024 13:09:12 +0800 Subject: [PATCH 141/434] Vue Polling - update info log location for PerfexCRM --- .../PerfexCRM/Services/ConvertsPerfexCRMLeadToCustomer.php | 2 +- .../Modules/PerfexCRM/Services/CreatesPerfexCRMCustomer.php | 2 +- .../PerfexCRM/Services/CreatesPerfexCRMCustomerContact.php | 2 +- .../PerfexCRM/Services/CreatesPerfexCRMCustomerProject.php | 2 +- .../Modules/PerfexCRM/Services/CreatesPerfexCRMInvoice.php | 2 +- .../PerfexCRM/Services/CreatesPerfexCRMInvoicePayment.php | 2 +- .../Modules/PerfexCRM/Services/CreatesPerfexCRMLead.php | 2 +- .../PerfexCRM/Services/CreatesPerfexCRMMilestone.php | 2 +- .../Modules/PerfexCRM/Services/CreatesPerfexCRMTask.php | 2 +- .../Modules/PerfexCRM/Services/FetchesPerfexCRMCustomer.php | 2 +- .../Modules/PerfexCRM/Services/FetchesPerfexCRMInvoice.php | 2 +- .../Modules/PerfexCRM/Services/FetchesPerfexCRMLead.php | 2 +- .../PerfexCRM/Services/FetchesPerfexCRMMilestone.php | 2 +- .../Modules/PerfexCRM/Services/FetchesPerfexCRMProject.php | 2 +- .../Modules/PerfexCRM/Services/UpdatesPerfexCRMInvoice.php | 2 +- .../Modules/PerfexCRM/Services/UpdatesPerfexCRMLead.php | 2 +- .../Modules/PerfexCRM/Services/UpdatesPerfexCRMProject.php | 2 +- .../Modules/PerfexCRM/Services/UpdatesPerfexCRMTask.php | 2 +- config/logging.php | 6 ++++++ 19 files changed, 24 insertions(+), 18 deletions(-) diff --git a/app/Classes/Modules/PerfexCRM/Services/ConvertsPerfexCRMLeadToCustomer.php b/app/Classes/Modules/PerfexCRM/Services/ConvertsPerfexCRMLeadToCustomer.php index e6e7323e..92e90a52 100644 --- a/app/Classes/Modules/PerfexCRM/Services/ConvertsPerfexCRMLeadToCustomer.php +++ b/app/Classes/Modules/PerfexCRM/Services/ConvertsPerfexCRMLeadToCustomer.php @@ -24,7 +24,7 @@ class ConvertsPerfexCRMLeadToCustomer return (object) $data; }else{ - Log::error($response); + Log::channel('perfex_crm')->info($response); return null; } }catch(\Exception $exception){ diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomer.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomer.php index e5a19ce3..b7eabaa7 100644 --- a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomer.php +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomer.php @@ -27,7 +27,7 @@ class CreatesPerfexCRMCustomer $data = $response->json(); return (object) $data; }else{ - Log::error($response); + Log::channel('perfex_crm')->info($response); return null; } }catch(\Exception $exception){ diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerContact.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerContact.php index 519c1495..12d3d7e8 100644 --- a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerContact.php +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerContact.php @@ -34,7 +34,7 @@ class CreatesPerfexCRMCustomerContact $data = $response->json(); return (object) $data; }else{ - Log::error($response); + Log::channel('perfex_crm')->info($response); return null; } }catch(\Exception $exception){ diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerProject.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerProject.php index f5d4de3e..1f513f31 100644 --- a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerProject.php +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMCustomerProject.php @@ -33,7 +33,7 @@ class CreatesPerfexCRMCustomerProject $data = $response->json(); return (object) $data; }else{ - Log::error($response); + Log::channel('perfex_crm')->info($response); return null; } }catch(\Exception $exception){ diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoice.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoice.php index ba0c2755..df952c4b 100644 --- a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoice.php +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoice.php @@ -53,7 +53,7 @@ class CreatesPerfexCRMInvoice $data = $response->json(); return (object) $data; }else{ - Log::error($response); + Log::channel('perfex_crm')->info($response); return null; } }catch(\Exception $exception){ diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoicePayment.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoicePayment.php index f3e92529..64590232 100644 --- a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoicePayment.php +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMInvoicePayment.php @@ -33,7 +33,7 @@ class CreatesPerfexCRMInvoicePayment $data = $response->json(); return (object) $data; }else{ - Log::error($response); + Log::channel('perfex_crm')->info($response); return null; } }catch(\Exception $exception){ diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMLead.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMLead.php index 373f4171..5ecef6e7 100644 --- a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMLead.php +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMLead.php @@ -40,7 +40,7 @@ class CreatesPerfexCRMLead $data = $response->json(); return (object) $data; }else{ - Log::error($response); + Log::channel('perfex_crm')->info($response); return null; } }catch(\Exception $exception){ diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMMilestone.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMMilestone.php index 80cb49bf..91afd314 100644 --- a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMMilestone.php +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMMilestone.php @@ -36,7 +36,7 @@ class CreatesPerfexCRMMilestone $data = $response->json(); return (object) $data; }else{ - Log::error($response); + Log::channel('perfex_crm')->info($response); return null; } }catch(\Exception $exception){ diff --git a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMTask.php b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMTask.php index feb8f9c8..45105fa9 100644 --- a/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMTask.php +++ b/app/Classes/Modules/PerfexCRM/Services/CreatesPerfexCRMTask.php @@ -56,7 +56,7 @@ class CreatesPerfexCRMTask $data = $response->json(); return (object) $data; }else{ - Log::error($response); + Log::channel('perfex_crm')->info($response); return null; } }catch(\Exception $exception){ diff --git a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMCustomer.php b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMCustomer.php index 9f3928f6..6efebec4 100644 --- a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMCustomer.php +++ b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMCustomer.php @@ -24,7 +24,7 @@ class FetchesPerfexCRMCustomer return (object) $data; }else{ - Log::error($response); + Log::channel('perfex_crm')->info($response); return null; } }catch(\Exception $exception){ diff --git a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMInvoice.php b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMInvoice.php index cd7aff30..7946cfec 100644 --- a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMInvoice.php +++ b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMInvoice.php @@ -26,7 +26,7 @@ class FetchesPerfexCRMInvoice return (object) $data; }else{ - Log::error($response); + Log::channel('perfex_crm')->info($response); return null; } }catch(\Exception $exception){ diff --git a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMLead.php b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMLead.php index df9c754d..a3543b20 100644 --- a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMLead.php +++ b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMLead.php @@ -24,7 +24,7 @@ class FetchesPerfexCRMLead return (object) $data; }else{ - Log::error($response); + Log::channel('perfex_crm')->info($response); return null; } }catch(\Exception $exception){ diff --git a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMMilestone.php b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMMilestone.php index 30ae0737..9c482fe7 100644 --- a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMMilestone.php +++ b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMMilestone.php @@ -30,7 +30,7 @@ class FetchesPerfexCRMMilestone return (object) $data; }else{ - Log::error($response); + Log::channel('perfex_crm')->info($response); return null; } }catch(\Exception $exception){ diff --git a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMProject.php b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMProject.php index c55f2c01..ce9762d8 100644 --- a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMProject.php +++ b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMProject.php @@ -30,7 +30,7 @@ class FetchesPerfexCRMProject return (object) $data; }else{ - Log::error($response); + Log::channel('perfex_crm')->info($response); return null; } }catch(\Exception $exception){ diff --git a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMInvoice.php b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMInvoice.php index 9adb9460..9825dde2 100644 --- a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMInvoice.php +++ b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMInvoice.php @@ -60,7 +60,7 @@ class UpdatesPerfexCRMInvoice $data = $response->json(); return (object) $data; }else{ - Log::error($response); + Log::channel('perfex_crm')->info($response); return null; } }catch(\Exception $exception){ diff --git a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMLead.php b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMLead.php index f8fbc944..69ac7fa8 100644 --- a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMLead.php +++ b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMLead.php @@ -41,7 +41,7 @@ class UpdatesPerfexCRMLead $data = $response->json(); return (object) $data; }else{ - Log::error($response); + Log::channel('perfex_crm')->info($response); return null; } }catch(\Exception $exception){ diff --git a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMProject.php b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMProject.php index cf782806..4b65347e 100644 --- a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMProject.php +++ b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMProject.php @@ -33,7 +33,7 @@ class UpdatesPerfexCRMProject $data = $response->json(); return (object) $data; }else{ - Log::error($response); + Log::channel('perfex_crm')->info($response); return null; } }catch(\Exception $exception){ diff --git a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMTask.php b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMTask.php index 95a09525..053fa16d 100644 --- a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMTask.php +++ b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMTask.php @@ -40,7 +40,7 @@ class UpdatesPerfexCRMTask $data = $response->json(); return (object) $data; }else{ - Log::error($response); + Log::channel('perfex_crm')->info($response); return null; } }catch(\Exception $exception){ diff --git a/config/logging.php b/config/logging.php index e480e00e..d4894384 100644 --- a/config/logging.php +++ b/config/logging.php @@ -115,6 +115,12 @@ return [ 'level' => 'info', ], + 'perfex_crm' => [ + 'driver' => 'single', + 'path' => storage_path('logs/laravel_perfex_crm.log'), + 'level' => 'info', + ], + ], ]; From 1ca7a25affdbc67ef50fd7300ff737caac77a9d9 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Mon, 18 Mar 2024 13:25:24 +0800 Subject: [PATCH 142/434] Vue Polling - update info log location for PerfexCRM, standardization exercise --- app/Classes/Jobs/UpdatePerfexCRMInvoice.php | 7 +++---- .../Processors/CreatePerfexCRMInvoiceProcessor.php | 4 ++-- .../Processors/FetchPerfexCRMInvoiceProcessor.php | 2 +- .../PerfexCRM/Processors/UpdatePerfexCRMProcessor.php | 4 ++-- .../Modules/PerfexCRM/Services/FetchesPerfexCRMTask.php | 2 +- .../PerfexCRM/Services/UpdatesPerfexCRMCustomer.php | 2 +- 6 files changed, 10 insertions(+), 11 deletions(-) diff --git a/app/Classes/Jobs/UpdatePerfexCRMInvoice.php b/app/Classes/Jobs/UpdatePerfexCRMInvoice.php index 26131bca..93f26b84 100644 --- a/app/Classes/Jobs/UpdatePerfexCRMInvoice.php +++ b/app/Classes/Jobs/UpdatePerfexCRMInvoice.php @@ -57,16 +57,15 @@ class UpdatePerfexCRMInvoice implements ShouldQueue $number = 'EXC-'.$number; $invoice = (App()->make(FetchesPerfexCRMInvoice::class))->execute($customer->userid,"INV-", $number); - Log::error(json_encode('UpdatePerfexCRMInvoice debug $number: '.$number)); + Log::channel('perfex_crm')->info(json_encode('UpdatePerfexCRMInvoice debug $number: '.$number)); if(is_null($invoice)){ $result = (App()->make(CreatePerfexCRMInvoiceProcessor::class))->execute($transaction); if ($result) { $invoiceId = $result->payload['id']; } else { - // Log::error(json_encode('UpdatePerfexCRMInvoice CreatePerfexCRMInvoiceProcessor failed')); $log['message'] = 'UpdatePerfexCRMInvoice CreatePerfexCRMInvoiceProcessor failed'; - Helper::debugLogger($log); + Log::channel('perfex_crm')->info($log); } } else{ @@ -75,7 +74,7 @@ class UpdatePerfexCRMInvoice implements ShouldQueue //This only run when invoice already exist and the invoice does not have a PAID status if($invoiceStatus != PerfexCRMInvoiceStatus::PAID){ - Log::error(json_encode('UpdatePerfexCRMInvoice debug $this->updatePerfexCRMInvoiceObject->getProjectId(): '.$this->updatePerfexCRMInvoiceObject->getProjectId())); + Log::channel('perfex_crm')->info('UpdatePerfexCRMInvoice debug $this->updatePerfexCRMInvoiceObject->getProjectId(): '.$this->updatePerfexCRMInvoiceObject->getProjectId()); //update invoice (App()->make(UpdatesPerfexCRMInvoice::class))->execute($invoice, $this->updatePerfexCRMInvoiceObject->getProjectId()); diff --git a/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php index 4edb2ef5..dae44588 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/CreatePerfexCRMInvoiceProcessor.php @@ -108,12 +108,12 @@ class CreatePerfexCRMInvoiceProcessor $email = null; if ($firstSupplier) { $email = $firstSupplier->email; - Log::error('CreatePerfexCRMInvoiceProcessor debug:'.$email); + Log::channel('perfex_crm')->info('CreatePerfexCRMInvoiceProcessor debug:'.$email); } else { $bookingMarking = $transaction->owner->marking; $serviceTypeName = $transaction->owner->company->services()->where('id', $transaction->owner->service_id)->first()->name; $projectName = 'Exchange | '.$serviceTypeName.' | '.$bookingMarking; - Log::error('$projectName: '.$projectName); + Log::channel('perfex_crm')->info('$projectName: '.$projectName); return $email; } diff --git a/app/Classes/Modules/PerfexCRM/Processors/FetchPerfexCRMInvoiceProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/FetchPerfexCRMInvoiceProcessor.php index 4c8ee9bf..c073fb7a 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/FetchPerfexCRMInvoiceProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/FetchPerfexCRMInvoiceProcessor.php @@ -62,7 +62,7 @@ class FetchPerfexCRMInvoiceProcessor $invoiceId = $result->payload['id']; } else { $log['message'] = 'FetchPerfexCRMInvoiceProcessor failed for transaction > bill_no: '.$number; - Helper::debugLogger($log); + Log::channel('perfex_crm')->info($log); } } else{ diff --git a/app/Classes/Modules/PerfexCRM/Processors/UpdatePerfexCRMProcessor.php b/app/Classes/Modules/PerfexCRM/Processors/UpdatePerfexCRMProcessor.php index fbf64be8..ac422c33 100644 --- a/app/Classes/Modules/PerfexCRM/Processors/UpdatePerfexCRMProcessor.php +++ b/app/Classes/Modules/PerfexCRM/Processors/UpdatePerfexCRMProcessor.php @@ -217,8 +217,8 @@ class UpdatePerfexCRMProcessor } $result = $this->fetchesPerfexCRMTask->execute($taskName, $milestoneId, 'project', $projectId, $updatePerfexCRMObject->getInvoiceId()); - // Log::error("UpdatePerfexCRMProcessor task: ".$taskName." , ".json_encode($result)); - Log::error("UpdatePerfexCRMProcessor task: ".$taskName); + // Log::channel('perfex_crm')->info("UpdatePerfexCRMProcessor task: ".$taskName." , ".json_encode($result)); + Log::channel('perfex_crm')->info("UpdatePerfexCRMProcessor task: ".$taskName); if(isset($result->payload)){ //&& $result->payload[0]['status'] == PerfexCRMTaskStatus::NOT_STARTED diff --git a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMTask.php b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMTask.php index 6cd4f052..0ab2b0fd 100644 --- a/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMTask.php +++ b/app/Classes/Modules/PerfexCRM/Services/FetchesPerfexCRMTask.php @@ -44,7 +44,7 @@ class FetchesPerfexCRMTask return (object) $data; }else{ - Helper::debugLogger($response); + Log::channel('perfex_crm')->info($response); return null; } }catch(\Exception $exception){ diff --git a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMCustomer.php b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMCustomer.php index 6d91c081..15963c31 100644 --- a/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMCustomer.php +++ b/app/Classes/Modules/PerfexCRM/Services/UpdatesPerfexCRMCustomer.php @@ -38,7 +38,7 @@ class UpdatesPerfexCRMCustomer $data = $response->json(); return (object) $data; }else{ - Helper::debugLogger($response); + Log::channel('perfex_crm')->info($response); return null; } }catch(\Exception $exception){ From 15482469a6673350f4fcada22b939cdb5f45dbcd Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Mon, 18 Mar 2024 13:29:51 +0800 Subject: [PATCH 143/434] Vue Polling - update info log location for PerfexCRM, standardization exercise --- app/Classes/Jobs/UpdatePerfexCRMInvoice.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Classes/Jobs/UpdatePerfexCRMInvoice.php b/app/Classes/Jobs/UpdatePerfexCRMInvoice.php index 93f26b84..80a60c15 100644 --- a/app/Classes/Jobs/UpdatePerfexCRMInvoice.php +++ b/app/Classes/Jobs/UpdatePerfexCRMInvoice.php @@ -57,7 +57,7 @@ class UpdatePerfexCRMInvoice implements ShouldQueue $number = 'EXC-'.$number; $invoice = (App()->make(FetchesPerfexCRMInvoice::class))->execute($customer->userid,"INV-", $number); - Log::channel('perfex_crm')->info(json_encode('UpdatePerfexCRMInvoice debug $number: '.$number)); + Log::channel('perfex_crm')->info(('UpdatePerfexCRMInvoice debug $number: '.$number)); if(is_null($invoice)){ $result = (App()->make(CreatePerfexCRMInvoiceProcessor::class))->execute($transaction); From daa422d41ae15d57c5fb8ef4a65e388256c9a11b Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Mon, 18 Mar 2024 22:13:05 +0800 Subject: [PATCH 144/434] -auto update booking fix amount once refund approve --- .../Services/CalculatesBookingOutstanding.php | 9 +++++++-- .../UpdateRefundTransactionStatusLogic.php | 17 ++++++++++++++--- .../elements/SupplierPendingOrderComponent.vue | 4 ++-- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/app/Classes/Modules/Bookings/Services/CalculatesBookingOutstanding.php b/app/Classes/Modules/Bookings/Services/CalculatesBookingOutstanding.php index 5f2c7733..f3a70a6a 100644 --- a/app/Classes/Modules/Bookings/Services/CalculatesBookingOutstanding.php +++ b/app/Classes/Modules/Bookings/Services/CalculatesBookingOutstanding.php @@ -13,20 +13,25 @@ class CalculatesBookingOutstanding /** @var CalculatesBookingFloatingAmount */ private $calculatesBookingFloatingAmount; + /** @var CalculatesBookingRefundAmount */ + private $calculatesBookingRefundAmount; + /** * CalculatesBookingOutstanding constructor. * @param CalculatesBookingPayableAmount $calculatesBookingPayableAmount * @param CalculatesBookingFloatingAmount $calculatesBookingFloatingAmount + * @param CalculatesBookingRefundAmount $calculatesBookingRefundAmount */ - public function __construct(CalculatesBookingPayableAmount $calculatesBookingPayableAmount, CalculatesBookingFloatingAmount $calculatesBookingFloatingAmount) + public function __construct(CalculatesBookingPayableAmount $calculatesBookingPayableAmount, CalculatesBookingFloatingAmount $calculatesBookingFloatingAmount, CalculatesBookingRefundAmount $calculatesBookingRefundAmount) { $this->calculatesBookingPayableAmount = $calculatesBookingPayableAmount; $this->calculatesBookingFloatingAmount = $calculatesBookingFloatingAmount; + $this->calculatesBookingRefundAmount = $calculatesBookingRefundAmount; } public function execute(Booking $booking){ - return $booking->fix_amount - $this->calculatesBookingFloatingAmount->execute($booking, $booking->fix_currency_id) - $this->calculatesBookingPayableAmount->execute($booking, $booking->fix_currency_id); + return $booking->fix_amount - $this->calculatesBookingFloatingAmount->execute($booking, $booking->fix_currency_id) - $this->calculatesBookingPayableAmount->execute($booking, $booking->fix_currency_id) + $this->calculatesBookingRefundAmount->execute($booking, $booking->fix_currency_id); } } \ No newline at end of file diff --git a/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php index 91b82f16..25db0f31 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php @@ -4,6 +4,7 @@ namespace App\Classes\Modules\Transactions\ControllersLogic; use App\Classes\General\Abstracts\AbstractControllerLogic; +use App\Classes\Modules\Bookings\ControllersLogic\UpdateBookingAmountLogic; use App\Classes\Modules\Companies\Services\FetchesCompany; use App\Classes\Modules\Transactions\Services\FetchesTransaction; use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus; @@ -51,6 +52,9 @@ class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic /** @var CalculatesBookingRefundAmount */ private $calculatesBookingRefundAmount; + /** @var UpdateBookingAmountLogic */ + private $updateBookingAmountLogic; + /** * CreatePaymentVerificationDocumentLogic constructor. * @param FetchesCompany $fetchesCompany @@ -60,8 +64,9 @@ class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic * @param CreditWalletProcessor $creditWalletProcessor * @param CalculatesBookingPayableAmount $calculatesBookingPayableAmount * @param CalculatesBookingRefundAmount $calculatesBookingRefundAmount + * @param UpdateBookingAmountLogic $updateBookingAmountLogic */ - public function __construct(FetchesCompany $fetchesCompany, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, DeletesDocument $deletesDocument, CreditWalletProcessor $creditWalletProcessor, CalculatesBookingPayableAmount $calculatesBookingPayableAmount, CalculatesBookingRefundAmount $calculatesBookingRefundAmount) + public function __construct(FetchesCompany $fetchesCompany, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, DeletesDocument $deletesDocument, CreditWalletProcessor $creditWalletProcessor, CalculatesBookingPayableAmount $calculatesBookingPayableAmount, CalculatesBookingRefundAmount $calculatesBookingRefundAmount, UpdateBookingAmountLogic $updateBookingAmountLogic) { $this->fetchesCompany = $fetchesCompany; $this->fetchesTransaction = $fetchesTransaction; @@ -70,6 +75,7 @@ class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic $this->creditWalletProcessor = $creditWalletProcessor; $this->calculatesBookingPayableAmount = $calculatesBookingPayableAmount; $this->calculatesBookingRefundAmount = $calculatesBookingRefundAmount; + $this->updateBookingAmountLogic = $updateBookingAmountLogic; } /** @@ -93,20 +99,25 @@ class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic $refundAmount = $this->calculatesBookingRefundAmount->calculateRefundAmount($paymentTransaction, $booking->fix_currency_id); + $paidAmount = $paymentTransaction->original_amount - $refundAmount; + if ($refundTransaction->status == ApprovalStatus::APPROVED) { $this->creditWalletProcessor->execute($booking->company, $refundTransaction->type, $refundTransaction->amount, $reference); $po_transaction = $booking->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first(); if ($po_transaction) { $this->updatesTransactionStatus->execute($po_transaction, (float) number_format($po_transaction->amount, 2, '.', '') === (float) number_format((float)$booking->fix_amount - $refundAmount, 2, '.', '') ? ApprovalStatus::PENDING_VERIFICATION : ApprovalStatus::PENDING_SUBMISSION); - } + } + + $request['fix_amount'] = $paidAmount; + $request->route()->setParameter('id', $booking->id); + $this->updateBookingAmountLogic->execute($request); } if ($supplierRefundTransaction) { $this->updatesTransactionStatus->execute($supplierRefundTransaction, $request->route('status')); } - $paidAmount = $paymentTransaction->original_amount - $refundAmount; if (!$paidAmount > 0) { $this->updatesTransactionStatus->execute($paymentTransaction, ApprovalStatus::REFUNDED); } diff --git a/resources/assets/vue/components/bookings/elements/SupplierPendingOrderComponent.vue b/resources/assets/vue/components/bookings/elements/SupplierPendingOrderComponent.vue index 309f2b9b..860a493c 100644 --- a/resources/assets/vue/components/bookings/elements/SupplierPendingOrderComponent.vue +++ b/resources/assets/vue/components/bookings/elements/SupplierPendingOrderComponent.vue @@ -56,7 +56,7 @@ {{item.original_currency.short_code}}
-
+
From 04b8dfb0ddb52c6877eb07ec29506145256b0461 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Tue, 19 Mar 2024 00:23:09 +0800 Subject: [PATCH 145/434] -fix issue where cannot approve PO when we have refunded transaction --- .../Bookings/Services/CalculatesBookingTransferredAmount.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Classes/Modules/Bookings/Services/CalculatesBookingTransferredAmount.php b/app/Classes/Modules/Bookings/Services/CalculatesBookingTransferredAmount.php index fc355d64..099d4571 100644 --- a/app/Classes/Modules/Bookings/Services/CalculatesBookingTransferredAmount.php +++ b/app/Classes/Modules/Bookings/Services/CalculatesBookingTransferredAmount.php @@ -13,7 +13,7 @@ class CalculatesBookingTransferredAmount public function execute(Booking $booking){ return $booking->transactions()->payments()->complete()->whereHas('transactions', function($query){ - return $query->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); + return $query->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->where('type', TransactionType::BILL); })->sum('original_amount'); } From 156c4645148b04e0646a50e4750fa16a04b07917 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Thu, 21 Mar 2024 17:50:03 +0800 Subject: [PATCH 146/434] Fix a problem with Jenkinsfile, sync code from Shipping Portal --- Jenkinsfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Jenkinsfile b/Jenkinsfile index 0c083045..a7358b25 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -32,6 +32,7 @@ pipeline { credentialsId: 'gitlab-jenkins-localhost', branch: GIT_BRANCH ) + break case "origin/dillon/34-jenkins-vapor": git( url: 'https://gitlab.com/CIEFWorldwideSdnBhd/exchange-2.0.git', From da47b92b7c29be1a3e88a1d4aecd8720f121c031 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Fri, 22 Mar 2024 13:53:56 +0800 Subject: [PATCH 147/434] Setup priority queue with AWS SQS (Sync from Shipping Portal) --- .../Bookings/ControllersLogic/ListBookingJobLogic.php | 2 +- .../Documents/ControllersLogic/ListDocumentJobLogic.php | 2 +- .../ControllersLogic/ListTransactionsJobLogic.php | 2 +- vapor.yml | 9 +++++++++ 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/app/Classes/Modules/Bookings/ControllersLogic/ListBookingJobLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/ListBookingJobLogic.php index ef3570f7..827f7f2a 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/ListBookingJobLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/ListBookingJobLogic.php @@ -62,7 +62,7 @@ class ListBookingJobLogic extends AbstractControllerLogic $userInfo ); - ListBookingsJob::dispatch($listGenericJobObject); + ListBookingsJob::dispatch($listGenericJobObject)->onQueue(env('SQS_QUEUENAME_PREFIX', '').'high_priority'); $result = []; $result['job_id'] = $jobId; diff --git a/app/Classes/Modules/Documents/ControllersLogic/ListDocumentJobLogic.php b/app/Classes/Modules/Documents/ControllersLogic/ListDocumentJobLogic.php index 5e895ad8..c49b58d2 100644 --- a/app/Classes/Modules/Documents/ControllersLogic/ListDocumentJobLogic.php +++ b/app/Classes/Modules/Documents/ControllersLogic/ListDocumentJobLogic.php @@ -63,7 +63,7 @@ class ListDocumentJobLogic extends AbstractControllerLogic $userInfo ); - ListDocumentsJob::dispatch($listGenericJobObject); + ListDocumentsJob::dispatch($listGenericJobObject)->onQueue(env('SQS_QUEUENAME_PREFIX', '').'high_priority'); $result = []; $result['job_id'] = $jobId; diff --git a/app/Classes/Modules/Transactions/ControllersLogic/ListTransactionsJobLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/ListTransactionsJobLogic.php index 654a360f..76dd2e9f 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/ListTransactionsJobLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/ListTransactionsJobLogic.php @@ -61,7 +61,7 @@ class ListTransactionsJobLogic extends AbstractControllerLogic $userInfo ); - ListTransactionsJob::dispatch($listGenericJobObject); + ListTransactionsJob::dispatch($listGenericJobObject)->onQueue(env('SQS_QUEUENAME_PREFIX', '').'high_priority'); $result = []; $result['job_id'] = $jobId; diff --git a/vapor.yml b/vapor.yml index 38d4e1a6..a0d31602 100644 --- a/vapor.yml +++ b/vapor.yml @@ -6,6 +6,9 @@ environments: domain: production.exchange.izyim.com memory: 1024 cli-memory: 512 + queues: + - exchange-default-production + - exchange-high_priority-production database: cief-rds-mysql storage: exchange-2.0-production # gateway-version: 2 @@ -30,6 +33,9 @@ environments: domain: staging.exchange.izyim.com memory: 1024 cli-memory: 512 + queues: + - exchange-default-staging + - exchange-high_priority-staging database: cief-rds-mysql storage: exchange-2.0-staging runtime: 'docker' @@ -45,6 +51,9 @@ environments: domain: dev.exchange.izyim.com memory: 1024 cli-memory: 512 + queues: + - exchange-default-development + - exchange-high_priority-development database: cief-rds-mysql storage: exchange-2.0-development runtime: 'docker' From 4ec90b68da1d4ccde6cb9049a39a6da70c98d33c Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Fri, 22 Mar 2024 16:43:17 +0800 Subject: [PATCH 148/434] Fix a problem when using vue polling method at /dashboard page > currency orders tab > changing ddl does not get list updated --- .../SupplierPendingOrdersSectionComponent.vue | 8 ++++---- .../general/elements/ListPollingComponent.vue | 14 +++++++------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/resources/assets/vue/components/bookings/sections/SupplierPendingOrdersSectionComponent.vue b/resources/assets/vue/components/bookings/sections/SupplierPendingOrdersSectionComponent.vue index fb766fe4..6b83d563 100644 --- a/resources/assets/vue/components/bookings/sections/SupplierPendingOrdersSectionComponent.vue +++ b/resources/assets/vue/components/bookings/sections/SupplierPendingOrdersSectionComponent.vue @@ -117,16 +117,16 @@
- + + - --> +
diff --git a/resources/assets/vue/components/general/elements/ListPollingComponent.vue b/resources/assets/vue/components/general/elements/ListPollingComponent.vue index 6d945cb6..11ae89b6 100644 --- a/resources/assets/vue/components/general/elements/ListPollingComponent.vue +++ b/resources/assets/vue/components/general/elements/ListPollingComponent.vue @@ -103,13 +103,13 @@ this.isLoading = true; this.submitJob(url); }, - //cief todo: remove? - // updateFilters(filters){ - // this.filters = filters; - // this.setDecoratorDefault(); - // console.log('updateFilters'); - // this.submit(this.endpoint + '?page=1&filters=' + JSON.stringify(this.filters), 'get', this.section, false, false); //cief todo: Uncaught (in promise) null - // }, + updateFilters(filters){ + console.log('ListPollingComponent updateFilters: ' + JSON.stringify(filters)); + this.filters = filters; + this.setDecoratorDefault(); + this.$store.dispatch('updateListQueue', {'name': this.section, 'page': 1, 'filters': this.filters}); + // this.submit(this.endpoint + '?page=1&filters=' + JSON.stringify(this.filters), 'get', this.section, false, false); //cief todo: Uncaught (in promise) null + }, successHandler(response){ let result = JSON.parse(response.payload.data.result); result.meta = { From a200f7083b99827da6b7a3a7a92c313302701a7f Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Sun, 24 Mar 2024 18:20:24 +0800 Subject: [PATCH 149/434] Laravel Vapor - Version 2 of Commands for 3 files + Resolved 3 TODOs --- .../V2/AutoFillPurchaseOrderV2CommandJob.php | 89 ++++++++++++ .../V2/ExpiredBookingV2CommandJob.php | 81 +++++++++++ .../V2/ExpiredRefundedBookingV2CommandJob.php | 137 ++++++++++++++++++ .../V2/AutoFillPurchaseOrderV2Command.php | 34 +++++ .../Commands/V2/ExpiredBookingV2Command.php | 34 +++++ .../V2/ExpiredRefundedBookingV2Command.php | 34 +++++ app/Console/Kernel.php | 10 +- .../assets/vue/vuex/modules/crudRequest.js | 4 +- routes/api.php | 4 +- 9 files changed, 420 insertions(+), 7 deletions(-) create mode 100644 app/Classes/Jobs/Commands/V2/AutoFillPurchaseOrderV2CommandJob.php create mode 100644 app/Classes/Jobs/Commands/V2/ExpiredBookingV2CommandJob.php create mode 100644 app/Classes/Jobs/Commands/V2/ExpiredRefundedBookingV2CommandJob.php create mode 100644 app/Console/Commands/V2/AutoFillPurchaseOrderV2Command.php create mode 100644 app/Console/Commands/V2/ExpiredBookingV2Command.php create mode 100644 app/Console/Commands/V2/ExpiredRefundedBookingV2Command.php diff --git a/app/Classes/Jobs/Commands/V2/AutoFillPurchaseOrderV2CommandJob.php b/app/Classes/Jobs/Commands/V2/AutoFillPurchaseOrderV2CommandJob.php new file mode 100644 index 00000000..1d1b86f9 --- /dev/null +++ b/app/Classes/Jobs/Commands/V2/AutoFillPurchaseOrderV2CommandJob.php @@ -0,0 +1,89 @@ +where('created_at', '<', now()->subDays(60)->endOfDay()) + ->whereHas('transactions', function($transaction) { + return $transaction->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); + }) + ->whereDoesntHave('transactions', function($transaction){ + $transaction->where('type', TransactionType::PURCHASE_ORDER); + $transaction->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED]); + })->get(); + Log::info('Bookings count: '.count($bookings)); + + foreach ($bookings as $booking) { + $po = Transaction::where('type', TransactionType::PURCHASE_ORDER) + ->where('status', ApprovalStatus::APPROVED)->where('issuer', $booking->company_id) + ->select('*', DB::raw('abs(amount - ' . $booking->fix_amount . ') as nearest_price'))->orderBy('nearest_price')->first(); + + + if (!$po) { + $po = Transaction::where('type', TransactionType::PURCHASE_ORDER) + ->where('status', ApprovalStatus::APPROVED)->select('*', DB::raw('abs(amount - ' . $booking->fix_amount . ') as nearest_price'))->orderBy('nearest_price')->first(); + } + + $products = (App()->make(GeneratesPurchaseOrderProducts::class))->execute($po, $booking->fix_amount); + + $deference = $booking->fix_amount - $products->sum('total'); + + if($deference > -150 && $deference < 150 && $deference != 0) { + + $products->push([ + 'description' => $deference < 0 ? 'Discount':'Shipping Fee', + 'quantity' => 1, + 'stockCode' => '', + 'total' => $deference, + 'unit_price' => $deference + ]); + } + + $billNumber = (App()->make(GeneratesTransactionBillNumber::class))->execute('XPO-'); + + Log::info('Single booking billNumber: '.$billNumber); + + $total = $products->sum('total'); + + $object = new TransactionObject($billNumber, TransactionType::PURCHASE_ORDER, $booking->company->id, 1, + 1, PaymentMethodType::CASH, + $total, $total, $booking->fix_currency_id, $booking->fix_currency_id, + 1, 0, 0, null, ApprovalStatus::PENDING_SUBMISSION, $products->toArray()); + + (App()->make(CreatePurchaseOrderTransactionProcessor::class))->execute($booking, $object); + } + + $end = new Carbon(); + $elapsedTime = $start->diff($end)->format('%H:%I:%S'); + Log::info(Carbon::now() . ': End job - Auto fill up the purchase order for booking that have payment. ElapsedTime: ' . $elapsedTime . '.'); + } +} diff --git a/app/Classes/Jobs/Commands/V2/ExpiredBookingV2CommandJob.php b/app/Classes/Jobs/Commands/V2/ExpiredBookingV2CommandJob.php new file mode 100644 index 00000000..22f91ba6 --- /dev/null +++ b/app/Classes/Jobs/Commands/V2/ExpiredBookingV2CommandJob.php @@ -0,0 +1,81 @@ +where('created_at', '<', now()->subDays(30)->endOfDay()) + ->where(function ($query) { + $query->whereDoesntHave('transactions') + ->orWhereDoesntHave('transactions', function($transaction) { + return $transaction->where('type', TransactionType::PURCHASE_ORDER)->orWhere(function ($q) { + $q->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); + }); + }); + })->get(); + + foreach ($bookings as $booking) { + (App()->make(UpdatesBookingStatus::class))->execute($booking, ApprovalStatus::EXPIRED); + Log::info(Carbon::now() . " : Expired Booking without payment & purchase order, booking id: " . $booking->id); + $transactions = $booking->transactions; + + foreach ($transactions as $transaction) { + $prevStatus = $transaction->status; + $transaction->status = ApprovalStatus::EXPIRED; + $transaction->save(); + Log::info(Carbon::now() . " : Expired Transaction id: {$transaction->id} from Booking id: {$booking->id}. Status before update: {$prevStatus}"); + } + } + + // 2. Cancel booking without payment but with purchase order (2 month) + $bookings = Booking::where('status', ApprovalStatus::APPROVED) + ->where('created_at', '<', now()->subDays(60)->endOfDay()) + ->where(function ($query) { + $query->whereDoesntHave('transactions', function($transaction) { + return $transaction->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); + })->whereHas('transactions', function($transaction) { + return $transaction->where('type', TransactionType::PURCHASE_ORDER); + }); + })->get(); + + foreach ($bookings as $booking) { + (App()->make(UpdatesBookingStatus::class))->execute($booking, ApprovalStatus::EXPIRED); + Log::info(Carbon::now() . " : Expired Booking without payment but with purchase order, booking id: " . $booking->id); + $transactions = $booking->transactions; + + foreach ($transactions as $transaction) { + $prevStatus = $transaction->status; + $transaction->status = ApprovalStatus::EXPIRED; + $transaction->save(); + Log::info(Carbon::now() . " : Expired Transaction id: {$transaction->id} from Booking id: {$booking->id}. Status before update: {$prevStatus}"); + } + } + + $end = new Carbon(); + $elapsedTime = $start->diff($end)->format('%H:%I:%S'); + Log::info(Carbon::now() . ': End job - Expiring booking that do not have further action by user. ElapsedTime: ' . $elapsedTime . '.'); + } +} diff --git a/app/Classes/Jobs/Commands/V2/ExpiredRefundedBookingV2CommandJob.php b/app/Classes/Jobs/Commands/V2/ExpiredRefundedBookingV2CommandJob.php new file mode 100644 index 00000000..4d5ad89e --- /dev/null +++ b/app/Classes/Jobs/Commands/V2/ExpiredRefundedBookingV2CommandJob.php @@ -0,0 +1,137 @@ +where('payment_reference', 'LIKE', "%refund%")->get(); + + foreach ($transactions as $transaction) { + // get the booking marking + $payment_reference = explode(" ", trim($transaction->payment_reference)); + // $marking = substr($transaction->payment_reference, -5); + $marking = trim(end($payment_reference)); + + if (!preg_match('/^[0-9]+$/', $marking)) { + $payment_reference = explode(".", trim($transaction->payment_reference)); + $marking = trim(end($payment_reference)); + } + + // for a special payment reference on transaction id: 140231 + if (!preg_match('/^[0-9]+$/', $marking)) { + $payment_reference = explode("No", trim($transaction->payment_reference)); + $marking = end($payment_reference); + } + + // for a special payment reference on transaction id: 152013 + if (!preg_match('/^[0-9]+$/', $marking)) { + $payment_reference = explode(" ", trim($transaction->payment_reference)); + $marking = end($payment_reference); + $marking = prev($payment_reference); + } + + if (preg_match('/^[0-9]+$/', $marking)) { + $booking = Booking::where('marking', $marking)->first(); + + if ($booking) { + $bookingPayment = $booking->transactions()->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->first(); + if (!$bookingPayment) { + $bookingPaymentCount = $booking->transactions()->payments()->count(); + if ($bookingPaymentCount > 1) { + Log::info("Credit note transaction id: {$transaction->id}, there are {$bookingPaymentCount} payment for the booking."); + foreach ($booking->transactions()->payments()->get() as $bp) { + if ($transaction->amount - $bp->amount < 0.01) { + $bookingPayment = $bp; + break; + } + } + } + + if (!$bookingPayment) { + $bookingPayment = $booking->transactions()->payments()->whereIn('status', [ApprovalStatus::SUSPENDED, ApprovalStatus::EXPIRED, ApprovalStatus::REJECTED])->orderBy('id', 'DESC')->first(); + } + $status = ApprovalStatus::APPROVAL_STATUS_ID[$bookingPayment->status]; + Log::info("Credit note transaction id: {$transaction->id}, the payment for the booking is in status {$status}"); + } + $bookingPaymentAmount = $bookingPayment->amount; + // check if the booking is fully refund + $amountDifference = bcsub($transaction->amount, $bookingPaymentAmount, 7); + + if (abs($amountDifference) < 0.01) { + // rejecting booking payment transaction + // $bookingPayment->status = ApprovalStatus::REJECTED; + // $bookingPayment->save(); + + //expired booking + // $this->updatesBookingStatus->execute($booking, ApprovalStatus::EXPIRED); + Log::info("Credit note transaction id: {$transaction->id} is fully refunded, the refunded amount was {$transaction->amount} the payment reference is: {$transaction->payment_reference}"); + // Log::info("Credit note transaction id: {$transaction->id}, Rejected Booking Transaction Payment id: {$bookingPayment->id}, the payment amount was {$bookingPayment->amount}"); + // Log::info("Credit note transaction id: {$transaction->id}, Expired Booking id: {$booking->id}"); + } else { + Log::info("Credit note transaction id: {$transaction->id} is not fully refunded, the refunded amount was {$transaction->amount}, the payment amount was {$bookingPayment->amount}, the payment reference is: {$transaction->payment_reference}"); + } + + $refund = $bookingPayment->transactions()->refunds()->where('amount', $transaction->amount)->where('status', ApprovalStatus::APPROVED)->first(); + + $bookingInWhiteForm = $bookingPayment->transactions()->bills()->first(); + + if ($refund) { + Log::info("Credit note transaction id: {$transaction->id}, already created same amount of refund transaction for same booking payment transaction"); + } + + if ($bookingInWhiteForm) { + Log::info("Credit note transaction id: {$transaction->id}, booking is in white form"); + } + + if (!$refund && !$bookingInWhiteForm) { + $billNumber = (App()->make(GeneratesTransactionBillNumber::class))->execute('RFD-'); + + $object = new TransactionObject($billNumber, TransactionType::REFUND, 1, $booking->company->id, + 1, PaymentMethodType::CASH, + $transaction->amount, $transaction->amount * $bookingPayment->currency_rate, 1, + $bookingPayment->original_currency_id, $bookingPayment->currency_rate, + 0, 0, null, ApprovalStatus::APPROVED, [], $bookingPayment->bill_no); + + $transaction =(App()->make(CreatesTransaction::class))->execute($bookingPayment, $object); + } + } else { + Log::info("Credit note transaction id: {$transaction->id}, booking marking not found, the payment reference is: {$transaction->payment_reference}"); + } + } else { + Log::info("Credit note transaction id: {$transaction->id} does not have booking marking, the payment reference is: {$transaction->payment_reference}"); + } + } + + + + $end = new Carbon(); + $elapsedTime = $start->diff($end)->format('%H:%I:%S'); + Log::info(Carbon::now() . ': End job - Expiring refunded booking. ElapsedTime: ' . $elapsedTime . '.'); + } +} diff --git a/app/Console/Commands/V2/AutoFillPurchaseOrderV2Command.php b/app/Console/Commands/V2/AutoFillPurchaseOrderV2Command.php new file mode 100644 index 00000000..a6f83a32 --- /dev/null +++ b/app/Console/Commands/V2/AutoFillPurchaseOrderV2Command.php @@ -0,0 +1,34 @@ +command('new-user-registration-expire-check-command') ->dailyAt('23:55') ->withoutOverlapping(); + + $schedule->command('booking-expired-command') + ->dailyAt('02:00') + ->withoutOverlapping(); + + // $schedule->command('purchase-order-autofill-command') + // ->dailyAt('03:00') + // ->withoutOverlapping(); } //Commands Version 1: Before Laravel Vapor/AWS else{ @@ -68,13 +76,11 @@ class Kernel extends ConsoleKernel ->appendOutputTo(storage_path().'/logs/delete-bulk-download-files.log') ->withoutOverlapping(); - //cief todo: command version 2 $schedule->command('booking:expired') ->dailyAt('02:00') ->appendOutputTo(storage_path().'/logs/expire-booking.log') ->withoutOverlapping(); - //cief todo: command version 2 // $schedule->command('purchaseOrder:autoFill') // ->dailyAt('03:00') // ->withoutOverlapping(); diff --git a/resources/assets/vue/vuex/modules/crudRequest.js b/resources/assets/vue/vuex/modules/crudRequest.js index cea9f12d..6f1b6ee0 100644 --- a/resources/assets/vue/vuex/modules/crudRequest.js +++ b/resources/assets/vue/vuex/modules/crudRequest.js @@ -1,8 +1,8 @@ export default { actions: { crudRequest({getters, dispatch}, {endpoint, method, parameters}){ - console.log(endpoint); - console.log(window.LARAVEL_VAPOR_ENABLED); + // console.log(endpoint); + // console.log(window.LARAVEL_VAPOR_ENABLED); return dispatch('ensureReCaptchaIsSet').then(function () { let combinedAbsoluteUrl = endpoint; if(window.LARAVEL_VAPOR_ENABLED){ diff --git a/routes/api.php b/routes/api.php index 460bd772..9d67e62c 100644 --- a/routes/api.php +++ b/routes/api.php @@ -60,15 +60,13 @@ Route::group(['middleware' => 'api', 'prefix' => 'v1', 'as' => 'api.'], function require __DIR__ . '/wallet.php'; require __DIR__ . '/voucher.php'; - + require __DIR__ . '/accounting.php'; require __DIR__ . '/reward.php'; require __DIR__ . '/milestone.php'; - // require __DIR__ . '/accounting.php'; //cief todo: To check if this is needed - require __DIR__ . '/job.php'; // require __DIR__ . '/rate.php'; From 454b1ff1a942834829cf9517c7bde10cde69a928 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Sun, 24 Mar 2024 18:26:09 +0800 Subject: [PATCH 150/434] To test run new command --- app/Console/Kernel.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 6342a8b2..abb6762a 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -50,7 +50,8 @@ class Kernel extends ConsoleKernel ->withoutOverlapping(); $schedule->command('new-user-registration-expire-check-command') - ->dailyAt('23:55') + //->dailyAt('23:55') //cief todo: original, to be reverted back to this + ->everyFifteenMinutes() ->withoutOverlapping(); $schedule->command('booking-expired-command') From 102e0a6fa68a46e5f60e605f46b4fdc82116e5b6 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Sun, 24 Mar 2024 19:01:06 +0800 Subject: [PATCH 151/434] Test run schedule task - NewUserRegistrationExpireCheckV2CommandJob --- .../Commands/V2/NewUserRegistrationExpireCheckV2CommandJob.php | 2 ++ app/Models/UserEmailVerification.php | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/Classes/Jobs/Commands/V2/NewUserRegistrationExpireCheckV2CommandJob.php b/app/Classes/Jobs/Commands/V2/NewUserRegistrationExpireCheckV2CommandJob.php index c0c4ecda..45155927 100644 --- a/app/Classes/Jobs/Commands/V2/NewUserRegistrationExpireCheckV2CommandJob.php +++ b/app/Classes/Jobs/Commands/V2/NewUserRegistrationExpireCheckV2CommandJob.php @@ -22,6 +22,8 @@ class NewUserRegistrationExpireCheckV2CommandJob implements ShouldQueue $start = new Carbon(); $attempts = UserEmailVerification::active()->twoDaysOld()->get(); + + Log::info('Carbon now()->subHours(48): '. Carbon::now()->subHours(48)); Log::info('Attempts count: '.count($attempts)); foreach ($attempts as $attempt){ diff --git a/app/Models/UserEmailVerification.php b/app/Models/UserEmailVerification.php index c4b60c7c..718420bc 100644 --- a/app/Models/UserEmailVerification.php +++ b/app/Models/UserEmailVerification.php @@ -33,6 +33,6 @@ class UserEmailVerification extends AbstractModel */ public function scopeTwoDaysOld($query) { - return $query->where('created_at', '>=', Carbon::now()->subHours(48)); + return $query->where('created_at', '<=', Carbon::now()->subHours(48)); } } From 7fc11cc7e7f667e3bb8048b46a6732c1d2d85b4b Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Sun, 24 Mar 2024 19:44:17 +0800 Subject: [PATCH 152/434] Laravel Vapor - Added comments for debugging code --- routes/web.php | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/routes/web.php b/routes/web.php index bdc41b62..d34e1b56 100644 --- a/routes/web.php +++ b/routes/web.php @@ -802,17 +802,6 @@ Route::get('/customer/vouchers/{marking}', function ($marking) { })->name('customer.reward'); Route::get('transaction/{id}/credit_note/download', 'Transactions\GenerateCreditNotePdfController@download')->name('transaction.credit_note.download'); -Route::get('/aws-image-upload', 'AWS\AWSImageUploadController@imageUpload')->name('aws.image.upload'); -Route::post('/aws-image-upload', 'AWS\AWSImageUploadController@imageUploadPost')->name('aws.image.upload.post'); -Route::get('/aws-image/{filename}', 'AWS\AWSImageUploadController@displayImage')->name('aws.image.displayImage'); - -Route::get('/token', function (Request $request) { - $token = $request->session()->token(); - echo $token; - $token = csrf_token(); - echo $token; - -}); Route::get('/invoice/{marking}/{started_at}/{ended_at}/fix', function($marking, $started_at, $ended_at) { @@ -890,3 +879,16 @@ Route::get('/invoice/{marking}/{started_at}/{ended_at}/fix', function($marking, } ); })->name('invoice.fix.byCustomerMarking'); + +//Laravel Vapor - Starts +Route::get('/aws-image-upload', 'AWS\AWSImageUploadController@imageUpload')->name('aws.image.upload'); +Route::post('/aws-image-upload', 'AWS\AWSImageUploadController@imageUploadPost')->name('aws.image.upload.post'); +Route::get('/aws-image/{filename}', 'AWS\AWSImageUploadController@displayImage')->name('aws.image.displayImage'); + +Route::get('/token', function (Request $request) { + $token = $request->session()->token(); + echo $token; + $token = csrf_token(); + echo $token; +}); +//Laravel Vapor - Ends From bd7fd92cf0920f788d159e947c753c99667b38da Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Sun, 24 Mar 2024 20:14:38 +0800 Subject: [PATCH 153/434] Laravel Vapor - Delete comments --- app/Classes/Jobs/ListDocumentsJob.php | 11 ----------- .../Accounts/Processors/AuthenticationProcessor.php | 2 +- .../Addresses/ControllersLogic/CreateAddressLogic.php | 2 +- .../Banks/ControllersLogic/CreateBankLogic.php | 2 +- .../Bookings/ControllersLogic/CreateBookingLogic.php | 2 +- .../ControllersLogic/AssignCompanyToSegmentLogic.php | 2 +- .../CreateIdentificationDocumentLogic.php | 2 +- app/Http/Controllers/AWS/AWSImageUploadController.php | 2 +- app/Http/Resources/CompanyResource.php | 4 ---- 9 files changed, 7 insertions(+), 22 deletions(-) diff --git a/app/Classes/Jobs/ListDocumentsJob.php b/app/Classes/Jobs/ListDocumentsJob.php index 6e93062b..25247c50 100644 --- a/app/Classes/Jobs/ListDocumentsJob.php +++ b/app/Classes/Jobs/ListDocumentsJob.php @@ -44,17 +44,6 @@ class ListDocumentsJob implements ShouldQueue } $result = (App()->make(ListDocumentsJobProcessor::class))->execute($this->listGenericJobObject); - - //cief todo: Insert into DB: job id, query result, timestamp - // Store the result in the job_results table - - //cief todo: why cannot save data in table like this - // $model = new JobResult(); - // $model->job_id = $this->job->getJobId(); - // $model->result = json_encode($result); - // $model->save(); - - // Log::error(json_encode($model->id)); } public function getJobId(){ diff --git a/app/Classes/Modules/Accounts/Processors/AuthenticationProcessor.php b/app/Classes/Modules/Accounts/Processors/AuthenticationProcessor.php index 707369e9..952bebdd 100644 --- a/app/Classes/Modules/Accounts/Processors/AuthenticationProcessor.php +++ b/app/Classes/Modules/Accounts/Processors/AuthenticationProcessor.php @@ -81,7 +81,7 @@ class AuthenticationProcessor $this->newCustomerToVoucherifyProcessor->execute(0, $user, false); } - //cief todo: case study 1 + //cief todo: case study 1 voucherify //$this->checkMilestonesForRewardProcessor->execute($user, [Milestones::MILESTONE_1]); return ['access_token' => $this->generatesAuthenticationToken->execute($user), 'redirect_url' => $this->authenticationRedirect->url($user)]; diff --git a/app/Classes/Modules/Addresses/ControllersLogic/CreateAddressLogic.php b/app/Classes/Modules/Addresses/ControllersLogic/CreateAddressLogic.php index a760254f..9c5bc602 100644 --- a/app/Classes/Modules/Addresses/ControllersLogic/CreateAddressLogic.php +++ b/app/Classes/Modules/Addresses/ControllersLogic/CreateAddressLogic.php @@ -81,7 +81,7 @@ class CreateAddressLogic extends AbstractControllerLogic $company = $this->fetchesCompany->execute(['id' => $request->input('company_id')]); $query = $this->createsAddress->execute($company, $object); - //cief todo: case study 6 + //cief todo: case study 6 voucherify // $user = $company->employees()->first(); // $this->checkMilestonesForRewardProcessor->execute($user, [Milestones::MILESTONE_6]); diff --git a/app/Classes/Modules/Banks/ControllersLogic/CreateBankLogic.php b/app/Classes/Modules/Banks/ControllersLogic/CreateBankLogic.php index bb9a3468..7d340b74 100644 --- a/app/Classes/Modules/Banks/ControllersLogic/CreateBankLogic.php +++ b/app/Classes/Modules/Banks/ControllersLogic/CreateBankLogic.php @@ -89,7 +89,7 @@ class CreateBankLogic extends AbstractControllerLogic // $bankLog = $this->createsBankLog->execute($bank); - //cief todo: case study 4 + //cief todo: case study 4 voucherify // $company = $this->fetchesCompany->execute(['id' => $request->input('company_id')]); // $user = $company->employees()->first(); // $this->checkMilestonesForRewardProcessor->execute($user, [Milestones::MILESTONE_4]); diff --git a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingLogic.php index 61f78dcb..9c13a015 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingLogic.php @@ -97,7 +97,7 @@ class CreateBookingLogic extends AbstractControllerLogic $this->bookingToPerfexCRMProcessor->execute($booking); } - //cief todo: case study 5 + //cief todo: case study 5 voucherify // $user = $company->employees()->first(); // $this->checkMilestonesForRewardProcessor->execute($user, [Milestones::MILESTONE_5]); diff --git a/app/Classes/Modules/Companies/ControllersLogic/AssignCompanyToSegmentLogic.php b/app/Classes/Modules/Companies/ControllersLogic/AssignCompanyToSegmentLogic.php index 1148a6d6..3e8d0110 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/AssignCompanyToSegmentLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/AssignCompanyToSegmentLogic.php @@ -88,7 +88,7 @@ class AssignCompanyToSegmentLogic extends AbstractControllerLogic $this->createsSeasonalSegment->execute($seasonalSegmentObject); } - //cief todo: case study 3 + //cief todo: case study 3 voucherify // $user = $company->employees()->first(); // $this->checkMilestonesForRewardProcessor->execute($user, [Milestones::MILESTONE_3]); diff --git a/app/Classes/Modules/Companies/ControllersLogic/CreateIdentificationDocumentLogic.php b/app/Classes/Modules/Companies/ControllersLogic/CreateIdentificationDocumentLogic.php index 6a818ea8..5e1c331d 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/CreateIdentificationDocumentLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/CreateIdentificationDocumentLogic.php @@ -94,7 +94,7 @@ class CreateIdentificationDocumentLogic extends AbstractControllerLogic $this->newLeadTaskToPerfexCRMProcessor->execute($company); } - //cief todo: case study 2 + //cief todo: case study 2 voucherify // $user = $company->employees()->first(); // $this->checkMilestonesForRewardProcessor->execute($user, [Milestones::MILESTONE_2]); diff --git a/app/Http/Controllers/AWS/AWSImageUploadController.php b/app/Http/Controllers/AWS/AWSImageUploadController.php index f034b3a1..b0929c06 100644 --- a/app/Http/Controllers/AWS/AWSImageUploadController.php +++ b/app/Http/Controllers/AWS/AWSImageUploadController.php @@ -29,7 +29,7 @@ class AWSImageUploadController extends Controller $request->image->storeAs('images', $imageName); - //cief todo: checking if storage disk exist + //checking if storage disk exist if (Storage::disk('documents')) { $check1 = "The disk documents exists."; } else { diff --git a/app/Http/Resources/CompanyResource.php b/app/Http/Resources/CompanyResource.php index 55043f85..59eb3cee 100644 --- a/app/Http/Resources/CompanyResource.php +++ b/app/Http/Resources/CompanyResource.php @@ -52,10 +52,6 @@ class CompanyResource extends JsonResource $userInfoType = Auth::user()->type; } - //cief todo: remove - // Log::error('CompanyResource 1: '. json_encode($userInfoEmail)); - // Log::error('CompanyResource 2: '. json_encode($userInfoType)); - if(!is_null($userInfoEmail) && !is_null($userInfoType)){ $userResource = new UserResource($userInfoType === RoleTypes::USER ? $this->employees()->where('email', '=', $userInfoEmail)->first() : $this->employees()->orderBy('id', 'DESC')->first()); } From c95c274db7ded39b5c070e72a3dbc74109f20836 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Mon, 25 Mar 2024 00:47:52 +0800 Subject: [PATCH 154/434] update --- .../bookings/elements/SupplierRefundComponent.vue | 9 ++++++--- .../bookings/forms/PurchaseOrderFormComponent.vue | 10 +++++----- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/resources/assets/vue/components/bookings/elements/SupplierRefundComponent.vue b/resources/assets/vue/components/bookings/elements/SupplierRefundComponent.vue index 872ebef4..68839221 100644 --- a/resources/assets/vue/components/bookings/elements/SupplierRefundComponent.vue +++ b/resources/assets/vue/components/bookings/elements/SupplierRefundComponent.vue @@ -17,11 +17,14 @@ {{item.created_at}}
+
+
Reference
+ +
Amount
-
{{item.currency.short_code}} {{((Math.round(( item.amount + Number.EPSILON) * 100) / 100)).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
diff --git a/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue b/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue index ad3627ba..b9a0f2d6 100644 --- a/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue +++ b/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue @@ -117,7 +117,7 @@
-
+
-
{{(Math.round(( poTotal + Number.EPSILON) * 1000) / 1000).toFixed(3)}}/{{(Math.round((data.paid_amount + Number.EPSILON) * 1000) / 1000).toFixed(3)}} {{data.fixed_currency.short_code}}
+
{{(Math.round(( poTotal + Number.EPSILON) * 1000) / 1000).toFixed(3)}}/{{(Math.round((data.amount + Number.EPSILON) * 1000) / 1000).toFixed(3)}} {{data.fixed_currency.short_code}}
- +
-
+
** you purchase order will be saved but wont be approved until your purchase order's total matches your transfer order's total.
@@ -286,7 +286,7 @@ this.submit(route('api.transaction.po.import', this.data.id), 'post', this.section, true, true); }, successHandler(){ - if((Math.round((this.poTotal + Number.EPSILON) * 1000) / 1000).toFixed(3) === (Math.round((this.data.paid_amount + Number.EPSILON) * 1000) / 1000).toFixed(3)){ + if((Math.round((this.poTotal + Number.EPSILON) * 1000) / 1000).toFixed(3) === (Math.round((this.data.amount + Number.EPSILON) * 1000) / 1000).toFixed(3)){ this.submitted = true; } this.updateList() From 3deba3468aec8eb4b2526c4370eea62b50a18077 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Mon, 25 Mar 2024 15:06:46 +0800 Subject: [PATCH 155/434] -Approve refund - only super admin -If invoice generated - only super admin can request refund --- .../ControllersLogic/CreateBookingRefundLogic.php | 10 ++++++---- .../UpdateRefundTransactionStatusLogic.php | 7 ++++++- .../bookings/elements/PaymentHistoryComponent.vue | 4 ++-- .../bookings/elements/RefundVerificationComponent.vue | 2 +- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php index 062db191..7e176363 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php @@ -73,14 +73,16 @@ class CreateBookingRefundLogic extends AbstractControllerLogic public function logic(Request $request) : JsonResponse { - if(auth()->user()->type === 3) { - throw new MalformedRequestException('You do not have the permission to refund the order.'); - } - $transaction = $this->fetchesTransaction->execute(['id' => $request->route('payment_id')]); $booking = $transaction->owner; + $invoice = $booking->transactions()->where('type', TransactionType::INVOICE)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->first(); + + if(auth()->user()->type === 3 || ($invoice && !(auth()->user()->type === 0 || auth()->user()->type === 1))) { + throw new MalformedRequestException('You do not have the permission to refund the order.'); + } + $billNumber = $this->generatesTransactionBillNumber->execute('RFD-'); $refund = $transaction->transactions()->refunds()->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED])->sum('original_amount'); diff --git a/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php index 25db0f31..615ded20 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php @@ -2,7 +2,7 @@ namespace App\Classes\Modules\Transactions\ControllersLogic; - +use App\Classes\Exceptions\MalformedRequestException; use App\Classes\General\Abstracts\AbstractControllerLogic; use App\Classes\Modules\Bookings\ControllersLogic\UpdateBookingAmountLogic; use App\Classes\Modules\Companies\Services\FetchesCompany; @@ -17,6 +17,7 @@ use App\Classes\Modules\Wallets\Processors\CreditWalletProcessor; use App\Classes\Modules\Bookings\Services\CalculatesBookingPayableAmount; use App\Classes\Modules\Bookings\Services\CalculatesBookingRefundAmount; use App\Classes\ValueObjects\Constants\TransactionType; +use Illuminate\Support\Facades\Auth; class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic { @@ -85,6 +86,10 @@ class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic */ public function logic(Request $request) : JsonResponse { + if (!(Auth::user()->type === 0 || Auth::user()->type === 1)) { + throw new MalformedRequestException('Only super admin can update refund status.'); + } + $refundTransaction = $this->fetchesTransaction->execute(['id' => $request->route('id')]); $refundTransaction = $this->updatesTransactionStatus->execute($refundTransaction, $request->route('status')); diff --git a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue index e3be870f..ec0c0d7a 100644 --- a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue +++ b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue @@ -290,7 +290,7 @@
-
+
@@ -345,7 +345,7 @@
-
+
-
+
From 5edf52eb5f7505aa619b6de03ca8aeddb28c947f Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Tue, 26 Mar 2024 03:25:24 +0800 Subject: [PATCH 156/434] Vue Polling - Revert back to original code, created new resource files for vue polling component, see next commit --- app/Http/Resources/BookingResource.php | 2 +- app/Http/Resources/CompanyResource.php | 27 +------------------------ app/Http/Resources/DocumentResource.php | 5 +---- 3 files changed, 3 insertions(+), 31 deletions(-) diff --git a/app/Http/Resources/BookingResource.php b/app/Http/Resources/BookingResource.php index 14fd2936..6803eec9 100644 --- a/app/Http/Resources/BookingResource.php +++ b/app/Http/Resources/BookingResource.php @@ -25,7 +25,7 @@ class BookingResource extends JsonResource { return [ 'id' => $this->id, - 'company' => new CompanyResource($this->company, $this->userInfo), + 'company' => new CompanyResource($this->company), 'bank' => new BankResource($this->bank), 'service' => new ServiceTypeResource($this->service), 'marking' => $this->marking, diff --git a/app/Http/Resources/CompanyResource.php b/app/Http/Resources/CompanyResource.php index 59eb3cee..eff2bd1b 100644 --- a/app/Http/Resources/CompanyResource.php +++ b/app/Http/Resources/CompanyResource.php @@ -18,14 +18,6 @@ use Illuminate\Support\Facades\Auth; class CompanyResource extends JsonResource { - private $userInfo; - - public function __construct($resource, $userInfo = null) - { - parent::__construct($resource); - $this->userInfo = $userInfo; - } - /** * Transform the resource into an array. * @@ -40,22 +32,6 @@ class CompanyResource extends JsonResource $segment = SegmentConstant::where('reference', SegmentConstants::SUPPLIER_CURRENCIES)->where('detail->id', $this->id)->first(); $serviceCharge = SegmentConstant::where('reference', SegmentConstants::SERVICE_CHARGE)->where('detail->id', $this->id)->first(); - $userResource = null; - - $userInfoEmail = $this->userInfo && isset($this->userInfo->email) ? $this->userInfo->email : null; - $userInfoType = $this->userInfo && isset($this->userInfo->type) ? $this->userInfo->type : null; - - if(!$userInfoEmail && Auth::user()){ - $userInfoEmail = Auth::user()->email; - } - if(!$userInfoType && Auth::user()){ - $userInfoType = Auth::user()->type; - } - - if(!is_null($userInfoEmail) && !is_null($userInfoType)){ - $userResource = new UserResource($userInfoType === RoleTypes::USER ? $this->employees()->where('email', '=', $userInfoEmail)->first() : $this->employees()->orderBy('id', 'DESC')->first()); - } - return [ 'id' => $this->id, 'name' => $this->name, @@ -66,8 +42,7 @@ class CompanyResource extends JsonResource 'status' => (int) $this->status, 'contact' => new ContactResource ($this->when($this->has('contacts'), $this->contacts->first())), 'address' => new AddressResource($this->when($this->has('addresses'), $this->addresses->where('billing', true)->first())), - //cief todo: this one need to decide what to do to replace Auth:user() when it is run by job queue - 'employee' => $userResource, + 'employee' => new UserResource(Auth::user()->type === RoleTypes::USER ? $this->employees()->where('email', '=', Auth::user()->email)->first() : $this->employees()->orderBy('id', 'DESC')->first()), 'identification' => new DocumentResource($this->documents->whereIn('document_type', DocumentType::IDENTIFICATION_DOCUMENTS)->first()), 'bookings' => $this->whenLoaded('bookings', $this->bookings()->orderBy('id', 'DESC')->get(), []), 'confirmed_bookings' => $this->bookings()->whereHas('transactions', function ($query){ diff --git a/app/Http/Resources/DocumentResource.php b/app/Http/Resources/DocumentResource.php index 075e27f3..c0f801bb 100644 --- a/app/Http/Resources/DocumentResource.php +++ b/app/Http/Resources/DocumentResource.php @@ -5,9 +5,6 @@ namespace App\Http\Resources; use App\Models\Booking; use Carbon\Carbon; use Illuminate\Http\Resources\Json\JsonResource; -use Illuminate\Support\Facades\Log; -use Illuminate\Support\Facades\Auth; -use Illuminate\Http\Resources\Json\AnonymousResourceCollection; class DocumentResource extends JsonResource { @@ -24,7 +21,7 @@ class DocumentResource extends JsonResource 'reference' => $this->reference, 'status' => (int) $this->status, 'document_type' => $this->document_type, - 'owner' => $this->relationLoaded('owner') ? ($this->owner instanceof Booking ? new BookingResource($this->owner, $this->userInfo) : new CompanyResource($this->owner, $this->userInfo)) : null, + 'owner' => $this->relationLoaded('owner') ? ($this->owner instanceof Booking ? new BookingResource($this->owner) : new CompanyResource($this->owner)) : null, 'files' => FileResource::collection($this->files), 'created_at' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A') ]; From 1786ae63f31534c8ff4d39e6a9b447b515cf6874 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Tue, 26 Mar 2024 03:50:06 +0800 Subject: [PATCH 157/434] Laravel Vapor - Created new resource files for Vue Polling Component --- .../V2/DeleteBulkInvoiceFilesV2CommandJob.php | 6 +- .../Commands/V2/DeleteOrderV2CommandJob.php | 2 +- ...erateEmailVerificationAttemptProcessor.php | 2 +- .../Processors/ListBookingsJobProcessor.php | 4 +- .../Processors/ListDocumentsJobProcessor.php | 4 +- .../ListTransactionsJobProcessor.php | 6 +- app/Http/Resources/ListBookingJobResource.php | 81 ------------------- app/Http/Resources/V2/BookingV2Resource.php | 34 ++++---- app/Http/Resources/V2/CompanyV2Resource.php | 20 ++--- app/Http/Resources/V2/DocumentV2Resource.php | 28 +++++++ app/Http/Resources/V2/FileV2Resource.php | 23 ++++++ .../Resources/V2/ListBookingJobResource.php | 76 +++++++++++++++++ .../{ => V2}/ListDocumentJobResource.php | 13 +-- .../{ => V2}/ListTransactionJobResource.php | 39 ++++++--- .../Resources/V2/TransactionV2Resource.php | 72 +++++++++++++++++ config/perfexcrm.php | 2 +- 16 files changed, 271 insertions(+), 141 deletions(-) delete mode 100644 app/Http/Resources/ListBookingJobResource.php create mode 100644 app/Http/Resources/V2/DocumentV2Resource.php create mode 100644 app/Http/Resources/V2/FileV2Resource.php create mode 100644 app/Http/Resources/V2/ListBookingJobResource.php rename app/Http/Resources/{ => V2}/ListDocumentJobResource.php (68%) rename app/Http/Resources/{ => V2}/ListTransactionJobResource.php (50%) create mode 100644 app/Http/Resources/V2/TransactionV2Resource.php diff --git a/app/Classes/Jobs/Commands/V2/DeleteBulkInvoiceFilesV2CommandJob.php b/app/Classes/Jobs/Commands/V2/DeleteBulkInvoiceFilesV2CommandJob.php index 3b6815d5..89733472 100644 --- a/app/Classes/Jobs/Commands/V2/DeleteBulkInvoiceFilesV2CommandJob.php +++ b/app/Classes/Jobs/Commands/V2/DeleteBulkInvoiceFilesV2CommandJob.php @@ -23,15 +23,15 @@ class DeleteBulkInvoiceFilesV2CommandJob implements ShouldQueue $start = new Carbon(); $directories = [ - storage_path('app/bulk_invoice'), - storage_path('app/bulk_whiteform'), + storage_path('app/bulk_invoice'), //cief todo: should map to the equivalent in AWS S3 bucket + storage_path('app/bulk_whiteform'), //cief todo: should map to the equivalent in AWS S3 bucket ]; foreach ($directories as $directory) { $start = new Carbon(); Log::info(Carbon::now() . ' Start cleaning - ' . $directory); - if (File::isDirectory($directory)) { + if (File::isDirectory($directory)) { //cief todo: should map to the equivalent in AWS S3 bucket File::cleanDirectory($directory); Log::info('All files have been deleted.'); } else { diff --git a/app/Classes/Jobs/Commands/V2/DeleteOrderV2CommandJob.php b/app/Classes/Jobs/Commands/V2/DeleteOrderV2CommandJob.php index a5489eec..256ed7b8 100644 --- a/app/Classes/Jobs/Commands/V2/DeleteOrderV2CommandJob.php +++ b/app/Classes/Jobs/Commands/V2/DeleteOrderV2CommandJob.php @@ -74,7 +74,7 @@ class DeleteOrderV2CommandJob implements ShouldQueue Log::info(Carbon::now() . ' : ' . $text); - $filePath = storage_path('logs/delete-orders.log'); + $filePath = storage_path('logs/delete-orders.log'); //cief todo: should map to the equivalent in AWS S3 bucket $textToAppend = Carbon::now()->format('[Y-m-d H:i:s]') . ' ' . $text . PHP_EOL; file_put_contents($filePath, $textToAppend, FILE_APPEND); } diff --git a/app/Classes/Modules/Accounts/Processors/GenerateEmailVerificationAttemptProcessor.php b/app/Classes/Modules/Accounts/Processors/GenerateEmailVerificationAttemptProcessor.php index 7c4b35a7..b07b0cc9 100644 --- a/app/Classes/Modules/Accounts/Processors/GenerateEmailVerificationAttemptProcessor.php +++ b/app/Classes/Modules/Accounts/Processors/GenerateEmailVerificationAttemptProcessor.php @@ -50,7 +50,7 @@ class GenerateEmailVerificationAttemptProcessor $attempt = $this->generatesEmailVerificationAttempt->execute($user); - // $this->emailVerificationAttemptExpiration::dispatch($attempt)->delay(now()->addHours(48)); //cief todo: changed to schedule task + // $this->emailVerificationAttemptExpiration::dispatch($attempt)->delay(now()->addHours(48)); //cief todo: changed to schedule task (DONE) $this->sendUserVerificationEmail::dispatch($user, $attempt); diff --git a/app/Classes/Modules/Bookings/Processors/ListBookingsJobProcessor.php b/app/Classes/Modules/Bookings/Processors/ListBookingsJobProcessor.php index 2a09eb12..672c6846 100644 --- a/app/Classes/Modules/Bookings/Processors/ListBookingsJobProcessor.php +++ b/app/Classes/Modules/Bookings/Processors/ListBookingsJobProcessor.php @@ -6,7 +6,7 @@ use App\Classes\Modules\Bookings\Services\ListsBookings; use App\Classes\Modules\Jobs\Processors\UpdateJobResultProcessor; use App\Classes\General\Helper; use App\Classes\Modules\Jobs\DataTransferObjects\ListGenericJobObject; -use App\Http\Resources\ListBookingJobResource; +use App\Http\Resources\V2\ListBookingJobResource; class ListBookingsJobProcessor { @@ -37,7 +37,7 @@ class ListBookingsJobProcessor public function execute(ListGenericJobObject $listGenericJobObject) { $query = $this->listsBookings->execute($this->listsBookings->deserializeFilters($listGenericJobObject->getPayload()['filters']), ['page' => $listGenericJobObject->getPayload()['page']]); - foreach ($query->items() as &$item) { + foreach ($query->items() as $item) { $item['userInfo'] = $listGenericJobObject->getUserInfo(); } $resultCurrent = Helper::collectionResponse(ListBookingJobResource::collection($query)); diff --git a/app/Classes/Modules/Documents/Processors/ListDocumentsJobProcessor.php b/app/Classes/Modules/Documents/Processors/ListDocumentsJobProcessor.php index 70777f0c..f7090d31 100644 --- a/app/Classes/Modules/Documents/Processors/ListDocumentsJobProcessor.php +++ b/app/Classes/Modules/Documents/Processors/ListDocumentsJobProcessor.php @@ -6,7 +6,7 @@ use App\Classes\Modules\Documents\Services\ListsDocuments; use App\Classes\Modules\Jobs\Processors\UpdateJobResultProcessor; use App\Classes\General\Helper; use App\Classes\Modules\Jobs\DataTransferObjects\ListGenericJobObject; -use App\Http\Resources\ListDocumentJobResource; +use App\Http\Resources\V2\ListDocumentJobResource; class ListDocumentsJobProcessor { @@ -37,7 +37,7 @@ class ListDocumentsJobProcessor public function execute(ListGenericJobObject $listGenericJobObject) { $query = $this->listsDocuments->execute($this->listsDocuments->deserializeFilters($listGenericJobObject->getPayload()['filters']), ['page' => $listGenericJobObject->getPayload()['page']]); - foreach ($query->items() as &$item) { + foreach ($query->items() as $item) { $item['userInfo'] = $listGenericJobObject->getUserInfo(); } $resultCurrent = Helper::collectionResponse(ListDocumentJobResource::collection($query)); diff --git a/app/Classes/Modules/Transactions/Processors/ListTransactionsJobProcessor.php b/app/Classes/Modules/Transactions/Processors/ListTransactionsJobProcessor.php index 475d4715..9d325abc 100644 --- a/app/Classes/Modules/Transactions/Processors/ListTransactionsJobProcessor.php +++ b/app/Classes/Modules/Transactions/Processors/ListTransactionsJobProcessor.php @@ -6,7 +6,7 @@ use App\Classes\Modules\Transactions\Services\ListsTransactions; use App\Classes\Modules\Jobs\Processors\UpdateJobResultProcessor; use App\Classes\General\Helper; use App\Classes\Modules\Jobs\DataTransferObjects\ListGenericJobObject; -use App\Http\Resources\ListTransactionJobResource; +use App\Http\Resources\V2\ListTransactionJobResource; class ListTransactionsJobProcessor { @@ -37,7 +37,9 @@ class ListTransactionsJobProcessor public function execute(ListGenericJobObject $listGenericJobObject) { $query = $this->listsTransactions->execute($this->listsTransactions->deserializeFilters($listGenericJobObject->getPayload()['filters']), ['page' => $listGenericJobObject->getPayload()['page']]); - + foreach ($query->items() as $item) { + $item['userInfo'] = $listGenericJobObject->getUserInfo(); + } $resultCurrent = Helper::collectionResponse(ListTransactionJobResource::collection($query)); $this->updateJobResultProcessor->execute($listGenericJobObject, $resultCurrent); } diff --git a/app/Http/Resources/ListBookingJobResource.php b/app/Http/Resources/ListBookingJobResource.php deleted file mode 100644 index 06f8c38d..00000000 --- a/app/Http/Resources/ListBookingJobResource.php +++ /dev/null @@ -1,81 +0,0 @@ -userInfo = $userInfo ?? ($resource->userInfo ?? null); - } - - /** - * Transform the resource into an array. - * - * @param \Illuminate\Http\Request $request - * @return array - * @throws \Illuminate\Contracts\Container\BindingResolutionException - */ - public function toArray($request) - { - return [ - 'id' => $this->id, - 'company' => new CompanyResource($this->company, $this->userInfo), - 'bank' => new BankResource($this->bank), - 'service' => new ServiceTypeResource($this->service), - 'marking' => $this->marking, - 'amount' => $this->fix_amount, - 'floating_amount' => floatval((App()->make(CalculatesBookingFloatingAmount::class))->execute($this->resource, $this->fix_currency_id)), - 'paid_amount' => floatval((App()->make(CalculatesBookingPayableAmount::class))->execute($this->resource, $this->fix_currency_id)) - floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)), - 'outstanding_amount' => floatval((App()->make(CalculatesBookingOutstanding::class))->execute($this->resource)) - floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)), - 'fixed_currency' => new CurrencyResource($this->fixedCurrency), - '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()), - '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()), - ], - 'status' => $this->status, - 'created_at' => Carbon::parse($this->created_at)->format('d-m-Y'), - 'created_at_with_time' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A'), - $this->mergeWhen($this->relationLoaded('transactions'), [ - 'purchase_order' => new TransactionResource($this->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first()), - 'payment_attempts' => TransactionResource::collection( - $this->transactions() - ->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION) - ->whereDate('expires_on', '>=', Carbon::now()) - ->get() - ), - 'expired_payment_attempts' => TransactionResource::collection($this->transactions()->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION)->whereDate('expires_on', '>=', Carbon::now())->where('expires_on', '>', Carbon::now()->toTimeString())->get()), - 'payment_history' => TransactionResource::collection($this->transactions()->where(function($query){ - $query->where(function($query){ - $query->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::COMPLETED, ApprovalStatus::REJECTED]); - })->orWhere(function($query){ - $query->where(function($query){ - $query->where('type', TransactionType::REFUND)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::REJECTED, ApprovalStatus::COMPLETED]); - })->orWhere(function($query){ - $query->where('type', TransactionType::CREDIT_NOTE)->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); - }); - }); - })->latest()->get()) - ]) - ]; - } -} diff --git a/app/Http/Resources/V2/BookingV2Resource.php b/app/Http/Resources/V2/BookingV2Resource.php index ee17181e..a41d7e35 100644 --- a/app/Http/Resources/V2/BookingV2Resource.php +++ b/app/Http/Resources/V2/BookingV2Resource.php @@ -12,17 +12,10 @@ use App\Classes\ValueObjects\Constants\DocumentType; use Carbon\Carbon; use Illuminate\Http\Resources\Json\JsonResource; use App\Http\Resources as V1; +use App\Http\Resources\V2 as V2; class BookingV2Resource extends JsonResource { - private $userInfo; - - public function __construct($resource, $userInfo = null) - { - parent::__construct($resource); - $this->userInfo = $userInfo ?? ($resource->userInfo ?? null); - } - /** * Transform the resource into an array. * @@ -32,9 +25,12 @@ class BookingV2Resource extends JsonResource */ public function toArray($request) { + if($this->userInfo){ + $this->company->userInfo = $this->userInfo; + } return [ 'id' => $this->id, - 'company' => new CompanyV2Resource($this->company, $this->userInfo), + 'company' => new V2\CompanyV2Resource($this->company), 'bank' => new V1\BankResource($this->bank), 'service' => new V1\ServiceTypeResource($this->service), 'marking' => $this->marking, @@ -46,26 +42,26 @@ class BookingV2Resource extends JsonResource 'convertible_currency' => new V1\CurrencyResource($this->convertibleCurrency), 'conversion_currency' => new V1\CurrencyResource($this->conversionCurrency), 'documents' => [ - 'purchase_order' => new V1\DocumentResource($this->documents()->where('document_type', DocumentType::PURCHASE_ORDER)->first()), - 'delivery_order' => new V1\DocumentResource($this->documents()->where('document_type', DocumentType::DELIVER_ORDER)->first()), - 'invoice' => new V1\DocumentResource($this->documents()->where('document_type', DocumentType::INVOICE)->first()), - 'supplier_delivery_order' => new V1\DocumentResource($this->documents()->where('document_type', DocumentType::SUPPLIER_DELIVER_ORDER)->first()), - 'proforma_invoice' => new V1\DocumentResource($this->documents()->where('document_type', DocumentType::PROFORMA_INVOICE)->whereNotIn('status', [ApprovalStatus::REJECTED, ApprovalStatus::EXPIRED])->orderByDesc('id')->first()), - 'ecommerce_purchase_order' => new V1\DocumentResource($this->documents()->where('document_type', DocumentType::ECOMMERCE_PURCHASE_ORDER)->first()), + 'purchase_order' => new V2\DocumentV2Resource($this->documents()->where('document_type', DocumentType::PURCHASE_ORDER)->first()), + 'delivery_order' => new V2\DocumentV2Resource($this->documents()->where('document_type', DocumentType::DELIVER_ORDER)->first()), + 'invoice' => new V2\DocumentV2Resource($this->documents()->where('document_type', DocumentType::INVOICE)->first()), + 'supplier_delivery_order' => new V2\DocumentV2Resource($this->documents()->where('document_type', DocumentType::SUPPLIER_DELIVER_ORDER)->first()), + 'proforma_invoice' => new V2\DocumentV2Resource($this->documents()->where('document_type', DocumentType::PROFORMA_INVOICE)->whereNotIn('status', [ApprovalStatus::REJECTED, ApprovalStatus::EXPIRED])->orderByDesc('id')->first()), + 'ecommerce_purchase_order' => new V2\DocumentV2Resource($this->documents()->where('document_type', DocumentType::ECOMMERCE_PURCHASE_ORDER)->first()), ], 'status' => $this->status, 'created_at' => Carbon::parse($this->created_at)->format('d-m-Y'), 'created_at_with_time' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A'), $this->mergeWhen($this->relationLoaded('transactions'), [ - 'purchase_order' => new V1\TransactionResource($this->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first()), - 'payment_attempts' => V1\TransactionResource::collection( + 'purchase_order' => new V2\TransactionV2Resource($this->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first()), + 'payment_attempts' => V2\TransactionV2Resource::collection( $this->transactions() ->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION) ->whereDate('expires_on', '>=', Carbon::now()) ->get() ), - 'expired_payment_attempts' => V1\TransactionResource::collection($this->transactions()->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION)->whereDate('expires_on', '>=', Carbon::now())->where('expires_on', '>', Carbon::now()->toTimeString())->get()), - 'payment_history' => V1\TransactionResource::collection($this->transactions()->where(function($query){ + 'expired_payment_attempts' => V2\TransactionV2Resource::collection($this->transactions()->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION)->whereDate('expires_on', '>=', Carbon::now())->where('expires_on', '>', Carbon::now()->toTimeString())->get()), + 'payment_history' => V2\TransactionV2Resource::collection($this->transactions()->where(function($query){ $query->where(function($query){ $query->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::COMPLETED, ApprovalStatus::REJECTED]); })->orWhere(function($query){ diff --git a/app/Http/Resources/V2/CompanyV2Resource.php b/app/Http/Resources/V2/CompanyV2Resource.php index 64fca7c7..11eff32f 100644 --- a/app/Http/Resources/V2/CompanyV2Resource.php +++ b/app/Http/Resources/V2/CompanyV2Resource.php @@ -20,14 +20,6 @@ use App\Http\Resources as V1; class CompanyV2Resource extends JsonResource { - private $userInfo; - - public function __construct($resource, $userInfo = null) - { - parent::__construct($resource); - $this->userInfo = $userInfo; - } - /** * Transform the resource into an array. * @@ -47,12 +39,12 @@ class CompanyV2Resource extends JsonResource $userInfoEmail = $this->userInfo && isset($this->userInfo->email) ? $this->userInfo->email : null; $userInfoType = $this->userInfo && isset($this->userInfo->type) ? $this->userInfo->type : null; - if(!$userInfoEmail && Auth::user()){ - $userInfoEmail = Auth::user()->email; - } - if(!$userInfoType && Auth::user()){ - $userInfoType = Auth::user()->type; - } + // if(!$userInfoEmail && Auth::user()){ + // $userInfoEmail = Auth::user()->email; + // } + // if(!$userInfoType && Auth::user()){ + // $userInfoType = Auth::user()->type; + // } if(!is_null($userInfoEmail) && !is_null($userInfoType)){ $userResource = new V1\UserResource($userInfoType === RoleTypes::USER ? $this->employees()->where('email', '=', $userInfoEmail)->first() : $this->employees()->orderBy('id', 'DESC')->first()); diff --git a/app/Http/Resources/V2/DocumentV2Resource.php b/app/Http/Resources/V2/DocumentV2Resource.php new file mode 100644 index 00000000..17da64c7 --- /dev/null +++ b/app/Http/Resources/V2/DocumentV2Resource.php @@ -0,0 +1,28 @@ + $this->id, + 'reference' => $this->reference, + 'status' => (int) $this->status, + 'document_type' => $this->document_type, + 'files' => FileV2Resource::collection($this->files), + 'created_at' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A') + ]; + } +} diff --git a/app/Http/Resources/V2/FileV2Resource.php b/app/Http/Resources/V2/FileV2Resource.php new file mode 100644 index 00000000..8e7ac98a --- /dev/null +++ b/app/Http/Resources/V2/FileV2Resource.php @@ -0,0 +1,23 @@ + $this->id, + 'file' => $this->file, + 'type' => (int) $this->file_type, + ]; + } +} diff --git a/app/Http/Resources/V2/ListBookingJobResource.php b/app/Http/Resources/V2/ListBookingJobResource.php new file mode 100644 index 00000000..1d5d47f0 --- /dev/null +++ b/app/Http/Resources/V2/ListBookingJobResource.php @@ -0,0 +1,76 @@ +userInfo){ + $this->company->userInfo = $this->userInfo; + } + return [ + 'id' => $this->id, + 'company' => new CompanyV2Resource($this->company), + 'bank' => new V1\BankResource($this->bank), + 'service' => new V1\ServiceTypeResource($this->service), + 'marking' => $this->marking, + 'amount' => $this->fix_amount, + 'floating_amount' => floatval((App()->make(CalculatesBookingFloatingAmount::class))->execute($this->resource, $this->fix_currency_id)), + 'paid_amount' => floatval((App()->make(CalculatesBookingPayableAmount::class))->execute($this->resource, $this->fix_currency_id)) - floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)), + 'outstanding_amount' => floatval((App()->make(CalculatesBookingOutstanding::class))->execute($this->resource)) - floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)), + 'fixed_currency' => new V1\CurrencyResource($this->fixedCurrency), + 'convertible_currency' => new V1\CurrencyResource($this->convertibleCurrency), + 'conversion_currency' => new V1\CurrencyResource($this->conversionCurrency), + 'documents' => [ + 'purchase_order' => new DocumentV2Resource($this->documents()->where('document_type', DocumentType::PURCHASE_ORDER)->first()), + 'delivery_order' => new DocumentV2Resource($this->documents()->where('document_type', DocumentType::DELIVER_ORDER)->first()), + 'invoice' => new DocumentV2Resource($this->documents()->where('document_type', DocumentType::INVOICE)->first()), + 'supplier_delivery_order' => new DocumentV2Resource($this->documents()->where('document_type', DocumentType::SUPPLIER_DELIVER_ORDER)->first()), + 'proforma_invoice' => new DocumentV2Resource($this->documents()->where('document_type', DocumentType::PROFORMA_INVOICE)->whereNotIn('status', [ApprovalStatus::REJECTED, ApprovalStatus::EXPIRED])->orderByDesc('id')->first()), + 'ecommerce_purchase_order' => new DocumentV2Resource($this->documents()->where('document_type', DocumentType::ECOMMERCE_PURCHASE_ORDER)->first()), + ], + 'status' => $this->status, + 'created_at' => Carbon::parse($this->created_at)->format('d-m-Y'), + 'created_at_with_time' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A'), + // $this->mergeWhen($this->relationLoaded('transactions'), [ + // 'purchase_order' => new V1\TransactionResource($this->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first()), + // 'payment_attempts' => V1\TransactionResource::collection( + // $this->transactions() + // ->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION) + // ->whereDate('expires_on', '>=', Carbon::now()) + // ->get() + // ), + // 'expired_payment_attempts' => V1\TransactionResource::collection($this->transactions()->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION)->whereDate('expires_on', '>=', Carbon::now())->where('expires_on', '>', Carbon::now()->toTimeString())->get()), + // 'payment_history' => V1\TransactionResource::collection($this->transactions()->where(function($query){ + // $query->where(function($query){ + // $query->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::COMPLETED, ApprovalStatus::REJECTED]); + // })->orWhere(function($query){ + // $query->where(function($query){ + // $query->where('type', TransactionType::REFUND)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::REJECTED, ApprovalStatus::COMPLETED]); + // })->orWhere(function($query){ + // $query->where('type', TransactionType::CREDIT_NOTE)->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); + // }); + // }); + // })->latest()->get()) + // ]) + ]; + } +} diff --git a/app/Http/Resources/ListDocumentJobResource.php b/app/Http/Resources/V2/ListDocumentJobResource.php similarity index 68% rename from app/Http/Resources/ListDocumentJobResource.php rename to app/Http/Resources/V2/ListDocumentJobResource.php index edf549ef..cc233aac 100644 --- a/app/Http/Resources/ListDocumentJobResource.php +++ b/app/Http/Resources/V2/ListDocumentJobResource.php @@ -1,12 +1,11 @@ userInfo){ + $this->owner->userInfo = $this->userInfo; + } + return [ 'id' => $this->id, 'reference' => $this->reference, 'status' => (int) $this->status, 'document_type' => $this->document_type, - 'owner' => $this->relationLoaded('owner') ? ($this->owner instanceof Booking ? new BookingV2Resource($this->owner, $this->userInfo) : new CompanyV2Resource($this->owner, $this->userInfo)) : null, - 'files' => FileResource::collection($this->files), + 'owner' => $this->relationLoaded('owner') ? ($this->owner instanceof Booking ? new BookingV2Resource($this->owner) : new CompanyV2Resource($this->owner)) : null, + 'files' => FileV2Resource::collection($this->files), 'created_at' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A') ]; } diff --git a/app/Http/Resources/ListTransactionJobResource.php b/app/Http/Resources/V2/ListTransactionJobResource.php similarity index 50% rename from app/Http/Resources/ListTransactionJobResource.php rename to app/Http/Resources/V2/ListTransactionJobResource.php index 6c4c0ece..df4bbd2d 100644 --- a/app/Http/Resources/ListTransactionJobResource.php +++ b/app/Http/Resources/V2/ListTransactionJobResource.php @@ -1,10 +1,12 @@ type, [TransactionType::BILL, TransactionType::REFUND])? $this->owner->owner : $this->owner; $days = $this->created_at->endOfDay()->addWeekdays($booking->service_id === 3 ? 3 : 1); + $transactionBillQuery = $this->when((int) $this->type === TransactionType::PAYMENT, $this->transactions()->bills()->first()); + $transactionRefundsQuery = $this->when((int) $this->type === TransactionType::PAYMENT, $this->transactions()->refunds()->get()); + + if($this->userInfo){ + $booking->userInfo = $this->userInfo; + if ($transactionBillQuery) { + $transactionBillQuery->userInfo = $this->userInfo; + } + if ($transactionRefundsQuery) { + foreach ($transactionRefundsQuery as $item) { + $item['userInfo'] = $this->userInfo; + } + } + } + $transactionBill = new TransactionV2Resource($transactionBillQuery); + $transactionRefunds = TransactionV2Resource::collection($transactionRefundsQuery); + return [ 'id' => $this->id, - 'booking' => new BookingResource($booking), + 'booking' => new BookingV2Resource($booking), 'type' => (int) $this->type, 'bill_no' => $this->bill_no, 'payment_reference' => $this->payment_reference, 'payment_method' => (float) $this->payment_method, - 'recipient_bank_account' => new BankResource($booking->bank), + 'recipient_bank_account' => new V1\BankResource($booking->bank), 'issuer_name' => $this->issuerCompany->name, 'issuer_id' => $this->issuerCompany->id, 'amount' => (double) $this->amount, 'original_amount' => (double) $this->original_amount, - 'currency' => new CurrencyResource($this->currency), - 'original_currency' => new CurrencyResource($this->original_currency), + 'currency' => new V1\CurrencyResource($this->currency), + 'original_currency' => new V1\CurrencyResource($this->original_currency), 'service_charge' => (double) $this->service_charge, 'tax' => (double) $this->tax, 'currency_rate' => (double) $this->currency_rate, 'status' => (int) $this->status, - 'details' => TransactionDetailResource::collection($this->transactionDetails), - 'documents' => new DocumentResource($this->documents()->first()), - 'transaction_bill' => new TransactionResource($this->when((int) $this->type === TransactionType::PAYMENT, $this->transactions()->bills()->first())), - 'transaction_refunds' => TransactionResource::collection($this->when((int) $this->type === TransactionType::PAYMENT, $this->transactions()->refunds()->get())), + 'details' => V1\TransactionDetailResource::collection($this->transactionDetails), + 'documents' => new DocumentV2Resource($this->documents()->first()), + 'transaction_bill' => $transactionBill, + 'transaction_refunds' => $transactionRefunds, 'expires_on' => Carbon::parse($this->expires_on)->format('d-m-Y h:i:s A'), 'updated_at' => Carbon::parse($this->updated_at)->format('d-m-Y h:i:s A'), 'interval' => [ 'value' => $days->gt(Carbon::now()) ? '+' : '-', 'duration' => $days->diff(Carbon::now())->format('%d'), ], - 'redemption' => new VoucherRedemptionResource($this->voucherRedemption) + 'redemption' => new V1\VoucherRedemptionResource($this->voucherRedemption) ]; } } diff --git a/app/Http/Resources/V2/TransactionV2Resource.php b/app/Http/Resources/V2/TransactionV2Resource.php new file mode 100644 index 00000000..d358e490 --- /dev/null +++ b/app/Http/Resources/V2/TransactionV2Resource.php @@ -0,0 +1,72 @@ +type, [TransactionType::BILL, TransactionType::REFUND])? $this->owner->owner : $this->owner; + $days = $this->created_at->endOfDay()->addWeekdays($booking->service_id === 3 ? 3 : 1); + $transactionBillQuery = $this->when((int) $this->type === TransactionType::PAYMENT, $this->transactions()->bills()->first()); + $transactionRefundsQuery = $this->when((int) $this->type === TransactionType::PAYMENT, $this->transactions()->refunds()->get()); + + if($this->userInfo){ + $booking->userInfo = $this->userInfo; + if ($transactionBillQuery) { + $transactionBillQuery->userInfo = $this->userInfo; + } + if ($transactionRefundsQuery) { + foreach ($transactionRefundsQuery as $item) { + $item['userInfo'] = $this->userInfo; + } + } + } + $transactionBill = new TransactionV2Resource($transactionBillQuery); + $transactionRefunds = TransactionV2Resource::collection($transactionRefundsQuery); + return [ + 'id' => $this->id, + 'booking' => new BookingV2Resource($booking), + 'type' => (int) $this->type, + 'bill_no' => $this->bill_no, + 'payment_reference' => $this->payment_reference, + 'payment_method' => (float) $this->payment_method, + 'recipient_bank_account' => new V1\BankResource($booking->bank), + 'issuer_name' => $this->issuerCompany->name, + 'issuer_id' => $this->issuerCompany->id, + 'amount' => (double) $this->amount, + 'original_amount' => (double) $this->original_amount, + 'currency' => new V1\CurrencyResource($this->currency), + 'original_currency' => new V1\CurrencyResource($this->original_currency), + 'service_charge' => (double) $this->service_charge, + 'tax' => (double) $this->tax, + 'currency_rate' => (double) $this->currency_rate, + 'status' => (int) $this->status, + 'details' => V1\TransactionDetailResource::collection($this->transactionDetails), + 'documents' => new DocumentV2Resource($this->documents()->first()), + 'transaction_bill' => $transactionBill, + 'transaction_refunds' => $transactionRefunds, + 'refunded_amount' => $this->booking ? floatval((App()->make(CalculatesBookingRefundAmount::class))->calculateRefundAmount($this->resource, $this->booking->fix_currency_id)) : null, + 'expires_on' => Carbon::parse($this->expires_on)->format('d-m-Y h:i:s A'), + 'updated_at' => Carbon::parse($this->updated_at)->format('d-m-Y h:i:s A'), + 'created_at' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A'), + 'interval' => [ + 'value' => $days->gt(Carbon::now()) ? '+' : '-', + 'duration' => $days->diff(Carbon::now())->format('%d'), + ], + 'redemption' => new V1\VoucherRedemptionResource($this->voucherRedemption) + ]; + } +} diff --git a/config/perfexcrm.php b/config/perfexcrm.php index 7644a489..848c833e 100644 --- a/config/perfexcrm.php +++ b/config/perfexcrm.php @@ -1,7 +1,7 @@ env('PERFEXCRM_BASE_URL', 'http://192.168.1.101:8084'), //cief todo: Update crm api domain here + 'base_url' => env('PERFEXCRM_BASE_URL', 'http://192.168.1.101:8084'), //cief todo: Environment variables 'api_key' => env('PERFEXCRM_API_KEY', 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiZXhjaGFuZ2Utc2hpcHBpbmciLCJuYW1lIjoiRXhjaGFuZ2UgYW5kIFNoaXBwaW5nIFBvcnRhbCIsIkFQSV9USU1FIjoxNjc1MDg2Mzc4fQ.SGAHWl5stcxQwp55TBGeMRVTdlLeWQIbsvJh5glyVvs'), 'is_enabled' => env('PERFEXCRM_IS_ENABLED', 'true'), ]; From 3af3c95032ba9592d62d7085800c8840719c30aa Mon Sep 17 00:00:00 2001 From: edmondlang Date: Wed, 27 Mar 2024 01:09:55 +0800 Subject: [PATCH 158/434] show white form transactions in date range --- routes/web.php | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/routes/web.php b/routes/web.php index b90ef72e..d6798271 100644 --- a/routes/web.php +++ b/routes/web.php @@ -879,3 +879,61 @@ Route::get('/invoice/{marking}/{started_at}/{ended_at}/fix', function($marking, } ); })->name('invoice.fix.byCustomerMarking'); + + +Route::get('/show-white-form-transactions-in-date-range/{from_date}/{to_date}', function ($from_date, $to_date) { + $approvedTransactions = Transaction::where('type', TransactionType::PAYMENT)->where('status', ApprovalStatus::APPROVED)->where('owner_type', '!=', Wallet::class)->get(); + + echo '

Approved Payments

'; + echo '
Refunded Original AmountRemarkServiceLast Updated AtBank TypeBank Holder Name
'.($index + 1).'.'.$payment->updated_at->format('d-M-y').''.$payment->original_currency->short_code.''.number_format($original_refunds, 5, '.', '').''.$remark.''.$booking->service->name.''.$payment->updated_at->diffForHumans().''.$bankType.'
'; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + + foreach ($approvedTransactions as $approvedTransaction) { + echo ''; + echo ''; + echo ''; + echo ''; + } + + echo ''; + echo '
BookingPayment Date
' . $approvedTransaction->owner->marking . '' . $approvedTransaction->created_at . '
'; + + $startDate = Carbon::createFromFormat('d-m-Y', $from_date)->startOfDay(); + $endDate = Carbon::createFromFormat('d-m-Y', $to_date)->endOfDay(); + + $approvalSatatusArray = ApprovalStatus::APPROVAL_STATUS_ID; + + echo '

Bills in the date range

'; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + + + $datas = Transaction::where('type', TransactionType::BILL)->whereBetween('created_at', [$startDate, $endDate])->get(); + + foreach ($datas as $data) { + echo ''; + $payment = $data->owner; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + } + + echo ''; + echo '
StatusBills Created AtBookingPayment Date
' . $approvalSatatusArray[$data['status']] . '' . $data->created_at . '' . $data->owner->owner->marking . '' . $payment->created_at . '
'; +}); From 937610272c3a8bf84b61227ac236acdc3cfb4d81 Mon Sep 17 00:00:00 2001 From: Omair Saleh Date: Wed, 27 Mar 2024 09:42:24 +0800 Subject: [PATCH 159/434] tidy up whiteform report --- routes/web.php | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/routes/web.php b/routes/web.php index d6798271..06e0dc67 100644 --- a/routes/web.php +++ b/routes/web.php @@ -882,14 +882,17 @@ Route::get('/invoice/{marking}/{started_at}/{ended_at}/fix', function($marking, Route::get('/show-white-form-transactions-in-date-range/{from_date}/{to_date}', function ($from_date, $to_date) { - $approvedTransactions = Transaction::where('type', TransactionType::PAYMENT)->where('status', ApprovalStatus::APPROVED)->where('owner_type', '!=', Wallet::class)->get(); - echo '

Approved Payments

'; + $approvedTransactions = Transaction::where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED])->where('owner_type', '!=', Wallet::class)->orderBy('status')->get(); + + echo '

Pending Orders Payments

'; echo ''; echo ''; echo ''; echo ''; + echo ''; echo ''; + echo ''; echo ''; echo ''; echo ''; @@ -897,7 +900,9 @@ Route::get('/show-white-form-transactions-in-date-range/{from_date}/{to_date}', foreach ($approvedTransactions as $approvedTransaction) { echo ''; echo ''; + echo ''; echo ''; + echo ''; echo ''; } @@ -907,30 +912,34 @@ Route::get('/show-white-form-transactions-in-date-range/{from_date}/{to_date}', $startDate = Carbon::createFromFormat('d-m-Y', $from_date)->startOfDay(); $endDate = Carbon::createFromFormat('d-m-Y', $to_date)->endOfDay(); - $approvalSatatusArray = ApprovalStatus::APPROVAL_STATUS_ID; echo '

Bills in the date range

'; echo '
BookingAmountPayment DateStatus
' . $approvedTransaction->owner->marking . '' . $approvedTransaction->amount . '' . $approvedTransaction->created_at . '' . ApprovalStatus::APPROVAL_STATUS_ID[$approvedTransaction->status] . '
'; echo ''; echo ''; - echo ''; - echo ''; echo ''; - echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; echo ''; echo ''; echo ''; - $datas = Transaction::where('type', TransactionType::BILL)->whereBetween('created_at', [$startDate, $endDate])->get(); + $bills = Transaction::where('type', TransactionType::BILL)->whereBetween('created_at', [$startDate, $endDate])->get(); - foreach ($datas as $data) { + foreach ($bills as $bill) { echo ''; - $payment = $data->owner; - echo ''; - echo ''; - echo ''; + $payment = $bill->owner; + $po = $payment->owner->transaction()->where('type', TransactionType::PURCHASE_ORDER)->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED])->first(); + echo ''; echo ''; + echo ''; + echo ''; + echo ''; + echo ''; echo ''; } From 9a6e41ff3b17553aa838acf65cba7c57946c8d35 Mon Sep 17 00:00:00 2001 From: Omair Saleh Date: Wed, 27 Mar 2024 09:47:42 +0800 Subject: [PATCH 160/434] tidy up whiteform report --- routes/web.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/routes/web.php b/routes/web.php index 06e0dc67..246cb94b 100644 --- a/routes/web.php +++ b/routes/web.php @@ -900,7 +900,7 @@ Route::get('/show-white-form-transactions-in-date-range/{from_date}/{to_date}', foreach ($approvedTransactions as $approvedTransaction) { echo ''; echo ''; - echo ''; + echo ''; echo ''; echo ''; echo ''; @@ -918,8 +918,10 @@ Route::get('/show-white-form-transactions-in-date-range/{from_date}/{to_date}', echo ''; echo ''; echo ''; + echo ''; echo ''; echo ''; + echo ''; echo ''; echo ''; echo ''; @@ -933,10 +935,11 @@ Route::get('/show-white-form-transactions-in-date-range/{from_date}/{to_date}', foreach ($bills as $bill) { echo ''; $payment = $bill->owner; - $po = $payment->owner->transaction()->where('type', TransactionType::PURCHASE_ORDER)->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED])->first(); + $po = $payment->owner->transactions()->where('type', TransactionType::PURCHASE_ORDER)->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED])->first(); echo ''; echo ''; echo ''; + echo ''; echo ''; echo ''; echo ''; From baa8551b66aff21e8b3e4204ffdbaa255f66b59c Mon Sep 17 00:00:00 2001 From: Omair Saleh Date: Wed, 27 Mar 2024 09:54:58 +0800 Subject: [PATCH 161/434] tidy up whiteform report --- routes/web.php | 1 + 1 file changed, 1 insertion(+) diff --git a/routes/web.php b/routes/web.php index 246cb94b..ab187f16 100644 --- a/routes/web.php +++ b/routes/web.php @@ -936,6 +936,7 @@ Route::get('/show-white-form-transactions-in-date-range/{from_date}/{to_date}', echo ''; $payment = $bill->owner; $po = $payment->owner->transactions()->where('type', TransactionType::PURCHASE_ORDER)->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED])->first(); + var_dump($po); echo ''; echo ''; echo ''; From eb857937983887ad7ecc65c41137e863fe8372dc Mon Sep 17 00:00:00 2001 From: Omair Saleh Date: Wed, 27 Mar 2024 10:02:25 +0800 Subject: [PATCH 162/434] tidy up whiteform report --- routes/web.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/routes/web.php b/routes/web.php index ab187f16..d899f657 100644 --- a/routes/web.php +++ b/routes/web.php @@ -936,13 +936,12 @@ Route::get('/show-white-form-transactions-in-date-range/{from_date}/{to_date}', echo ''; $payment = $bill->owner; $po = $payment->owner->transactions()->where('type', TransactionType::PURCHASE_ORDER)->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED])->first(); - var_dump($po); echo ''; echo ''; echo ''; echo ''; echo ''; - echo ''; +// echo ''; echo ''; echo ''; } From b9765fbcf7e5b60652927a70d67b101236040391 Mon Sep 17 00:00:00 2001 From: Omair Saleh Date: Wed, 27 Mar 2024 10:03:26 +0800 Subject: [PATCH 163/434] tidy up whiteform report --- routes/web.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/routes/web.php b/routes/web.php index d899f657..6f4d12e7 100644 --- a/routes/web.php +++ b/routes/web.php @@ -941,8 +941,8 @@ Route::get('/show-white-form-transactions-in-date-range/{from_date}/{to_date}', echo ''; echo ''; echo ''; -// echo ''; - echo ''; + echo ''; + echo ''; echo ''; } From bb1cb6d44e4300ee253a28f486738d95a58cb0c1 Mon Sep 17 00:00:00 2001 From: Omair Saleh Date: Wed, 27 Mar 2024 10:11:02 +0800 Subject: [PATCH 164/434] tidy up whiteform report --- routes/web.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/routes/web.php b/routes/web.php index 6f4d12e7..1143c48c 100644 --- a/routes/web.php +++ b/routes/web.php @@ -901,7 +901,7 @@ Route::get('/show-white-form-transactions-in-date-range/{from_date}/{to_date}', echo ''; echo ''; echo ''; - echo ''; + echo ''; echo ''; echo ''; } @@ -937,12 +937,13 @@ Route::get('/show-white-form-transactions-in-date-range/{from_date}/{to_date}', $payment = $bill->owner; $po = $payment->owner->transactions()->where('type', TransactionType::PURCHASE_ORDER)->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED])->first(); echo ''; - echo ''; - echo ''; + echo ''; + echo ''; + echo ''; echo ''; - echo ''; - echo ''; - echo ''; + echo ''; + echo ''; + echo ''; echo ''; } From dc61f23fa88a9df088d000f973cf8fbcc8c2618d Mon Sep 17 00:00:00 2001 From: Omair Saleh Date: Mon, 1 Apr 2024 12:59:30 +0800 Subject: [PATCH 165/434] include pending verification status to expirying payment function --- .../ControllersLogic/ExpireBookingPaymentControllerLogic.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Classes/Modules/Bookings/ControllersLogic/ExpireBookingPaymentControllerLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/ExpireBookingPaymentControllerLogic.php index 8ee2bbfa..1b0a9ebb 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/ExpireBookingPaymentControllerLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/ExpireBookingPaymentControllerLogic.php @@ -45,7 +45,7 @@ class ExpireBookingPaymentControllerLogic extends AbstractControllerLogic $booking = $this->fetchesBooking->execute(['id' => $request->route('id')]); $payment = $booking->transactions() - ->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]) + ->payments()->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]) ->first(); $payment->status = ApprovalStatus::EXPIRED; From 02d28f8fba43548b9e1c00865981d751cd8cdc54 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Mon, 8 Apr 2024 21:17:37 +0800 Subject: [PATCH 166/434] fix invoice amount not tally when voucher is apply for booking --- .../CalculatesBookingCurrencyAverageRate.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/app/Classes/Modules/Bookings/Services/CalculatesBookingCurrencyAverageRate.php b/app/Classes/Modules/Bookings/Services/CalculatesBookingCurrencyAverageRate.php index da3fe0b4..9cb7717e 100644 --- a/app/Classes/Modules/Bookings/Services/CalculatesBookingCurrencyAverageRate.php +++ b/app/Classes/Modules/Bookings/Services/CalculatesBookingCurrencyAverageRate.php @@ -24,10 +24,22 @@ class CalculatesBookingCurrencyAverageRate public function execute(Booking $booking, $type){ + $transaction = $booking->transactions() + ->where('type', TransactionType::PAYMENT) + ->latest()->get()[0]; + + $voucherRedemption = $transaction->voucherRedemption; + + $discount = 0; + + if ($voucherRedemption) { + $discount = $voucherRedemption->value; + } + 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; + return $this->calculatesBookingPayableAmount->execute($booking, $booking->fix_currency_id) / ($totalPayment + $discount); } else if ($type == TransactionType::BILL) { From aeb0be11bf935becee6301f215750eaa3fdd5387 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Tue, 9 Apr 2024 00:20:19 +0800 Subject: [PATCH 167/434] remove - in the invoice discount section, amount is already in negative --- resources/views/pages/pdfs/purchase_order_table.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/pages/pdfs/purchase_order_table.blade.php b/resources/views/pages/pdfs/purchase_order_table.blade.php index cc47100e..5862ac69 100644 --- a/resources/views/pages/pdfs/purchase_order_table.blade.php +++ b/resources/views/pages/pdfs/purchase_order_table.blade.php @@ -60,7 +60,7 @@ - + @endif From 69e9328e748673128839a993f019670a0145305e Mon Sep 17 00:00:00 2001 From: edmondlang Date: Tue, 16 Apr 2024 22:34:41 +0800 Subject: [PATCH 168/434] fix bug cant approve the refund because booking amount cant be updated, error - Booking Amount cannot be less than xxxxx --- .../Bookings/ControllersLogic/UpdateBookingAmountLogic.php | 2 +- .../ControllersLogic/UpdateRefundTransactionStatusLogic.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingAmountLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingAmountLogic.php index fabdd058..e40a947d 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingAmountLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingAmountLogic.php @@ -81,7 +81,7 @@ class UpdateBookingAmountLogic extends AbstractControllerLogic $minimum_amount = $booking->fix_amount - $this->calculatesBookingOutstanding->execute($booking); - if ((float)$input_amount < $minimum_amount) { + if (((float)$input_amount + 0.01) < (float)$minimum_amount) { throw new MalformedRequestException('Booking Amount cannot be less than '. $minimum_amount .'.'); } diff --git a/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php index 615ded20..d2fa5ec6 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php @@ -114,7 +114,7 @@ class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic $this->updatesTransactionStatus->execute($po_transaction, (float) number_format($po_transaction->amount, 2, '.', '') === (float) number_format((float)$booking->fix_amount - $refundAmount, 2, '.', '') ? ApprovalStatus::PENDING_VERIFICATION : ApprovalStatus::PENDING_SUBMISSION); } - $request['fix_amount'] = $paidAmount; + $request['fix_amount'] = $booking->fix_amount - $refundAmount; $request->route()->setParameter('id', $booking->id); $this->updateBookingAmountLogic->execute($request); } From a8c13e9425dae66b93fb459d52019c735ec2cd48 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Mon, 22 Apr 2024 18:25:48 +0800 Subject: [PATCH 169/434] comment DB::commit() to fix the database seeder --- database/seeds/DatabaseSeeder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/database/seeds/DatabaseSeeder.php b/database/seeds/DatabaseSeeder.php index 87d72f71..eb94b74f 100644 --- a/database/seeds/DatabaseSeeder.php +++ b/database/seeds/DatabaseSeeder.php @@ -48,6 +48,6 @@ class DatabaseSeeder extends Seeder $this->call(DummyDataSeeder::class); } - DB::commit(); + // DB::commit(); } } From 332a12008c37e412620cbe2fb17a2a24483be806 Mon Sep 17 00:00:00 2001 From: Dodowingster Date: Wed, 24 Apr 2024 15:18:28 +0800 Subject: [PATCH 170/434] initial commit --- .../ControllersLogic/CreateRemarkLogic.php | 62 ++++++++++++++++ .../ControllersLogic/DeleteRemarkLogic.php | 66 +++++++++++++++++ .../ControllersLogic/FetchRemarkLogic.php | 59 +++++++++++++++ .../ControllersLogic/ListRemarksLogic.php | 59 +++++++++++++++ .../ControllersLogic/UpdateRemarkLogic.php | 71 ++++++++++++++++++ .../DataTransferObjects/RemarkObject.php | 38 ++++++++++ .../Processors/CreateRemarkProcessor.php | 47 ++++++++++++ .../Remarks/Services/CreatesRemark.php | 31 ++++++++ .../Remarks/Services/DeletesRemark.php | 19 +++++ .../Remarks/Services/FetchesRemark.php | 33 +++++++++ .../Modules/Remarks/Services/ListsRemarks.php | 33 +++++++++ .../Remarks/Services/UpdatesRemark.php | 26 +++++++ .../Standards/Rules/CanCreateRemark.php | 57 +++++++++++++++ .../Standards/Rules/CanDeleteRemark.php | 43 +++++++++++ .../Standards/Rules/CanFetchRemark.php | 43 +++++++++++ .../Standards/Rules/CanListRemarks.php | 43 +++++++++++ .../Standards/Rules/CanUpdateRemark.php | 57 +++++++++++++++ .../Standards/Validators/RemarkValidation.php | 41 +++++++++++ .../Remarks/CreateRemarkController.php | 20 +++++ .../Remarks/DeleteRemarkController.php | 20 +++++ .../Remarks/FetchRemarkController.php | 20 +++++ .../Remarks/ListRemarksController.php | 20 +++++ .../Remarks/UpdateRemarkController.php | 20 +++++ app/Http/Resources/RemarkResource.php | 26 +++++++ .../general/elements/RemarkComponent.vue | 32 ++++++++ .../general/elements/RemarkListComponent.vue | 71 ++++++++++++++++++ .../forms/DeleteRemarkFormComponent.vue | 32 ++++++++ .../forms/RemarkCommentFormComponent.vue | 55 ++++++++++++++ .../general/forms/RemarkFormComponent.vue | 73 +++++++++++++++++++ routes/remark.php | 11 +++ 30 files changed, 1228 insertions(+) create mode 100644 app/Classes/Modules/Remarks/ControllersLogic/CreateRemarkLogic.php create mode 100644 app/Classes/Modules/Remarks/ControllersLogic/DeleteRemarkLogic.php create mode 100644 app/Classes/Modules/Remarks/ControllersLogic/FetchRemarkLogic.php create mode 100644 app/Classes/Modules/Remarks/ControllersLogic/ListRemarksLogic.php create mode 100644 app/Classes/Modules/Remarks/ControllersLogic/UpdateRemarkLogic.php create mode 100644 app/Classes/Modules/Remarks/DataTransferObjects/RemarkObject.php create mode 100644 app/Classes/Modules/Remarks/Processors/CreateRemarkProcessor.php create mode 100644 app/Classes/Modules/Remarks/Services/CreatesRemark.php create mode 100644 app/Classes/Modules/Remarks/Services/DeletesRemark.php create mode 100644 app/Classes/Modules/Remarks/Services/FetchesRemark.php create mode 100644 app/Classes/Modules/Remarks/Services/ListsRemarks.php create mode 100644 app/Classes/Modules/Remarks/Services/UpdatesRemark.php create mode 100644 app/Classes/Modules/Remarks/Standards/Rules/CanCreateRemark.php create mode 100644 app/Classes/Modules/Remarks/Standards/Rules/CanDeleteRemark.php create mode 100644 app/Classes/Modules/Remarks/Standards/Rules/CanFetchRemark.php create mode 100644 app/Classes/Modules/Remarks/Standards/Rules/CanListRemarks.php create mode 100644 app/Classes/Modules/Remarks/Standards/Rules/CanUpdateRemark.php create mode 100644 app/Classes/Modules/Remarks/Standards/Validators/RemarkValidation.php create mode 100644 app/Http/Controllers/Remarks/CreateRemarkController.php create mode 100644 app/Http/Controllers/Remarks/DeleteRemarkController.php create mode 100644 app/Http/Controllers/Remarks/FetchRemarkController.php create mode 100644 app/Http/Controllers/Remarks/ListRemarksController.php create mode 100644 app/Http/Controllers/Remarks/UpdateRemarkController.php create mode 100644 app/Http/Resources/RemarkResource.php create mode 100644 resources/assets/vue/components/general/elements/RemarkComponent.vue create mode 100644 resources/assets/vue/components/general/elements/RemarkListComponent.vue create mode 100644 resources/assets/vue/components/general/forms/DeleteRemarkFormComponent.vue create mode 100644 resources/assets/vue/components/general/forms/RemarkCommentFormComponent.vue create mode 100644 resources/assets/vue/components/general/forms/RemarkFormComponent.vue create mode 100644 routes/remark.php diff --git a/app/Classes/Modules/Remarks/ControllersLogic/CreateRemarkLogic.php b/app/Classes/Modules/Remarks/ControllersLogic/CreateRemarkLogic.php new file mode 100644 index 00000000..46d822c5 --- /dev/null +++ b/app/Classes/Modules/Remarks/ControllersLogic/CreateRemarkLogic.php @@ -0,0 +1,62 @@ + 'Created Remark', + 'message' => 'You have successfully created a new Remark' + ]; + } + + /** @var CreateRemarkProcessor */ + private $createRemarkProcessor; + + /** + * CreateRemarkLogic constructor. + * @param CreateRemarkProcessor $createRemarkProcessor + */ + public function __construct(CreateRemarkProcessor $createRemarkProcessor) + { + $this->createRemarkProcessor = $createRemarkProcessor; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\RequestValidationException + */ + public function logic(Request $request) : JsonResponse + { + $classs = '\\App\\Models\\' . Str::studly($request->input('model_type')); + + if (!class_exists($classs)) { + throw new MalformedRequestException('Unable to process this entity'); + } + + $remarkOwner = $classs::find($request->route('id')); + + $remarkObject = new RemarkObject($request->input('content'), auth()->user()->id); + + $remmark = $this->createRemarkProcessor->execute($remarkOwner, $remarkObject); + + return $this->resourceResponse(new RemarkResource($remmark)); + } +} diff --git a/app/Classes/Modules/Remarks/ControllersLogic/DeleteRemarkLogic.php b/app/Classes/Modules/Remarks/ControllersLogic/DeleteRemarkLogic.php new file mode 100644 index 00000000..b593d603 --- /dev/null +++ b/app/Classes/Modules/Remarks/ControllersLogic/DeleteRemarkLogic.php @@ -0,0 +1,66 @@ + 'Deleted Remark', + 'message' => 'You have successfully deleted a Remark' + ]; + } + + + /** @var CanDeleteRemark */ + private $canDeleteRemark; + + /** @var DeletesRemark */ + private $deletesRemark; + + /** @var FetchesRemark */ + private $fetchesRemark; + + /** + * DeleteRemarkControllersLogic constructor. + * @param CanDeleteRemark $canDeleteRemark + * @param DeletesRemark $deletesRemark + * @param FetchesRemark $fetchesRemark + */ + public function __construct(CanDeleteRemark $canDeleteRemark, DeletesRemark $deletesRemark, FetchesRemark $fetchesRemark) + { + $this->canDeleteRemark = $canDeleteRemark; + $this->deletesRemark = $deletesRemark; + $this->fetchesRemark = $fetchesRemark; + } + + + /** + * @param Request $request + * @return JsonResponse + * @throws ErrorException + */ + public function logic(Request $request) : JsonResponse + { + $this->canDeleteRemark->passes(); + + $query = $this->fetchesRemark->execute(['id' => $request->route('id')]); + + $this->deletesRemark->execute($query); + + return $this->response([]); + } + +} diff --git a/app/Classes/Modules/Remarks/ControllersLogic/FetchRemarkLogic.php b/app/Classes/Modules/Remarks/ControllersLogic/FetchRemarkLogic.php new file mode 100644 index 00000000..9c5aa5af --- /dev/null +++ b/app/Classes/Modules/Remarks/ControllersLogic/FetchRemarkLogic.php @@ -0,0 +1,59 @@ + 'Retrieved Remark', + 'message' => 'You have successfully retrieved a Remark' + ]; + } + + /** @var CanFetchRemark */ + private $canFetchRemark; + + /** @var FetchesRemark */ + private $fetchesRemark; + + /** + * FetchRemarkControllersLogic constructor. + * @param CanFetchRemark $canFetchRemark + * @param FetchesRemark $fetchesRemark + */ + public function __construct(CanFetchRemark $canFetchRemark, FetchesRemark $fetchesRemark) + { + $this->canFetchRemark = $canFetchRemark; + $this->fetchesRemark = $fetchesRemark; + } + + + /** + * @param Request $request + * @return JsonResponse + * @throws ErrorException + */ + public function logic(Request $request) : JsonResponse + { + $this->canFetchRemark->passes(); + + $query = $this->fetchesRemark->execute(['id' => $request->route('id')]); + + return $this->resourceResponse(new RemarkResource($query)); + } + +} diff --git a/app/Classes/Modules/Remarks/ControllersLogic/ListRemarksLogic.php b/app/Classes/Modules/Remarks/ControllersLogic/ListRemarksLogic.php new file mode 100644 index 00000000..c70ccee1 --- /dev/null +++ b/app/Classes/Modules/Remarks/ControllersLogic/ListRemarksLogic.php @@ -0,0 +1,59 @@ + 'Retrieved Remarks', + 'message' => 'You have successfully retrieved a list of Remarks' + ]; + } + + /** @var CanListRemarks */ + private $canListRemarks; + + /** @var ListsRemarks */ + private $listsRemarks; + + /** + * ListRemarksLogic constructor. + * @param CanListRemarks $canListRemarks + * @param ListsRemarks $listsRemarks + */ + public function __construct(CanListRemarks $canListRemarks, ListsRemarks $listsRemarks) + { + $this->canListRemarks = $canListRemarks; + $this->listsRemarks = $listsRemarks; + } + + + /** + * @param Request $request + * @return JsonResponse + * @throws ErrorException + */ + public function logic(Request $request) : JsonResponse + { + $this->canListRemarks->passes(); + + $query = $this->listsRemarks->execute($this->listsRemarks->deserializeFilters($request->input('filters'))); + + return $this->collectionResponse(RemarkResource::collection($query)); + } + +} diff --git a/app/Classes/Modules/Remarks/ControllersLogic/UpdateRemarkLogic.php b/app/Classes/Modules/Remarks/ControllersLogic/UpdateRemarkLogic.php new file mode 100644 index 00000000..f120efab --- /dev/null +++ b/app/Classes/Modules/Remarks/ControllersLogic/UpdateRemarkLogic.php @@ -0,0 +1,71 @@ + 'Updated Remark', + 'message' => 'You have successfully updated the Remark' + ]; + } + + /** @var CanUpdateRemark */ + private $canUpdateRemark; + + /** @var UpdatesRemark */ + private $updatesRemark; + + /** @var FetchesRemark */ + private $fetchesRemark; + + /** + * UpdateRemarkLogic constructor. + * @param CanUpdateRemark $canUpdateRemark + * @param UpdatesRemark $updatesRemark + * @param FetchesRemark $fetchesRemark + */ + public function __construct(CanUpdateRemark $canUpdateRemark, UpdatesRemark $updatesRemark, FetchesRemark $fetchesRemark) + { + $this->canUpdateRemark = $canUpdateRemark; + $this->updatesRemark = $updatesRemark; + $this->fetchesRemark = $fetchesRemark; + } + + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\RequestValidationException + */ + public function logic(Request $request) : JsonResponse + { + $object = new RemarkObject($request->input('content'), auth()->user()->id); + + $this->canUpdateRemark->passes($object); + + $query = $this->fetchesRemark->execute(['id' => $request->route('id')]); + + $query = $this->updatesRemark->execute($query, $object); + + return $this->resourceResponse(new RemarkResource($query)); + } + +} diff --git a/app/Classes/Modules/Remarks/DataTransferObjects/RemarkObject.php b/app/Classes/Modules/Remarks/DataTransferObjects/RemarkObject.php new file mode 100644 index 00000000..44a9507f --- /dev/null +++ b/app/Classes/Modules/Remarks/DataTransferObjects/RemarkObject.php @@ -0,0 +1,38 @@ +commenterID = $commenterID; + $this->content = $content; + } + + /** + * @return int + */ + public function getCommenterId(): string + { + return $this->commenterID; + } + + /** + * @return string + */ + public function getContent(): ?string + { + return $this->content; + } + +} diff --git a/app/Classes/Modules/Remarks/Processors/CreateRemarkProcessor.php b/app/Classes/Modules/Remarks/Processors/CreateRemarkProcessor.php new file mode 100644 index 00000000..aadbe502 --- /dev/null +++ b/app/Classes/Modules/Remarks/Processors/CreateRemarkProcessor.php @@ -0,0 +1,47 @@ +createsRemark = $createsRemark; + $this->canCreateRemark = $canCreateRemark; + } + + + /** + * @param Remarkable $remarkable + * @param RemarkObject $object + * @return \Illuminate\Database\Eloquent\Model + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\RequestValidationException + */ + public function execute(Remarkable $remarkable, RemarkObject $object){ + + $this->canCreateRemark->passes($object); + return $this->createsRemark->execute($remarkable, $object); + + } + +} \ No newline at end of file diff --git a/app/Classes/Modules/Remarks/Services/CreatesRemark.php b/app/Classes/Modules/Remarks/Services/CreatesRemark.php new file mode 100644 index 00000000..ac0d57a3 --- /dev/null +++ b/app/Classes/Modules/Remarks/Services/CreatesRemark.php @@ -0,0 +1,31 @@ +commenter_id = $object->getCommenterId(); + $model->content = $object->getContent(); + + return $this->handler($remarkable->remarks(), $model); + + } +} diff --git a/app/Classes/Modules/Remarks/Services/DeletesRemark.php b/app/Classes/Modules/Remarks/Services/DeletesRemark.php new file mode 100644 index 00000000..4c29be9d --- /dev/null +++ b/app/Classes/Modules/Remarks/Services/DeletesRemark.php @@ -0,0 +1,19 @@ +handler($model); + } +} diff --git a/app/Classes/Modules/Remarks/Services/FetchesRemark.php b/app/Classes/Modules/Remarks/Services/FetchesRemark.php new file mode 100644 index 00000000..a3b5c765 --- /dev/null +++ b/app/Classes/Modules/Remarks/Services/FetchesRemark.php @@ -0,0 +1,33 @@ +repository = $repository; + } + + + /** + * @return Builder + */ + public function getRepository(): Builder + { + return $this->repository->newQuery(); + } +} diff --git a/app/Classes/Modules/Remarks/Services/ListsRemarks.php b/app/Classes/Modules/Remarks/Services/ListsRemarks.php new file mode 100644 index 00000000..53479558 --- /dev/null +++ b/app/Classes/Modules/Remarks/Services/ListsRemarks.php @@ -0,0 +1,33 @@ +repository = $repository; + } + + + /** + * @return Builder + */ + function getRepository(): Builder + { + return $this->repository->newQuery(); + } +} diff --git a/app/Classes/Modules/Remarks/Services/UpdatesRemark.php b/app/Classes/Modules/Remarks/Services/UpdatesRemark.php new file mode 100644 index 00000000..4ba9501c --- /dev/null +++ b/app/Classes/Modules/Remarks/Services/UpdatesRemark.php @@ -0,0 +1,26 @@ +commenter_id = $object->getCommenterId(); + $model->content = $object->getContent(); + + return $this->handler($model); + + } +} diff --git a/app/Classes/Modules/Remarks/Standards/Rules/CanCreateRemark.php b/app/Classes/Modules/Remarks/Standards/Rules/CanCreateRemark.php new file mode 100644 index 00000000..a7d2e5b1 --- /dev/null +++ b/app/Classes/Modules/Remarks/Standards/Rules/CanCreateRemark.php @@ -0,0 +1,57 @@ +RemarkValidation = $RemarkValidation; + } + + + /** + * @return bool + */ + protected function authorized($object): bool + { + // TODO Set Authorization rules + return true; + + } + + /** + * @param RemarkObject $object + * @return bool + * @throws \App\Classes\Exceptions\RequestValidationException + */ + protected function validators($object): bool + { + return $this->RemarkValidation->validate($object); + + } + + + /** + * @param RemarkObject $object + * @return bool + */ + protected function criteria($object): bool + { + return true; + } + +} diff --git a/app/Classes/Modules/Remarks/Standards/Rules/CanDeleteRemark.php b/app/Classes/Modules/Remarks/Standards/Rules/CanDeleteRemark.php new file mode 100644 index 00000000..1c61ac9d --- /dev/null +++ b/app/Classes/Modules/Remarks/Standards/Rules/CanDeleteRemark.php @@ -0,0 +1,43 @@ +RemarkValidation = $RemarkValidation; + } + + + /** + * @return bool + */ + protected function authorized($object): bool + { + // TODO Set Authorization rules + return true; + + } + + /** + * @param RemarkObject $object + * @return bool + * @throws \App\Classes\Exceptions\RequestValidationException + */ + protected function validators($object): bool + { + return $this->RemarkValidation->validate($object); + + } + + + /** + * @param RemarkObject $object + * @return bool + */ + protected function criteria($object): bool + { + return true; + } + +} diff --git a/app/Classes/Modules/Remarks/Standards/Validators/RemarkValidation.php b/app/Classes/Modules/Remarks/Standards/Validators/RemarkValidation.php new file mode 100644 index 00000000..b35d3bde --- /dev/null +++ b/app/Classes/Modules/Remarks/Standards/Validators/RemarkValidation.php @@ -0,0 +1,41 @@ + $object->getCommenterId(), + 'content' => $object->getContent(), + ]; + } + + /** + * @return array + */ + protected function rules(): array { + return [ + 'commenter_id' => 'required', + 'content' => 'required', + ]; + } + + /** + * @return array + */ + protected function messages(): array { + return []; + } + +} diff --git a/app/Http/Controllers/Remarks/CreateRemarkController.php b/app/Http/Controllers/Remarks/CreateRemarkController.php new file mode 100644 index 00000000..a66aa8fd --- /dev/null +++ b/app/Http/Controllers/Remarks/CreateRemarkController.php @@ -0,0 +1,20 @@ +execute($request); + } + +} diff --git a/app/Http/Controllers/Remarks/DeleteRemarkController.php b/app/Http/Controllers/Remarks/DeleteRemarkController.php new file mode 100644 index 00000000..8d0163c0 --- /dev/null +++ b/app/Http/Controllers/Remarks/DeleteRemarkController.php @@ -0,0 +1,20 @@ +execute($request); + } + +} diff --git a/app/Http/Controllers/Remarks/FetchRemarkController.php b/app/Http/Controllers/Remarks/FetchRemarkController.php new file mode 100644 index 00000000..ba43be07 --- /dev/null +++ b/app/Http/Controllers/Remarks/FetchRemarkController.php @@ -0,0 +1,20 @@ +execute($request); + } + +} diff --git a/app/Http/Controllers/Remarks/ListRemarksController.php b/app/Http/Controllers/Remarks/ListRemarksController.php new file mode 100644 index 00000000..f76f752e --- /dev/null +++ b/app/Http/Controllers/Remarks/ListRemarksController.php @@ -0,0 +1,20 @@ +execute($request); + } + +} diff --git a/app/Http/Controllers/Remarks/UpdateRemarkController.php b/app/Http/Controllers/Remarks/UpdateRemarkController.php new file mode 100644 index 00000000..ae53f6b7 --- /dev/null +++ b/app/Http/Controllers/Remarks/UpdateRemarkController.php @@ -0,0 +1,20 @@ +execute($request); + } + +} diff --git a/app/Http/Resources/RemarkResource.php b/app/Http/Resources/RemarkResource.php new file mode 100644 index 00000000..24081934 --- /dev/null +++ b/app/Http/Resources/RemarkResource.php @@ -0,0 +1,26 @@ + $this->id, + 'commenter' => new UserResource($this->commenter), + 'owner_id' => $this->owner_id, + 'content' => $this->content, + 'created_at' => $this->created_at->format('d-m-Y H:i'), + 'long_ago' => $this->created_at->diffForHumans() + ]; + } +} diff --git a/resources/assets/vue/components/general/elements/RemarkComponent.vue b/resources/assets/vue/components/general/elements/RemarkComponent.vue new file mode 100644 index 00000000..f2f9bf30 --- /dev/null +++ b/resources/assets/vue/components/general/elements/RemarkComponent.vue @@ -0,0 +1,32 @@ + + diff --git a/resources/assets/vue/components/general/elements/RemarkListComponent.vue b/resources/assets/vue/components/general/elements/RemarkListComponent.vue new file mode 100644 index 00000000..da218ea9 --- /dev/null +++ b/resources/assets/vue/components/general/elements/RemarkListComponent.vue @@ -0,0 +1,71 @@ + + diff --git a/resources/assets/vue/components/general/forms/DeleteRemarkFormComponent.vue b/resources/assets/vue/components/general/forms/DeleteRemarkFormComponent.vue new file mode 100644 index 00000000..4e50d8c4 --- /dev/null +++ b/resources/assets/vue/components/general/forms/DeleteRemarkFormComponent.vue @@ -0,0 +1,32 @@ + + diff --git a/resources/assets/vue/components/general/forms/RemarkCommentFormComponent.vue b/resources/assets/vue/components/general/forms/RemarkCommentFormComponent.vue new file mode 100644 index 00000000..7da26ca8 --- /dev/null +++ b/resources/assets/vue/components/general/forms/RemarkCommentFormComponent.vue @@ -0,0 +1,55 @@ + + diff --git a/resources/assets/vue/components/general/forms/RemarkFormComponent.vue b/resources/assets/vue/components/general/forms/RemarkFormComponent.vue new file mode 100644 index 00000000..73a8575f --- /dev/null +++ b/resources/assets/vue/components/general/forms/RemarkFormComponent.vue @@ -0,0 +1,73 @@ + + diff --git a/routes/remark.php b/routes/remark.php new file mode 100644 index 00000000..91ae4676 --- /dev/null +++ b/routes/remark.php @@ -0,0 +1,11 @@ + 'Remarks', 'as' => 'remark.', 'prefix' => 'remark'], function () { + Route::get('/{id}/show', 'FetchRemarkController@fetch')->name('show'); + Route::get('/list', 'ListRemarksController@list')->name('list'); + Route::post('/{id}/create', 'CreateRemarkController@create')->name('create'); + Route::put('/update/{id}', 'UpdateRemarkController@update')->name('update'); + Route::delete('/delete/{id}', 'DeleteRemarkController@delete')->name('delete'); +}); From 9c4ed9aba294b3ee66352a57e659742e8f93b4c8 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Wed, 24 Apr 2024 17:26:50 +0800 Subject: [PATCH 171/434] Laravel Vapor - Rewrite code to use S3 bucket --- .../BulkDownloadCustomerInvoicesLogic.php | 83 ++++++++++++++----- 1 file changed, 63 insertions(+), 20 deletions(-) diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php index 41a64ecf..89c8c1c4 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php @@ -8,7 +8,7 @@ use ZipArchive; use Illuminate\Http\Request; use Illuminate\Support\Facades\Storage; use App\Classes\Exceptions\MalformedRequestException; -use Illuminate\Support\Facades\File; +use Illuminate\Support\Facades\File; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\DocumentType; use App\Models\Company; @@ -53,33 +53,76 @@ class BulkDownloadCustomerInvoicesLogic ]); } - $zipDirectory = storage_path('app/bulk_invoice'); // Update this with the actual directory path - if (!file_exists($zipDirectory)) { - mkdir($zipDirectory, 0755, true); - } + $filesystemDriver = Storage::getDefaultDriver(); + if($filesystemDriver == 's3'){ + $zip = new ZipArchive(); + $zipDataStr = ''; - $zip_file = "{$zipDirectory}/invoices_{$request->input('startDate')}_to_{$request->input('endDate')}_{$company->reference}.zip"; - - $zip = new ZipArchive(); - if ($zip->open($zip_file, ZipArchive::CREATE | ZipArchive::OVERWRITE)) { foreach ($invoicebookings as $booking) { - $invoice_file = $booking->documents()->where('document_type', DocumentType::INVOICE)->whereNull('deleted_at')->first()->files()->first(); - $zip->addFile(Storage::disk('documents')->path($invoice_file->file->file_info->original->file), 'invoice-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf'); + $invoiceFile = $booking->documents() + ->where('document_type', DocumentType::INVOICE) + ->whereNull('deleted_at') + ->first() + ->files() + ->first(); + + $fileContent = Storage::disk('documents') + ->get($invoiceFile->file->file_info->original->file); + + $zipDataStr .= 'invoice-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf'; + $zipDataStr .= "\n"; // Add a separator + $zipDataStr .= $fileContent; } - $zip->close(); + $zipFileName = "invoices_{$startDate}_to_{$endDate}_{$company->reference}.zip"; - while (ob_get_level()) { - ob_end_clean(); + if ($zip->open($zipFileName, ZipArchive::CREATE | ZipArchive::OVERWRITE)) { + $zip->addFromString($zipFileName, $zipDataStr); + $zip->close(); + + $filePath = 'bulk_invoice/'.$zipFileName; + Storage::put($filePath, file_get_contents($zipFileName), 's3'); + + return response(['src' => Storage::disk('s3')->get($$filePath) ]); + + } else { + return response()->json([ + 'status' => 'Error', + 'message' => 'Failed to create the Zip archive.', + ]); + } + } + else{ + + $zipDirectory = storage_path('app/bulk_invoice'); // Update this with the actual directory path + + if (!file_exists($zipDirectory)) { + mkdir($zipDirectory, 0755, true); } - return response()->download($zip_file); - } else { - return response()->json([ - 'status' => 'Error', - 'message' => 'Failed to create the Zip archive.', - ]); + $zip_file = "{$zipDirectory}/invoices_{$request->input('startDate')}_to_{$request->input('endDate')}_{$company->reference}.zip"; + + $zip = new ZipArchive(); + if ($zip->open($zip_file, ZipArchive::CREATE | ZipArchive::OVERWRITE)) { + foreach ($invoicebookings as $booking) { + $invoice_file = $booking->documents()->where('document_type', DocumentType::INVOICE)->whereNull('deleted_at')->first()->files()->first(); + $zip->addFile(Storage::disk('documents')->path($invoice_file->file->file_info->original->file), 'invoice-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf'); + } + + $zip->close(); + + while (ob_get_level()) { + ob_end_clean(); + } + + return response()->download($zip_file); + } else { + return response()->json([ + 'status' => 'Error', + 'message' => 'Failed to create the Zip archive.', + ]); + } } } catch (\Exception $e) { // Log the exception for debugging From 631282eaf5205ad975bc82dd04e03e985a9d797f Mon Sep 17 00:00:00 2001 From: edmondlang Date: Wed, 24 Apr 2024 18:09:22 +0800 Subject: [PATCH 172/434] add remarks table migration --- .../ValueObjects/Constants/RemarkTypes.php | 13 ++++++ ...2024_04_24_180633_create_remarks_table.php | 41 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 app/Classes/ValueObjects/Constants/RemarkTypes.php create mode 100644 database/migrations/2024_04_24_180633_create_remarks_table.php diff --git a/app/Classes/ValueObjects/Constants/RemarkTypes.php b/app/Classes/ValueObjects/Constants/RemarkTypes.php new file mode 100644 index 00000000..9629e89a --- /dev/null +++ b/app/Classes/ValueObjects/Constants/RemarkTypes.php @@ -0,0 +1,13 @@ +id(); + $table->morphs('owner'); + $table->bigInteger('commenter_id')->unsigned()->index(); + $table->string('content',200); + $table->integer('type')->default(RemarkTypes::INTERNAL); + $table->softDeletes(); + $table->timestamps(); + }); + + Schema::table('remarks', function (Blueprint $table) { + $table->string('owner_type', 191)->change(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('remarks'); + } +} From 9879b16f2ae1fb371f966c59e4063ca32f559033 Mon Sep 17 00:00:00 2001 From: Dodowingster Date: Thu, 25 Apr 2024 10:22:08 +0800 Subject: [PATCH 173/434] feat: remarks and add remarks --- routes/web.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/routes/web.php b/routes/web.php index 355dc7f1..079831aa 100644 --- a/routes/web.php +++ b/routes/web.php @@ -31,6 +31,7 @@ use App\Classes\Modules\Transactions\Processors\CreateInvoiceTransactionWithInvo use App\Classes\Modules\Transactions\Services\DeletesTransaction; use Illuminate\Support\Facades\Log; + /* |-------------------------------------------------------------------------- | Web Routes @@ -968,6 +969,7 @@ Route::get('/invoice/{marking}/{started_at}/{ended_at}/fix', function($marking, ); })->name('invoice.fix.byCustomerMarking'); +require __DIR__.'/remark.php'; Route::get('/show-white-form-transactions-in-date-range/{from_date}/{to_date}', function ($from_date, $to_date) { @@ -981,6 +983,8 @@ Route::get('/show-white-form-transactions-in-date-range/{from_date}/{to_date}', echo ''; echo ''; echo ''; + echo ''; + echo ''; echo ''; echo ''; echo ''; @@ -991,6 +995,13 @@ Route::get('/show-white-form-transactions-in-date-range/{from_date}/{to_date}', echo ''; echo ''; echo ''; + echo ''; + echo ''; echo ''; } From 3383f6b138547b352cf24869f409bccafe68f904 Mon Sep 17 00:00:00 2001 From: Dodowingster Date: Thu, 25 Apr 2024 13:39:40 +0800 Subject: [PATCH 174/434] initial commit --- app/Models/Remark.php | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 app/Models/Remark.php diff --git a/app/Models/Remark.php b/app/Models/Remark.php new file mode 100644 index 00000000..f2de3a5c --- /dev/null +++ b/app/Models/Remark.php @@ -0,0 +1,27 @@ +morphTo(); + } + + /** + * @return BelongsTo + */ + public function commenter(): BelongsTo + { + return $this->BelongsTo(User::class, 'commenter_id', 'id'); + } +} From a9414712f5fc037385709d48d238bcd13d464039 Mon Sep 17 00:00:00 2001 From: Dodowingster Date: Thu, 25 Apr 2024 13:40:04 +0800 Subject: [PATCH 175/434] feat: added remark.php --- routes/api.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/routes/api.php b/routes/api.php index 460bd772..2d52b3ea 100644 --- a/routes/api.php +++ b/routes/api.php @@ -67,6 +67,8 @@ Route::group(['middleware' => 'api', 'prefix' => 'v1', 'as' => 'api.'], function require __DIR__ . '/milestone.php'; + require __DIR__.'/remark.php'; + // require __DIR__ . '/accounting.php'; //cief todo: To check if this is needed require __DIR__ . '/job.php'; From 7fb4ae724c312398044bf41588a10359b4ede364 Mon Sep 17 00:00:00 2001 From: Dodowingster Date: Thu, 25 Apr 2024 13:40:23 +0800 Subject: [PATCH 176/434] refactor: adding remarks --- routes/web.php | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/routes/web.php b/routes/web.php index 079831aa..6a8ce6ca 100644 --- a/routes/web.php +++ b/routes/web.php @@ -2,6 +2,7 @@ use App\Classes\Modules\Transactions\Processors\CreateInvoiceTransactionProcessor; use App\Http\Controllers\Accounting\BankStatementController; +use App\Models\Remark; use Carbon\Carbon; use App\Models\User; use App\Models\Wallet; @@ -969,10 +970,18 @@ Route::get('/invoice/{marking}/{started_at}/{ended_at}/fix', function($marking, ); })->name('invoice.fix.byCustomerMarking'); -require __DIR__.'/remark.php'; +route:: post('/transaction/{id}/create-remark',function ($transactionId) { + $transaction = Transaction::find($transactionId); + $remark = new Remark(); + $remark->content = request('content'); + $remark->transaction_id; + $remark->save(); + return redirect()->back(); +})->name('transaction.create-remark'); Route::get('/show-white-form-transactions-in-date-range/{from_date}/{to_date}', function ($from_date, $to_date) { + $approvedTransactions = Transaction::where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED])->where('owner_type', '!=', Wallet::class)->orderBy('status')->get(); echo '

Pending Orders Payments

'; @@ -997,9 +1006,10 @@ Route::get('/show-white-form-transactions-in-date-range/{from_date}/{to_date}', echo '
'; echo ''; echo ''; echo ''; @@ -1048,4 +1058,6 @@ Route::get('/show-white-form-transactions-in-date-range/{from_date}/{to_date}', echo ''; echo '
StatusBills Created AtBookingPayment DateCustomer payment dateWhite form dateUpload bank slip DatePO submit datePO approve date
' . $approvalSatatusArray[$data['status']] . '' . $data->created_at . '' . $data->owner->owner->marking . '' . $payment->owner->marking . '' . $payment->created_at . '' . $bill->created_at . '' . $bill->status === ApprovalStatus::APPROVED ? $bill->updated_at : 'Pending Upload' . '' . $po ? $po->updated_at : 'Pending Submission' . '' . $po ? ($po->status === ApprovalStatus::APPROVED ? $po->updated_at : '' ) : '' . '
' . $approvedTransaction->owner->marking . '' . $approvedTransaction->amount . '' . round($approvedTransaction->amount, 2) . '' . $approvedTransaction->created_at . '' . ApprovalStatus::APPROVAL_STATUS_ID[$approvedTransaction->status] . '
BookingAmountCustomer payment dateWhite form dateSupplierUpload bank slip DatePO submit datePO approve date
' . $payment->owner->marking . '' . $payment->created_at . '' . $bill->created_at . '' . $bill->issuerCompany->name . '' . $bill->status === ApprovalStatus::APPROVED ? $bill->updated_at : 'Pending Upload' . '' . $po ? $po->updated_at : 'Pending Submission' . '' . $po ? ($po->status === ApprovalStatus::APPROVED ? $po->updated_at : '' ) : '' . '
' . $payment->owner->marking . '' . $payment->created_at . '' . $bill->created_at . '
' . $payment->owner->marking . '' . $payment->created_at . '' . $bill->created_at . '' . $bill->issuerCompany->name . '' . $bill->status === ApprovalStatus::APPROVED ? $bill->updated_at : 'Pending Upload' . '' . $po ? $po->updated_at : 'Pending Submission' . '' . $po ? $po->updated_at : 'Pending Submission' . '' . $po ? ($po->status === ApprovalStatus::APPROVED ? $po->updated_at : '' ) : '' . '
' . $bill->created_at . '' . $bill->issuerCompany->name . '' . $bill->status === ApprovalStatus::APPROVED ? $bill->updated_at : 'Pending Upload' . '' . $po ? $po->updated_at : 'Pending Submission' . '' . $po ? ($po->status === ApprovalStatus::APPROVED ? $po->updated_at : '' ) : '' . '' . ($po ? $po->updated_at : 'Pending Submission') . '' . ($po ? ($po->status === ApprovalStatus::APPROVED ? $po->updated_at : '' ) : '' ). '
' . $approvedTransaction->owner->marking . '' . round($approvedTransaction->amount, 2) . '' . $approvedTransaction->created_at . '' . $approvedTransaction->created_at->format('d-m-Y h:i A') . '' . ApprovalStatus::APPROVAL_STATUS_ID[$approvedTransaction->status] . '
' . $payment->owner->marking . '' . $payment->created_at . '' . $bill->created_at . '' . round($payment->amount, 2) . '' . $payment->created_at->format('d-m-Y h:i A') . '' . $bill->created_at->format('d-m-Y h:i A') . '' . $bill->issuerCompany->name . '' . $bill->status === ApprovalStatus::APPROVED ? $bill->updated_at : 'Pending Upload' . '' . ($po ? $po->updated_at : 'Pending Submission') . '' . ($po ? ($po->status === ApprovalStatus::APPROVED ? $po->updated_at : '' ) : '' ). '' . ($bill->status === ApprovalStatus::APPROVED ? $bill->updated_at->format('d-m-Y h:i A') : 'Pending Upload') . '' . ($po ? $po->updated_at->format('d-m-Y h:i A') : 'Pending Submission') . '' . ($po ? ($po->status === ApprovalStatus::APPROVED ? $po->updated_at->format('d-m-Y h:i A') : '' ) : '' ). '
Voucher ({{ $voucher_redemption->voucher->code }})-{{ number_format($voucherDiscount, 2) }}{{ number_format($voucherDiscount, 2) }}
AmountPayment DateStatusRemarkAdd Remarks
' . round($approvedTransaction->amount, 2) . '' . $approvedTransaction->created_at->format('d-m-Y h:i A') . '' . ApprovalStatus::APPROVAL_STATUS_ID[$approvedTransaction->status] . '' . $approvedTransaction->remarks . '' ; + echo '
'; + echo ''; + echo ''; + echo '
'; + echo '
' . ApprovalStatus::APPROVAL_STATUS_ID[$approvedTransaction->status] . '' . $approvedTransaction->remarks . '' ; - echo '
'; + echo ''; echo ''; echo ''; + echo csrf_field(); echo '
'; echo '
'; + + }); From 30172a6d7ad214a7d3c2a5821ac554f8a929a3e2 Mon Sep 17 00:00:00 2001 From: Dodowingster Date: Thu, 25 Apr 2024 14:20:31 +0800 Subject: [PATCH 177/434] refactor: proper remark database commit --- routes/web.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/routes/web.php b/routes/web.php index 6a8ce6ca..7dd5a3ef 100644 --- a/routes/web.php +++ b/routes/web.php @@ -974,7 +974,7 @@ route:: post('/transaction/{id}/create-remark',function ($transactionId) { $transaction = Transaction::find($transactionId); $remark = new Remark(); $remark->content = request('content'); - $remark->transaction_id; + $remark->id = $transactionId; $remark->save(); return redirect()->back(); })->name('transaction.create-remark'); @@ -1004,7 +1004,12 @@ Route::get('/show-white-form-transactions-in-date-range/{from_date}/{to_date}', echo '' . round($approvedTransaction->amount, 2) . ''; echo '' . $approvedTransaction->created_at->format('d-m-Y h:i A') . ''; echo '' . ApprovalStatus::APPROVAL_STATUS_ID[$approvedTransaction->status] . ''; - echo '' . $approvedTransaction->remarks . ''; + $remark = Remark::where('id', $approvedTransaction->id)->first(); + if ($remark) { + echo '' . $remark->content . ''; + } else { + echo 'No remark found'; + } echo '' ; echo '
'; echo ''; From 29507f51200cef7575b70ff78e6accc5defe17f3 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Thu, 25 Apr 2024 14:50:59 +0800 Subject: [PATCH 178/434] update remark on transactions --- app/Models/Transaction.php | 8 ++++++++ routes/web.php | 22 +++++++++++----------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/app/Models/Transaction.php b/app/Models/Transaction.php index 4161632b..aba5decc 100644 --- a/app/Models/Transaction.php +++ b/app/Models/Transaction.php @@ -259,4 +259,12 @@ class Transaction extends AbstractModel implements Documentable, Transactionable return $this->morphMany(VoucherEntityMapping::class, 'owner'); } + /** + * @return MorphMany + */ + public function remarks(): morphMany + { + return $this->morphMany(Remark::class, 'owner'); + } + } diff --git a/routes/web.php b/routes/web.php index 7dd5a3ef..7dc095f3 100644 --- a/routes/web.php +++ b/routes/web.php @@ -973,15 +973,17 @@ Route::get('/invoice/{marking}/{started_at}/{ended_at}/fix', function($marking, route:: post('/transaction/{id}/create-remark',function ($transactionId) { $transaction = Transaction::find($transactionId); $remark = new Remark(); + + $remark->owner_type = get_class($transaction); + $remark->owner_id = $transaction->id; + $remark->content = request('content'); - $remark->id = $transactionId; $remark->save(); return redirect()->back(); })->name('transaction.create-remark'); Route::get('/show-white-form-transactions-in-date-range/{from_date}/{to_date}', function ($from_date, $to_date) { - $approvedTransactions = Transaction::where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED])->where('owner_type', '!=', Wallet::class)->orderBy('status')->get(); echo '

Pending Orders Payments

'; @@ -1004,15 +1006,15 @@ Route::get('/show-white-form-transactions-in-date-range/{from_date}/{to_date}', echo '' . round($approvedTransaction->amount, 2) . ''; echo '' . $approvedTransaction->created_at->format('d-m-Y h:i A') . ''; echo '' . ApprovalStatus::APPROVAL_STATUS_ID[$approvedTransaction->status] . ''; - $remark = Remark::where('id', $approvedTransaction->id)->first(); - if ($remark) { - echo '' . $remark->content . ''; - } else { - echo 'No remark found'; - } + $remarks = $approvedTransaction->remarks; + echo ''; + foreach ($remarks as $remark) { + echo "

$remark->content

"; + } + echo ''; echo '' ; echo ''; - echo ''; + echo ''; echo ''; echo csrf_field(); echo ''; @@ -1063,6 +1065,4 @@ Route::get('/show-white-form-transactions-in-date-range/{from_date}/{to_date}', echo ''; echo ''; - - }); From 32d8b26451acc1fccc6f983432b547a88461b6b1 Mon Sep 17 00:00:00 2001 From: Dodowingster Date: Thu, 25 Apr 2024 15:52:38 +0800 Subject: [PATCH 179/434] feat: added date and time for remarks --- routes/web.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/routes/web.php b/routes/web.php index 7dc095f3..d8ea0f1b 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1009,7 +1009,9 @@ Route::get('/show-white-form-transactions-in-date-range/{from_date}/{to_date}', $remarks = $approvedTransaction->remarks; echo ''; foreach ($remarks as $remark) { - echo "

$remark->content

"; + echo $remark->created_at->format('d-m-Y | h:i A') . ' - '; + echo $remark->content; + echo '
'; } echo ''; echo '' ; From 20cb00ed248da5d86b3dfc88ee3b6cdd1cd66a50 Mon Sep 17 00:00:00 2001 From: edmondlang Date: Thu, 25 Apr 2024 16:48:39 +0800 Subject: [PATCH 180/434] update add remark on white form transactions --- routes/web.php | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/routes/web.php b/routes/web.php index d8ea0f1b..861f5bdf 100644 --- a/routes/web.php +++ b/routes/web.php @@ -994,8 +994,6 @@ Route::get('/show-white-form-transactions-in-date-range/{from_date}/{to_date}', echo 'Amount'; echo 'Payment Date'; echo 'Status'; - echo 'Remark'; - echo 'Add Remarks'; echo ''; echo ''; echo ''; @@ -1006,21 +1004,6 @@ Route::get('/show-white-form-transactions-in-date-range/{from_date}/{to_date}', echo '' . round($approvedTransaction->amount, 2) . ''; echo '' . $approvedTransaction->created_at->format('d-m-Y h:i A') . ''; echo '' . ApprovalStatus::APPROVAL_STATUS_ID[$approvedTransaction->status] . ''; - $remarks = $approvedTransaction->remarks; - echo ''; - foreach ($remarks as $remark) { - echo $remark->created_at->format('d-m-Y | h:i A') . ' - '; - echo $remark->content; - echo '
'; - } - echo ''; - echo '' ; - echo '
'; - echo ''; - echo ''; - echo csrf_field(); - echo '
'; - echo ''; echo ''; } @@ -1043,6 +1026,8 @@ Route::get('/show-white-form-transactions-in-date-range/{from_date}/{to_date}', echo 'Upload bank slip Date'; echo 'PO submit date'; echo 'PO approve date'; + echo 'Remark'; + echo 'Add Remarks'; echo ''; echo ''; echo ''; @@ -1062,6 +1047,21 @@ Route::get('/show-white-form-transactions-in-date-range/{from_date}/{to_date}', echo '' . ($bill->status === ApprovalStatus::APPROVED ? $bill->updated_at->format('d-m-Y h:i A') : 'Pending Upload') . ''; echo '' . ($po ? $po->updated_at->format('d-m-Y h:i A') : 'Pending Submission') . ''; echo '' . ($po ? ($po->status === ApprovalStatus::APPROVED ? $po->updated_at->format('d-m-Y h:i A') : '' ) : '' ). ''; + $remarks = $bill->remarks; + echo ''; + foreach ($remarks as $remark) { + echo $remark->created_at->format('d-m-Y : h:i A') . ' - '; + echo $remark->content; + echo '
'; + } + echo ''; + echo '' ; + echo '
'; + echo ''; + echo ''; + echo csrf_field(); + echo '
'; + echo ''; echo ''; } From 590b9bccc36a852df05315e01c393f0ae04e3d69 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Fri, 26 Apr 2024 13:57:43 +0800 Subject: [PATCH 181/434] Laravel Vapor - testing production S3 storage on development environment --- vapor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vapor.yml b/vapor.yml index a0d31602..4328e569 100644 --- a/vapor.yml +++ b/vapor.yml @@ -55,7 +55,7 @@ environments: - exchange-default-development - exchange-high_priority-development database: cief-rds-mysql - storage: exchange-2.0-development + storage: exchange-2.0-production runtime: 'docker' timeout: 180 build: From 931a0f6bf5c737780f74ce914f2bc0d36d689101 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Fri, 26 Apr 2024 14:43:22 +0800 Subject: [PATCH 182/434] Laravel Vapor - debug reading from S3 storage --- .../ControllersLogic/BulkDownloadCustomerInvoicesLogic.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php index 89c8c1c4..87e4323e 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php @@ -67,8 +67,8 @@ class BulkDownloadCustomerInvoicesLogic ->files() ->first(); - $fileContent = Storage::disk('documents') - ->get($invoiceFile->file->file_info->original->file); + $fileContent = Storage::disk('s3') + ->get('documents/'.$invoiceFile->file->file_info->original->file); $zipDataStr .= 'invoice-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf'; $zipDataStr .= "\n"; // Add a separator From a93b8091b259d92aa575d0ccc6a268ba4d310f3d Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Fri, 26 Apr 2024 15:27:06 +0800 Subject: [PATCH 183/434] Laravel Vapor - debug reading from S3 storage --- .../BulkDownloadCustomerInvoicesLogic.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php index 87e4323e..4e118044 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php @@ -75,7 +75,13 @@ class BulkDownloadCustomerInvoicesLogic $zipDataStr .= $fileContent; } - $zipFileName = "invoices_{$startDate}_to_{$endDate}_{$company->reference}.zip"; + $zipDirectory = storage_path('app/bulk_invoice'); // Update this with the actual directory path + + if (!file_exists($zipDirectory)) { + mkdir($zipDirectory, 0755, true); + } + + $zipFileName = "{$zipDirectory}/invoices_{$startDate}_to_{$endDate}_{$company->reference}.zip"; if ($zip->open($zipFileName, ZipArchive::CREATE | ZipArchive::OVERWRITE)) { $zip->addFromString($zipFileName, $zipDataStr); From 2662980247a5837738e1c856f94712078bc24975 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Fri, 26 Apr 2024 15:53:28 +0800 Subject: [PATCH 184/434] Laravel Vapor - debug reading from S3 storage --- .../BulkDownloadCustomerInvoicesLogic.php | 31 ++++++------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php index 4e118044..014063b2 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php @@ -56,24 +56,6 @@ class BulkDownloadCustomerInvoicesLogic $filesystemDriver = Storage::getDefaultDriver(); if($filesystemDriver == 's3'){ - $zip = new ZipArchive(); - $zipDataStr = ''; - - foreach ($invoicebookings as $booking) { - $invoiceFile = $booking->documents() - ->where('document_type', DocumentType::INVOICE) - ->whereNull('deleted_at') - ->first() - ->files() - ->first(); - - $fileContent = Storage::disk('s3') - ->get('documents/'.$invoiceFile->file->file_info->original->file); - - $zipDataStr .= 'invoice-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf'; - $zipDataStr .= "\n"; // Add a separator - $zipDataStr .= $fileContent; - } $zipDirectory = storage_path('app/bulk_invoice'); // Update this with the actual directory path @@ -81,14 +63,19 @@ class BulkDownloadCustomerInvoicesLogic mkdir($zipDirectory, 0755, true); } - $zipFileName = "{$zipDirectory}/invoices_{$startDate}_to_{$endDate}_{$company->reference}.zip"; + $zipFileName = "invoices_{$startDate}_to_{$endDate}_{$company->reference}.zip"; + $zip_file = "{$zipDirectory}/{$zipFileName}"; - if ($zip->open($zipFileName, ZipArchive::CREATE | ZipArchive::OVERWRITE)) { - $zip->addFromString($zipFileName, $zipDataStr); + $zip = new ZipArchive(); + if ($zip->open($zip_file, ZipArchive::CREATE | ZipArchive::OVERWRITE)) { + foreach ($invoicebookings as $booking) { + $invoice_file = $booking->documents()->where('document_type', DocumentType::INVOICE)->whereNull('deleted_at')->first()->files()->first(); + $zip->addFile(Storage::disk('documents')->path($invoice_file->file->file_info->original->file), 'invoice-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf'); + } $zip->close(); $filePath = 'bulk_invoice/'.$zipFileName; - Storage::put($filePath, file_get_contents($zipFileName), 's3'); + Storage::put($filePath, file_get_contents($zip_file), 's3'); return response(['src' => Storage::disk('s3')->get($$filePath) ]); From 2a556b7a2841e9b5040dce5865f69d49af79bd66 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Fri, 26 Apr 2024 16:07:19 +0800 Subject: [PATCH 185/434] Laravel Vapor - debug reading from S3 storage --- .../ControllersLogic/BulkDownloadCustomerInvoicesLogic.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php index 014063b2..c409922f 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php @@ -70,7 +70,7 @@ class BulkDownloadCustomerInvoicesLogic if ($zip->open($zip_file, ZipArchive::CREATE | ZipArchive::OVERWRITE)) { foreach ($invoicebookings as $booking) { $invoice_file = $booking->documents()->where('document_type', DocumentType::INVOICE)->whereNull('deleted_at')->first()->files()->first(); - $zip->addFile(Storage::disk('documents')->path($invoice_file->file->file_info->original->file), 'invoice-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf'); + $zip->addFile(Storage::disk('s3')->get('documents/'.$invoice_file->file->file_info->original->file), 'invoice-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf'); } $zip->close(); From f44d0670ca45851dbd50d90f338a476b342259c6 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Fri, 26 Apr 2024 16:32:06 +0800 Subject: [PATCH 186/434] Laravel Vapor - debug reading from S3 storage --- .../ControllersLogic/BulkDownloadCustomerInvoicesLogic.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php index c409922f..06640779 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php @@ -70,14 +70,15 @@ class BulkDownloadCustomerInvoicesLogic if ($zip->open($zip_file, ZipArchive::CREATE | ZipArchive::OVERWRITE)) { foreach ($invoicebookings as $booking) { $invoice_file = $booking->documents()->where('document_type', DocumentType::INVOICE)->whereNull('deleted_at')->first()->files()->first(); - $zip->addFile(Storage::disk('s3')->get('documents/'.$invoice_file->file->file_info->original->file), 'invoice-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf'); + $fileContent = Storage::disk('s3')->get('documents/'.$invoice_file->file->file_info->original->file); + $zip->addFromString('invoice-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf', $fileContent); } $zip->close(); $filePath = 'bulk_invoice/'.$zipFileName; Storage::put($filePath, file_get_contents($zip_file), 's3'); - return response(['src' => Storage::disk('s3')->get($$filePath) ]); + return response(['src' => Storage::disk('s3')->get($filePath) ]); } else { return response()->json([ From a76adf34a5685b2f19009de03771cd027ba68055 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Fri, 26 Apr 2024 17:06:25 +0800 Subject: [PATCH 187/434] Laravel Vapor - debug reading from S3 storage --- .../ControllersLogic/BulkDownloadCustomerInvoicesLogic.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php index 06640779..b95c465e 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php @@ -78,7 +78,7 @@ class BulkDownloadCustomerInvoicesLogic $filePath = 'bulk_invoice/'.$zipFileName; Storage::put($filePath, file_get_contents($zip_file), 's3'); - return response(['src' => Storage::disk('s3')->get($filePath) ]); + return response()->download(Storage::disk('s3')->path($filePath)); } else { return response()->json([ From e05872e60959431a1dcfa6fb49d73213f9580c4f Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Fri, 26 Apr 2024 17:29:08 +0800 Subject: [PATCH 188/434] Laravel Vapor - debug reading from S3 storage --- .../ControllersLogic/BulkDownloadCustomerInvoicesLogic.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php index b95c465e..13f7e710 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php @@ -78,8 +78,8 @@ class BulkDownloadCustomerInvoicesLogic $filePath = 'bulk_invoice/'.$zipFileName; Storage::put($filePath, file_get_contents($zip_file), 's3'); - return response()->download(Storage::disk('s3')->path($filePath)); - + $responseContent = Storage::disk('s3')->get($filePath); + return response($responseContent)->header('Content-Type', 'application/zip'); } else { return response()->json([ 'status' => 'Error', From c0a87da77a8059d1069f5cf0d1e8e4c1c1b2d31a Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Fri, 26 Apr 2024 17:52:03 +0800 Subject: [PATCH 189/434] Laravel Vapor - debug reading from S3 storage --- .../ControllersLogic/BulkDownloadCustomerInvoicesLogic.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php index 13f7e710..b6279192 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php @@ -65,6 +65,8 @@ class BulkDownloadCustomerInvoicesLogic $zipFileName = "invoices_{$startDate}_to_{$endDate}_{$company->reference}.zip"; $zip_file = "{$zipDirectory}/{$zipFileName}"; + $zipFileName2 = "invoices_{$startDate}_to_{$endDate}_{$company->reference}_dup.zip"; + $zip_file2 = "{$zipDirectory}/{$zipFileName2}"; $zip = new ZipArchive(); if ($zip->open($zip_file, ZipArchive::CREATE | ZipArchive::OVERWRITE)) { @@ -79,7 +81,9 @@ class BulkDownloadCustomerInvoicesLogic Storage::put($filePath, file_get_contents($zip_file), 's3'); $responseContent = Storage::disk('s3')->get($filePath); - return response($responseContent)->header('Content-Type', 'application/zip'); + file_put_contents($zip_file2, $responseContent); + + return response()->download($zip_file2); } else { return response()->json([ 'status' => 'Error', From 38ad3d315d10584e6836f017c8e82a084d190b58 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Fri, 26 Apr 2024 18:34:09 +0800 Subject: [PATCH 190/434] Laravel Vapor - debug reading from S3 storage --- .../BulkDownloadCustomerInvoicesLogic.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php index b6279192..a02ff4e8 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php @@ -65,8 +65,8 @@ class BulkDownloadCustomerInvoicesLogic $zipFileName = "invoices_{$startDate}_to_{$endDate}_{$company->reference}.zip"; $zip_file = "{$zipDirectory}/{$zipFileName}"; - $zipFileName2 = "invoices_{$startDate}_to_{$endDate}_{$company->reference}_dup.zip"; - $zip_file2 = "{$zipDirectory}/{$zipFileName2}"; + // $zipFileName2 = "invoices_{$startDate}_to_{$endDate}_{$company->reference}_dup.zip"; + // $zip_file2 = "{$zipDirectory}/{$zipFileName2}"; $zip = new ZipArchive(); if ($zip->open($zip_file, ZipArchive::CREATE | ZipArchive::OVERWRITE)) { @@ -77,13 +77,13 @@ class BulkDownloadCustomerInvoicesLogic } $zip->close(); - $filePath = 'bulk_invoice/'.$zipFileName; - Storage::put($filePath, file_get_contents($zip_file), 's3'); + // $filePathForS3 = 'bulk_invoice/'.$zipFileName; + // Storage::put($filePathForS3, file_get_contents($zip_file), 's3'); + // $responseContent = Storage::disk('s3')->get($filePathForS3); + // file_put_contents($zip_file2, $responseContent); + // return response()->download($zip_file2); - $responseContent = Storage::disk('s3')->get($filePath); - file_put_contents($zip_file2, $responseContent); - - return response()->download($zip_file2); + return response()->download($zip_file); } else { return response()->json([ 'status' => 'Error', From 3f88c365e8f80da79ccef52272ebf1668b420d0e Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Sat, 27 Apr 2024 10:08:55 +0800 Subject: [PATCH 191/434] Laravel Vapor - sync code for download files in bulk from S3 to more files --- .../BulkDownloadCustomerInvoicesLogic.php | 29 ++------ .../BulkDownloadSupplierWhiteFormsLogic.php | 66 +++++++++++++------ 2 files changed, 52 insertions(+), 43 deletions(-) diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php index a02ff4e8..d8c3506d 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php @@ -53,20 +53,18 @@ class BulkDownloadCustomerInvoicesLogic ]); } + $zipDirectory = storage_path('app/bulk_invoice'); // Update this with the actual directory path + + if (!file_exists($zipDirectory)) { + mkdir($zipDirectory, 0755, true); + } $filesystemDriver = Storage::getDefaultDriver(); if($filesystemDriver == 's3'){ - - $zipDirectory = storage_path('app/bulk_invoice'); // Update this with the actual directory path - - if (!file_exists($zipDirectory)) { - mkdir($zipDirectory, 0755, true); - } - + $startDate = $startDate->format('d-m-Y'); + $endDate = $endDate->format('d-m-Y'); $zipFileName = "invoices_{$startDate}_to_{$endDate}_{$company->reference}.zip"; $zip_file = "{$zipDirectory}/{$zipFileName}"; - // $zipFileName2 = "invoices_{$startDate}_to_{$endDate}_{$company->reference}_dup.zip"; - // $zip_file2 = "{$zipDirectory}/{$zipFileName2}"; $zip = new ZipArchive(); if ($zip->open($zip_file, ZipArchive::CREATE | ZipArchive::OVERWRITE)) { @@ -77,12 +75,6 @@ class BulkDownloadCustomerInvoicesLogic } $zip->close(); - // $filePathForS3 = 'bulk_invoice/'.$zipFileName; - // Storage::put($filePathForS3, file_get_contents($zip_file), 's3'); - // $responseContent = Storage::disk('s3')->get($filePathForS3); - // file_put_contents($zip_file2, $responseContent); - // return response()->download($zip_file2); - return response()->download($zip_file); } else { return response()->json([ @@ -92,13 +84,6 @@ class BulkDownloadCustomerInvoicesLogic } } else{ - - $zipDirectory = storage_path('app/bulk_invoice'); // Update this with the actual directory path - - if (!file_exists($zipDirectory)) { - mkdir($zipDirectory, 0755, true); - } - $zip_file = "{$zipDirectory}/invoices_{$request->input('startDate')}_to_{$request->input('endDate')}_{$company->reference}.zip"; $zip = new ZipArchive(); diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php index 87f0ad83..fe65027b 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php @@ -22,17 +22,17 @@ class BulkDownloadSupplierWhiteFormsLogic public function execute(Request $request) { try { - + $startDate = Carbon::createFromFormat('d-m-Y', $request->input('startDate'))->startOfDay(); $endDate = Carbon::createFromFormat('d-m-Y', $request->input('endDate'))->endOfDay(); - + $companyReference = Company::find($request->input('supplier'))->reference; $groups = Group::where('issuer', $request->input('supplier')) ->whereDate('created_at', '>=', $startDate) ->whereDate('created_at', '<=', $endDate) ->orderBy('created_at', 'DESC') ->get(); - + if (count($groups) > 0) { $zipDirectory = storage_path('app/bulk_whiteform'); // Update this with the actual directory path @@ -40,25 +40,49 @@ class BulkDownloadSupplierWhiteFormsLogic if (!file_exists($zipDirectory)) { mkdir($zipDirectory, 0755, true); } - - $zip_file = "{$zipDirectory}/currency_vendor_orders_{$request->input('startDate')}_to_{$request->input('endDate')}_{$companyReference}.zip"; - $zip = new ZipArchive(); - if ($zip->open($zip_file, ZIPARCHIVE::CREATE | ZipArchive::OVERWRITE)) { - foreach($groups as $group) { - $document = $group->documents()->where('document_type', DocumentType::CURRENCY_VENDOR_ORDER)->whereNull('deleted_at')->first()->files()->first(); - $created_at = $group->created_at->format('Y-m-d'); - $zip->addFile(Storage::disk('documents')->path($document->file->file_info->original->file), $created_at . "_" . $group->amount . "_" . $group->reference . '.pdf'); - } - - $zip->close(); - while (ob_get_level()) { - ob_end_clean(); - } - - return response()->download($zip_file); + + $filesystemDriver = Storage::getDefaultDriver(); + if($filesystemDriver == 's3'){ + + $startDate = $startDate->format('d-m-Y'); + $endDate = $endDate->format('d-m-Y'); + $zipFileName = "currency_vendor_orders_{$startDate}_to_{$endDate}_{$companyReference}.zip"; + $zip_file = "{$zipDirectory}/{$zipFileName}"; + + $zip = new ZipArchive(); + if ($zip->open($zip_file, ZIPARCHIVE::CREATE | ZipArchive::OVERWRITE)) { + foreach($groups as $group) { + $document = $group->documents()->where('document_type', DocumentType::CURRENCY_VENDOR_ORDER)->whereNull('deleted_at')->first()->files()->first(); + $created_at = $group->created_at->format('Y-m-d'); + $fileContent = Storage::disk('s3')->get('documents/'.$document->file->file_info->original->file); + $zip->addFromString('invoice-' . $created_at . "_" . $group->amount . "_" . $group->reference . '.pdf', $fileContent); + } + + $zip->close(); + + return response()->download($zip_file); } - } + else{ + $zip_file = "{$zipDirectory}/currency_vendor_orders_{$request->input('startDate')}_to_{$request->input('endDate')}_{$companyReference}.zip"; + + $zip = new ZipArchive(); + if ($zip->open($zip_file, ZIPARCHIVE::CREATE | ZipArchive::OVERWRITE)) { + foreach($groups as $group) { + $document = $group->documents()->where('document_type', DocumentType::CURRENCY_VENDOR_ORDER)->whereNull('deleted_at')->first()->files()->first(); + $created_at = $group->created_at->format('Y-m-d'); + $zip->addFile(Storage::disk('documents')->path($document->file->file_info->original->file), $created_at . "_" . $group->amount . "_" . $group->reference . '.pdf'); + } + + $zip->close(); + while (ob_get_level()) { + ob_end_clean(); + } + + return response()->download($zip_file); + } + } + } return response()->json([ 'status' => 'Failed', @@ -75,4 +99,4 @@ class BulkDownloadSupplierWhiteFormsLogic ]); } } -} \ No newline at end of file +} From e240bdd2b4b4ebdf0acafe610d203606cdcdbda9 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Sat, 27 Apr 2024 10:26:10 +0800 Subject: [PATCH 192/434] Laravel Vapor - sync code for download files in bulk from S3 to more files --- .../ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php index fe65027b..b7b3879f 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php @@ -62,6 +62,7 @@ class BulkDownloadSupplierWhiteFormsLogic $zip->close(); return response()->download($zip_file); + } } else{ $zip_file = "{$zipDirectory}/currency_vendor_orders_{$request->input('startDate')}_to_{$request->input('endDate')}_{$companyReference}.zip"; From 4ec4ecbb7ae364f075d0fd81ed57bb790063a4d2 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Sat, 27 Apr 2024 10:36:56 +0800 Subject: [PATCH 193/434] Laravel Vapor - sync code for download files in bulk from S3 to more files --- .../V2/DeleteBulkInvoiceFilesV2CommandJob.php | 44 ++++++++++++++----- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/app/Classes/Jobs/Commands/V2/DeleteBulkInvoiceFilesV2CommandJob.php b/app/Classes/Jobs/Commands/V2/DeleteBulkInvoiceFilesV2CommandJob.php index 89733472..42c990ce 100644 --- a/app/Classes/Jobs/Commands/V2/DeleteBulkInvoiceFilesV2CommandJob.php +++ b/app/Classes/Jobs/Commands/V2/DeleteBulkInvoiceFilesV2CommandJob.php @@ -11,6 +11,7 @@ use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; use Illuminate\Support\Facades\File; use Illuminate\Support\Facades\Log; +use Illuminate\Support\Facades\Storage; class DeleteBulkInvoiceFilesV2CommandJob implements ShouldQueue { @@ -23,25 +24,48 @@ class DeleteBulkInvoiceFilesV2CommandJob implements ShouldQueue $start = new Carbon(); $directories = [ - storage_path('app/bulk_invoice'), //cief todo: should map to the equivalent in AWS S3 bucket - storage_path('app/bulk_whiteform'), //cief todo: should map to the equivalent in AWS S3 bucket + storage_path('app/bulk_invoice'), + storage_path('app/bulk_whiteform'), ]; foreach ($directories as $directory) { - $start = new Carbon(); - Log::info(Carbon::now() . ' Start cleaning - ' . $directory); + $startInner = new Carbon(); + Log::info(Carbon::now() . ' [Local] Start cleaning - ' . $directory); - if (File::isDirectory($directory)) { //cief todo: should map to the equivalent in AWS S3 bucket + if (File::isDirectory($directory)) { File::cleanDirectory($directory); - Log::info('All files have been deleted.'); + Log::info('[Local] All files have been deleted.'); } else { - Log::info('Directory does not exist.'); + Log::info('[Local] Directory does not exist.'); } - $end = new Carbon(); - $elapsedTime = $start->diff($end)->format('%H:%I:%S'); + $endInner = new Carbon(); + $elapsedTime = $startInner->diff($endInner)->format('%H:%I:%S'); - Log::info(Carbon::now() . ' Process ended. ElapsedTime: ' . $elapsedTime); + Log::info(Carbon::now() . ' [Local] Process ended. ElapsedTime: ' . $elapsedTime); + } + + $s3 = Storage::disk('s3'); + $directories = [ + 'bulk_invoice', + 'bulk_whiteform', + ]; + foreach ($directories as $directory) { + $startInner = Carbon::now(); + Log::info(Carbon::now() . ' [S3] Start cleaning - ' . $directory); + + $objects = $s3->allFiles($directory); + + foreach ($objects as $object) { + $s3->delete($object); + Log::info('[S3] Deleted object: ' . $object); + } + + Log::info('[S3] All files have been deleted.'); + + $endInner = Carbon::now(); + $elapsedTime = $startInner->diff($endInner)->format('%H:%I:%S'); + Log::info(Carbon::now() . ' [S3] Process ended. ElapsedTime: ' . $elapsedTime); } $end = new Carbon(); From f98e2cb4dd3c376acffb879747b3013c2bf5cf74 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Sat, 27 Apr 2024 11:50:32 +0800 Subject: [PATCH 194/434] Laravel Vapor - sync code for download files in bulk from S3 to more files --- .../BulkDownloadSupplierWhiteFormsLogic.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php index b7b3879f..32fadf03 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php @@ -63,6 +63,12 @@ class BulkDownloadSupplierWhiteFormsLogic return response()->download($zip_file); } + else { + return response()->json([ + 'status' => 'Error', + 'message' => 'Failed to create the Zip archive for supplier white forms.', + ]); + } } else{ $zip_file = "{$zipDirectory}/currency_vendor_orders_{$request->input('startDate')}_to_{$request->input('endDate')}_{$companyReference}.zip"; From 69f939ad99240d98a64c8651f6f3de37e2c9647a Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Sat, 27 Apr 2024 12:13:28 +0800 Subject: [PATCH 195/434] Laravel Vapor - sync code for download files in bulk from S3 to more files --- .../BulkDownloadSupplierWhiteFormsLogic.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php index 32fadf03..60b8412c 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php @@ -55,10 +55,16 @@ class BulkDownloadSupplierWhiteFormsLogic foreach($groups as $group) { $document = $group->documents()->where('document_type', DocumentType::CURRENCY_VENDOR_ORDER)->whereNull('deleted_at')->first()->files()->first(); $created_at = $group->created_at->format('Y-m-d'); - $fileContent = Storage::disk('s3')->get('documents/'.$document->file->file_info->original->file); - $zip->addFromString('invoice-' . $created_at . "_" . $group->amount . "_" . $group->reference . '.pdf', $fileContent); + Log::info('BulkDownloadSupplierWhiteFormsLogic processing: ' . 'documents/'.$document->file->file_info->original->file); + if(!Storage::disk('s3')->exists('documents/'.$document->file->file_info->original->file)) + { + Log::info('BulkDownloadSupplierWhiteFormsLogic file does not exist: ' . 'documents/'.$document->file->file_info->original->file); + } + else{ + $fileContent = Storage::disk('s3')->get('documents/'.$document->file->file_info->original->file); + $zip->addFromString('invoice-' . $created_at . "_" . $group->amount . "_" . $group->reference . '.pdf', $fileContent); + } } - $zip->close(); return response()->download($zip_file); From e97515ab9fcfe0d9ad63ed3da02973e0f5014576 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Sat, 27 Apr 2024 12:31:37 +0800 Subject: [PATCH 196/434] Laravel Vapor - sync code for download files in bulk from S3 to more files --- .../ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php index 60b8412c..00b19b79 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php @@ -67,6 +67,10 @@ class BulkDownloadSupplierWhiteFormsLogic } $zip->close(); + $filePathForS3 = 'bulk_whiteform/'.$zipFileName; + Storage::put($filePathForS3, file_get_contents($zip_file), 's3'); + Log::info('BulkDownloadSupplierWhiteFormsLogic finished processing files count: '.count($groups)); + return response()->download($zip_file); } else { From cf80e31df73da92c53d087a0f3d13934d76cc2d3 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Sat, 27 Apr 2024 13:05:41 +0800 Subject: [PATCH 197/434] Laravel Vapor - sync code for download files in bulk from S3 to more files --- .../BulkDownloadSupplierWhiteFormsLogic.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php index 00b19b79..718aaa1a 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php @@ -49,6 +49,8 @@ class BulkDownloadSupplierWhiteFormsLogic $endDate = $endDate->format('d-m-Y'); $zipFileName = "currency_vendor_orders_{$startDate}_to_{$endDate}_{$companyReference}.zip"; $zip_file = "{$zipDirectory}/{$zipFileName}"; + $zipFileName2 = "currency_vendor_orders_{$startDate}_to_{$endDate}_{$companyReference}_dup.zip"; + $zip_file2 = "{$zipDirectory}/{$zipFileName2}"; $zip = new ZipArchive(); if ($zip->open($zip_file, ZIPARCHIVE::CREATE | ZipArchive::OVERWRITE)) { @@ -69,9 +71,13 @@ class BulkDownloadSupplierWhiteFormsLogic $filePathForS3 = 'bulk_whiteform/'.$zipFileName; Storage::put($filePathForS3, file_get_contents($zip_file), 's3'); + + $responseContent = Storage::disk('s3')->get($filePathForS3); + file_put_contents($zip_file2, $responseContent); + Log::info('BulkDownloadSupplierWhiteFormsLogic finished processing files count: '.count($groups)); - return response()->download($zip_file); + return response()->download($zip_file2); } else { return response()->json([ From 734038fd334191e47a5964e17fb867b9e4699cbf Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Mon, 29 Apr 2024 10:27:09 +0800 Subject: [PATCH 198/434] Laravel Vapor - sync code for download files in bulk from S3 to more files --- .../BulkDownloadSupplierWhiteFormsLogic.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php index 718aaa1a..5c68dd33 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php @@ -72,12 +72,14 @@ class BulkDownloadSupplierWhiteFormsLogic $filePathForS3 = 'bulk_whiteform/'.$zipFileName; Storage::put($filePathForS3, file_get_contents($zip_file), 's3'); - $responseContent = Storage::disk('s3')->get($filePathForS3); - file_put_contents($zip_file2, $responseContent); + // $responseContent = Storage::disk('s3')->get($filePathForS3); + // file_put_contents($zip_file2, $responseContent); + + $url = Storage::disk('s3')->url($filePathForS3); Log::info('BulkDownloadSupplierWhiteFormsLogic finished processing files count: '.count($groups)); - return response()->download($zip_file2); + return response()->download($url); } else { return response()->json([ From ac214d45b23dc040db64087054ba61b48515f713 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Mon, 29 Apr 2024 10:55:43 +0800 Subject: [PATCH 199/434] Laravel Vapor - sync code for download files in bulk from S3 to more files --- .../BulkDownloadSupplierWhiteFormsLogic.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php index 5c68dd33..fd92c097 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php @@ -70,16 +70,17 @@ class BulkDownloadSupplierWhiteFormsLogic $zip->close(); $filePathForS3 = 'bulk_whiteform/'.$zipFileName; - Storage::put($filePathForS3, file_get_contents($zip_file), 's3'); - - // $responseContent = Storage::disk('s3')->get($filePathForS3); - // file_put_contents($zip_file2, $responseContent); - - $url = Storage::disk('s3')->url($filePathForS3); + Storage::disk('s3')->put($filePathForS3, file_get_contents($zip_file)); Log::info('BulkDownloadSupplierWhiteFormsLogic finished processing files count: '.count($groups)); - return response()->download($url); + return redirect(Storage::disk('s3')->temporaryUrl( + $filePathForS3, + now()->addHour(), + ['ResponseContentDisposition' => 'attachment'] + )); + + // return response()->download($url); } else { return response()->json([ From 29300ee039adaefe8560bf3d5b573ae657b73bdd Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Mon, 29 Apr 2024 11:13:39 +0800 Subject: [PATCH 200/434] Laravel Vapor - sync code for download files in bulk from S3 to more files --- .../BulkDownloadSupplierWhiteFormsLogic.php | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php index fd92c097..50c8f1c8 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php @@ -49,8 +49,6 @@ class BulkDownloadSupplierWhiteFormsLogic $endDate = $endDate->format('d-m-Y'); $zipFileName = "currency_vendor_orders_{$startDate}_to_{$endDate}_{$companyReference}.zip"; $zip_file = "{$zipDirectory}/{$zipFileName}"; - $zipFileName2 = "currency_vendor_orders_{$startDate}_to_{$endDate}_{$companyReference}_dup.zip"; - $zip_file2 = "{$zipDirectory}/{$zipFileName2}"; $zip = new ZipArchive(); if ($zip->open($zip_file, ZIPARCHIVE::CREATE | ZipArchive::OVERWRITE)) { @@ -74,13 +72,13 @@ class BulkDownloadSupplierWhiteFormsLogic Log::info('BulkDownloadSupplierWhiteFormsLogic finished processing files count: '.count($groups)); - return redirect(Storage::disk('s3')->temporaryUrl( - $filePathForS3, - now()->addHour(), - ['ResponseContentDisposition' => 'attachment'] - )); - - // return response()->download($url); + return response()->streamDownload(function () use ($filePathForS3) { + return Storage::disk('s3')->temporaryUrl( + $filePathForS3, + Carbon::now()->addMinutes(60), + ['ResponseContentDisposition' => 'attachment'] + ); + }, $zipFileName); } else { return response()->json([ From 85013007d5f82e8d92b0a1e1ef8e875d4a309425 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Mon, 29 Apr 2024 11:28:58 +0800 Subject: [PATCH 201/434] Laravel Vapor - sync code for download files in bulk from S3 to more files --- .../ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php index 50c8f1c8..4bdbaa8d 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php @@ -73,7 +73,7 @@ class BulkDownloadSupplierWhiteFormsLogic Log::info('BulkDownloadSupplierWhiteFormsLogic finished processing files count: '.count($groups)); return response()->streamDownload(function () use ($filePathForS3) { - return Storage::disk('s3')->temporaryUrl( + echo Storage::disk('s3')->temporaryUrl( $filePathForS3, Carbon::now()->addMinutes(60), ['ResponseContentDisposition' => 'attachment'] From 577273bb240cb2f3bc3c97d81e23a0633b9c66b8 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Mon, 29 Apr 2024 11:47:19 +0800 Subject: [PATCH 202/434] Laravel Vapor - sync code for download files in bulk from S3 to more files --- .../BulkDownloadSupplierWhiteFormsLogic.php | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php index 4bdbaa8d..1f09e8dd 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php @@ -72,13 +72,19 @@ class BulkDownloadSupplierWhiteFormsLogic Log::info('BulkDownloadSupplierWhiteFormsLogic finished processing files count: '.count($groups)); - return response()->streamDownload(function () use ($filePathForS3) { - echo Storage::disk('s3')->temporaryUrl( - $filePathForS3, - Carbon::now()->addMinutes(60), - ['ResponseContentDisposition' => 'attachment'] - ); - }, $zipFileName); + // return response()->streamDownload(function () use ($filePathForS3) { + // echo Storage::disk('s3')->temporaryUrl( + // $filePathForS3, + // Carbon::now()->addMinutes(60), + // ['ResponseContentDisposition' => 'attachment'] + // ); + // }, $zipFileName); + + $tempUrl = Storage::disk('s3')->temporaryUrl( + $filePathForS3, + Carbon::now()->addMinutes(60) + ); + return response()->download($tempUrl); } else { return response()->json([ From 69572e7234323c0b57b7ec73e362d1a258ffc95d Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Mon, 29 Apr 2024 12:28:53 +0800 Subject: [PATCH 203/434] Laravel Vapor - sync code for download files in bulk from S3 to more files --- .../BulkDownloadSupplierWhiteFormsLogic.php | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php index 1f09e8dd..9ac6678e 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php @@ -72,19 +72,12 @@ class BulkDownloadSupplierWhiteFormsLogic Log::info('BulkDownloadSupplierWhiteFormsLogic finished processing files count: '.count($groups)); - // return response()->streamDownload(function () use ($filePathForS3) { - // echo Storage::disk('s3')->temporaryUrl( - // $filePathForS3, - // Carbon::now()->addMinutes(60), - // ['ResponseContentDisposition' => 'attachment'] - // ); - // }, $zipFileName); - - $tempUrl = Storage::disk('s3')->temporaryUrl( - $filePathForS3, - Carbon::now()->addMinutes(60) - ); - return response()->download($tempUrl); + return response()->streamDownload(function () use ($filePathForS3) { + echo Storage::disk('s3')->temporaryUrl( + $filePathForS3, + Carbon::now()->addMinutes(60) + ); + }, $zipFileName); } else { return response()->json([ From 23909e3608a51204a385d18da1d5f5e3873c79a8 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Mon, 29 Apr 2024 12:46:27 +0800 Subject: [PATCH 204/434] Laravel Vapor - sync code for download files in bulk from S3 to more files --- .../ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php index 9ac6678e..2e4acbe5 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php @@ -73,10 +73,12 @@ class BulkDownloadSupplierWhiteFormsLogic Log::info('BulkDownloadSupplierWhiteFormsLogic finished processing files count: '.count($groups)); return response()->streamDownload(function () use ($filePathForS3) { - echo Storage::disk('s3')->temporaryUrl( + $temporaryUrl = Storage::disk('s3')->temporaryUrl( $filePathForS3, Carbon::now()->addMinutes(60) ); + $fileContents = file_get_contents($temporaryUrl); + echo $fileContents; }, $zipFileName); } else { From 377ad11a4f8719273ffd04680f97ad96102cbc04 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Mon, 29 Apr 2024 13:04:56 +0800 Subject: [PATCH 205/434] Laravel Vapor - sync code for download files in bulk from S3 to more files --- .../ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php index 2e4acbe5..a6e29b83 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php @@ -10,6 +10,7 @@ use App\Classes\ValueObjects\Constants\DocumentType; use App\Models\Company; use App\Models\Group; use Carbon\Carbon; +use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Log; class BulkDownloadSupplierWhiteFormsLogic @@ -77,8 +78,8 @@ class BulkDownloadSupplierWhiteFormsLogic $filePathForS3, Carbon::now()->addMinutes(60) ); - $fileContents = file_get_contents($temporaryUrl); - echo $fileContents; + $response = Http::get($temporaryUrl); + echo $response->getBody()->getContents(); }, $zipFileName); } else { From 69980ef064e323208170275cd9dca3124f275596 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Mon, 29 Apr 2024 13:28:25 +0800 Subject: [PATCH 206/434] Laravel Vapor - sync code for download files in bulk from S3 to more files --- .../BulkDownloadSupplierWhiteFormsLogic.php | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php index a6e29b83..61cce5ae 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php @@ -73,14 +73,27 @@ class BulkDownloadSupplierWhiteFormsLogic Log::info('BulkDownloadSupplierWhiteFormsLogic finished processing files count: '.count($groups)); - return response()->streamDownload(function () use ($filePathForS3) { + // return response()->streamDownload(function () use ($filePathForS3) { + // $temporaryUrl = Storage::disk('s3')->temporaryUrl( + // $filePathForS3, + // Carbon::now()->addMinutes(60) + // ); + // $response = Http::get($temporaryUrl); + // echo $response->getBody()->getContents(); + // }, $zipFileName); + + return response()->stream(function () use ($filePathForS3) { $temporaryUrl = Storage::disk('s3')->temporaryUrl( $filePathForS3, Carbon::now()->addMinutes(60) ); - $response = Http::get($temporaryUrl); - echo $response->getBody()->getContents(); - }, $zipFileName); + $fileStream = fopen($temporaryUrl, 'r'); + fpassthru($fileStream); + fclose($fileStream); + }, 200, [ + 'Content-Type' => 'application/octet-stream', + 'Content-Disposition' => 'attachment', + ]); } else { return response()->json([ From 4575eab701c84e0ed69d3fec96dcbee36ff950ef Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Mon, 29 Apr 2024 13:49:50 +0800 Subject: [PATCH 207/434] Laravel Vapor - sync code for download files in bulk from S3 to more files --- .../BulkDownloadSupplierWhiteFormsLogic.php | 25 ++++--------------- .../elements/BulkDownloadInvoiceComponent.vue | 14 ++++++++--- 2 files changed, 15 insertions(+), 24 deletions(-) diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php index 61cce5ae..6708646b 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php @@ -73,27 +73,12 @@ class BulkDownloadSupplierWhiteFormsLogic Log::info('BulkDownloadSupplierWhiteFormsLogic finished processing files count: '.count($groups)); - // return response()->streamDownload(function () use ($filePathForS3) { - // $temporaryUrl = Storage::disk('s3')->temporaryUrl( - // $filePathForS3, - // Carbon::now()->addMinutes(60) - // ); - // $response = Http::get($temporaryUrl); - // echo $response->getBody()->getContents(); - // }, $zipFileName); + $temporaryUrl = Storage::disk('s3')->temporaryUrl( + $filePathForS3, + Carbon::now()->addMinutes(60) + ); - return response()->stream(function () use ($filePathForS3) { - $temporaryUrl = Storage::disk('s3')->temporaryUrl( - $filePathForS3, - Carbon::now()->addMinutes(60) - ); - $fileStream = fopen($temporaryUrl, 'r'); - fpassthru($fileStream); - fclose($fileStream); - }, 200, [ - 'Content-Type' => 'application/octet-stream', - 'Content-Disposition' => 'attachment', - ]); + return response(['src' => $temporaryUrl ]); } else { return response()->json([ diff --git a/resources/assets/vue/components/companies/elements/BulkDownloadInvoiceComponent.vue b/resources/assets/vue/components/companies/elements/BulkDownloadInvoiceComponent.vue index df9f4f9d..deff567e 100644 --- a/resources/assets/vue/components/companies/elements/BulkDownloadInvoiceComponent.vue +++ b/resources/assets/vue/components/companies/elements/BulkDownloadInvoiceComponent.vue @@ -88,10 +88,16 @@ }, successHandler(response) { this.isLoading = false; - if (response.message) { - this.returnData = response; - } else { - this.returnData = null; + if(window.LARAVEL_VAPOR_ENABLED){ + let src = response.payload.src; + window.location.href = src; + } + else{ + if (response.message) { + this.returnData = response; + } else { + this.returnData = null; + } } }, hasMarkingParameter() { From 5033f9b5f8ed5b50b647aee8c5cf6660dd10b3eb Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Mon, 29 Apr 2024 14:12:05 +0800 Subject: [PATCH 208/434] Laravel Vapor - sync code for download files in bulk from S3 to more files --- .../elements/DownloadSupplierWhiteFormComponent.vue | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/resources/assets/vue/components/bookings/elements/DownloadSupplierWhiteFormComponent.vue b/resources/assets/vue/components/bookings/elements/DownloadSupplierWhiteFormComponent.vue index 59465f25..ef18c6a9 100644 --- a/resources/assets/vue/components/bookings/elements/DownloadSupplierWhiteFormComponent.vue +++ b/resources/assets/vue/components/bookings/elements/DownloadSupplierWhiteFormComponent.vue @@ -86,10 +86,19 @@ export default { }, successHandler(response) { this.isLoading = false; + console.log('debug response: ' + JSON.stringify(response)); if (response.message) { this.returnData = response; - } else { + } + else { this.returnData = null; + if(window.LARAVEL_VAPOR_ENABLED){ + console.log('window.LARAVEL_VAPOR_ENABLED'); + let src = response.src; + if (src) { + window.location.href = src; + } + } } }, }, From 4c5ce234b6c137fdd22f5950a8bd6a20af5c7937 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Mon, 29 Apr 2024 14:30:25 +0800 Subject: [PATCH 209/434] Laravel Vapor - sync code for download files in bulk from S3 to more files --- .../BulkDownloadCustomerInvoicesLogic.php | 13 ++++++++++++- .../BulkDownloadSupplierWhiteFormsLogic.php | 2 +- .../DownloadSupplierWhiteFormComponent.vue | 5 ++--- .../elements/BulkDownloadInvoiceComponent.vue | 18 ++++++++++-------- 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php index d8c3506d..dd48425c 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php @@ -75,7 +75,18 @@ class BulkDownloadCustomerInvoicesLogic } $zip->close(); - return response()->download($zip_file); + $filePathForS3 = 'bulk_whiteform/'.$zipFileName; + Storage::disk('s3')->put($filePathForS3, file_get_contents($zip_file)); + + Log::info('BulkDownloadCustomerInvoicesLogic finished processing files count: '.count($invoicebookings)); + + $temporaryUrl = Storage::disk('s3')->temporaryUrl( + $filePathForS3, + Carbon::now()->addMinutes(10) + ); + + return response(['src' => $temporaryUrl ]); + } else { return response()->json([ 'status' => 'Error', diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php index 6708646b..61c91d9b 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php @@ -75,7 +75,7 @@ class BulkDownloadSupplierWhiteFormsLogic $temporaryUrl = Storage::disk('s3')->temporaryUrl( $filePathForS3, - Carbon::now()->addMinutes(60) + Carbon::now()->addMinutes(10) ); return response(['src' => $temporaryUrl ]); diff --git a/resources/assets/vue/components/bookings/elements/DownloadSupplierWhiteFormComponent.vue b/resources/assets/vue/components/bookings/elements/DownloadSupplierWhiteFormComponent.vue index ef18c6a9..54f1617e 100644 --- a/resources/assets/vue/components/bookings/elements/DownloadSupplierWhiteFormComponent.vue +++ b/resources/assets/vue/components/bookings/elements/DownloadSupplierWhiteFormComponent.vue @@ -94,9 +94,8 @@ export default { this.returnData = null; if(window.LARAVEL_VAPOR_ENABLED){ console.log('window.LARAVEL_VAPOR_ENABLED'); - let src = response.src; - if (src) { - window.location.href = src; + if (response.src) { + window.location.href = response.src; } } } diff --git a/resources/assets/vue/components/companies/elements/BulkDownloadInvoiceComponent.vue b/resources/assets/vue/components/companies/elements/BulkDownloadInvoiceComponent.vue index deff567e..b8b50998 100644 --- a/resources/assets/vue/components/companies/elements/BulkDownloadInvoiceComponent.vue +++ b/resources/assets/vue/components/companies/elements/BulkDownloadInvoiceComponent.vue @@ -88,15 +88,17 @@ }, successHandler(response) { this.isLoading = false; - if(window.LARAVEL_VAPOR_ENABLED){ - let src = response.payload.src; - window.location.href = src; + console.log('debug response: ' + JSON.stringify(response)); + if (response.message) { + this.returnData = response; } - else{ - if (response.message) { - this.returnData = response; - } else { - this.returnData = null; + else { + this.returnData = null; + if(window.LARAVEL_VAPOR_ENABLED){ + console.log('window.LARAVEL_VAPOR_ENABLED'); + if (response.src) { + window.location.href = response.src; + } } } }, From 357a4fde66eb26486a021781fe88b82ea5c022ae Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Mon, 29 Apr 2024 14:57:15 +0800 Subject: [PATCH 210/434] Laravel Vapor - sync code for download files in bulk from S3 to more files --- app/Classes/General/ExcelHandel.php | 15 ++++++++++++--- .../BulkDownloadCustomerInvoicesLogic.php | 2 +- .../BulkDownloadSupplierWhiteFormsLogic.php | 2 +- .../ControllersLogic/RenderDocumentLogic.php | 2 +- .../Documents/Services/ConvertsBase64ToFile.php | 2 +- .../Imports/ImportUpdateDebtorController.php | 1 - .../DownloadSupplierWhiteFormComponent.vue | 2 -- .../elements/BulkDownloadInvoiceComponent.vue | 2 -- 8 files changed, 16 insertions(+), 12 deletions(-) diff --git a/app/Classes/General/ExcelHandel.php b/app/Classes/General/ExcelHandel.php index 3060ed8b..31034ff8 100644 --- a/app/Classes/General/ExcelHandel.php +++ b/app/Classes/General/ExcelHandel.php @@ -3,6 +3,7 @@ namespace App\Classes\General; use Illuminate\Support\Str; use Illuminate\Support\Facades\Cache; +use Illuminate\Support\Facades\Storage; class ExcelHandel { @@ -67,9 +68,17 @@ class ExcelHandel public static function generateExcel($path = '', $exceldata = '', $filename = '', $extension = '') { $file_info = []; - $file = \Storage::disk('public')->put('excels/' . $path . '/' . $filename . '.' . $extension, $exceldata); + $filesystemDriver = Storage::getDefaultDriver(); + if($filesystemDriver === 's3'){ + $filePathForS3 = 'public/excels/' . $path . '/' . $filename . '.' . $extension; + Storage::disk('s3')->put($filePathForS3, $exceldata); + } + else{ + $file = Storage::disk('public')->put('excels/' . $path . '/' . $filename . '.' . $extension, $exceldata); + } + $file_info['original']['file'] = storage_path('app/public/excels/' . $path . '/' . $filename . '.' . $extension); - + return $file_info; } @@ -84,4 +93,4 @@ class ExcelHandel return true; } -} \ No newline at end of file +} diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php index dd48425c..f4d875c0 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php @@ -60,7 +60,7 @@ class BulkDownloadCustomerInvoicesLogic } $filesystemDriver = Storage::getDefaultDriver(); - if($filesystemDriver == 's3'){ + if($filesystemDriver === 's3'){ $startDate = $startDate->format('d-m-Y'); $endDate = $endDate->format('d-m-Y'); $zipFileName = "invoices_{$startDate}_to_{$endDate}_{$company->reference}.zip"; diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php index 61c91d9b..29d2720c 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php @@ -44,7 +44,7 @@ class BulkDownloadSupplierWhiteFormsLogic $filesystemDriver = Storage::getDefaultDriver(); - if($filesystemDriver == 's3'){ + if($filesystemDriver === 's3'){ $startDate = $startDate->format('d-m-Y'); $endDate = $endDate->format('d-m-Y'); diff --git a/app/Classes/Modules/Documents/ControllersLogic/RenderDocumentLogic.php b/app/Classes/Modules/Documents/ControllersLogic/RenderDocumentLogic.php index 0146a2f7..193a7bd2 100644 --- a/app/Classes/Modules/Documents/ControllersLogic/RenderDocumentLogic.php +++ b/app/Classes/Modules/Documents/ControllersLogic/RenderDocumentLogic.php @@ -55,7 +55,7 @@ class RenderDocumentLogic extends AbstractControllerLogic $this->canRenderDocument->passes(); $filesystemDriver = Storage::getDefaultDriver(); - if($filesystemDriver == 's3'){ + if($filesystemDriver === 's3'){ if(!Storage::disk('s3')->exists($file)) { throw new ResourceNotFoundException(); diff --git a/app/Classes/Modules/Documents/Services/ConvertsBase64ToFile.php b/app/Classes/Modules/Documents/Services/ConvertsBase64ToFile.php index dc9c2210..f246fcfa 100644 --- a/app/Classes/Modules/Documents/Services/ConvertsBase64ToFile.php +++ b/app/Classes/Modules/Documents/Services/ConvertsBase64ToFile.php @@ -100,7 +100,7 @@ class ConvertsBase64ToFile private function generateFile(FileObject $file, string $suffix = '') { $filesystemDriver = Storage::getDefaultDriver(); - if($filesystemDriver == 's3'){ + if($filesystemDriver === 's3'){ $filePath = 'documents/'.$this->path.'/'.$file->getFileName().$suffix.'.'.$file->getExtension(); Storage::put($filePath, $file->getDecodedData(), 's3'); return $filePath; diff --git a/app/Http/Controllers/Imports/ImportUpdateDebtorController.php b/app/Http/Controllers/Imports/ImportUpdateDebtorController.php index 1acc7b11..b3d5a534 100644 --- a/app/Http/Controllers/Imports/ImportUpdateDebtorController.php +++ b/app/Http/Controllers/Imports/ImportUpdateDebtorController.php @@ -4,7 +4,6 @@ namespace App\Http\Controllers\Imports; use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject; use App\Classes\Modules\Imports\Services\ImportsDebtor; -use App\Classes\General\ExcelHandel; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Models\User; diff --git a/resources/assets/vue/components/bookings/elements/DownloadSupplierWhiteFormComponent.vue b/resources/assets/vue/components/bookings/elements/DownloadSupplierWhiteFormComponent.vue index 54f1617e..83f6e3f2 100644 --- a/resources/assets/vue/components/bookings/elements/DownloadSupplierWhiteFormComponent.vue +++ b/resources/assets/vue/components/bookings/elements/DownloadSupplierWhiteFormComponent.vue @@ -86,14 +86,12 @@ export default { }, successHandler(response) { this.isLoading = false; - console.log('debug response: ' + JSON.stringify(response)); if (response.message) { this.returnData = response; } else { this.returnData = null; if(window.LARAVEL_VAPOR_ENABLED){ - console.log('window.LARAVEL_VAPOR_ENABLED'); if (response.src) { window.location.href = response.src; } diff --git a/resources/assets/vue/components/companies/elements/BulkDownloadInvoiceComponent.vue b/resources/assets/vue/components/companies/elements/BulkDownloadInvoiceComponent.vue index b8b50998..88cd0d9c 100644 --- a/resources/assets/vue/components/companies/elements/BulkDownloadInvoiceComponent.vue +++ b/resources/assets/vue/components/companies/elements/BulkDownloadInvoiceComponent.vue @@ -88,14 +88,12 @@ }, successHandler(response) { this.isLoading = false; - console.log('debug response: ' + JSON.stringify(response)); if (response.message) { this.returnData = response; } else { this.returnData = null; if(window.LARAVEL_VAPOR_ENABLED){ - console.log('window.LARAVEL_VAPOR_ENABLED'); if (response.src) { window.location.href = response.src; } From caf6228a88cb86a55ac6e04b9705ba5a5b4252d1 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Mon, 29 Apr 2024 15:37:02 +0800 Subject: [PATCH 211/434] Laravel Vapor - sync code for download files in bulk from S3 to more files --- .../Processors/CreateInvoiceDocumentProcessor.php | 9 ++++++++- .../Notifications/PaymentProofUploadedEmail.php | 10 +++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/app/Classes/Modules/Transactions/Processors/CreateInvoiceDocumentProcessor.php b/app/Classes/Modules/Transactions/Processors/CreateInvoiceDocumentProcessor.php index 6215a1e1..2be4a3fb 100644 --- a/app/Classes/Modules/Transactions/Processors/CreateInvoiceDocumentProcessor.php +++ b/app/Classes/Modules/Transactions/Processors/CreateInvoiceDocumentProcessor.php @@ -10,6 +10,7 @@ use App\Classes\ValueObjects\Constants\DocumentType; use App\Models\Document; use Mccarlosen\LaravelMpdf\Facades\LaravelMpdf; use Webklex\PDFMerger\Facades\PDFMergerFacade as PDFMerger; +use Illuminate\Support\Facades\Storage; class CreateInvoiceDocumentProcessor { @@ -52,8 +53,14 @@ class CreateInvoiceDocumentProcessor $order_pdf->save(storage_path('app/documents/temp.pdf')); $oMerger->addPDF(storage_path('app/documents/temp.pdf'), 'all'); + $filesystemDriver = Storage::getDefaultDriver(); foreach ($purchaseOrderDocuments as $document){ - $oMerger->addPDF(storage_path('app/documents/'.$document->files()->first()->file->file_info->original->file), 'all'); + $localFilePath = storage_path('app/documents/' . $document->files()->first()->file->file_info->original->file); + $oMerger->addPDF($localFilePath, 'all'); + if($filesystemDriver === 's3'){ + $filePathForS3 = 'documents/'.$document->files()->first()->file->file_info->original->file; + Storage::disk('s3')->put($filePathForS3, file_get_contents($localFilePath)); + } } $oMerger->merge(); diff --git a/app/Classes/Notifications/PaymentProofUploadedEmail.php b/app/Classes/Notifications/PaymentProofUploadedEmail.php index 1fdc8e14..c2307d76 100644 --- a/app/Classes/Notifications/PaymentProofUploadedEmail.php +++ b/app/Classes/Notifications/PaymentProofUploadedEmail.php @@ -7,6 +7,7 @@ use App\Models\User; use App\Models\File; use App\Models\UserEmailVerification; use Illuminate\Notifications\Messages\MailMessage; +use Illuminate\Support\Facades\Storage; class PaymentProofUploadedEmail extends AbstractEmail { @@ -40,7 +41,14 @@ class PaymentProofUploadedEmail extends AbstractEmail foreach ($file_info as $fileCount => $fileVal) { if (isset($fileVal->original)) { $file_path = $fileVal->original->file; - $attachedFile = storage_path('app/documents/' . $file_path); + + // $filesystemDriver = Storage::getDefaultDriver(); + // if($filesystemDriver === 's3'){ + // $fileContent = Storage::disk('s3')->get('documents/'.$file_path); + // } + // else{ + // $attachedFile = storage_path('app/documents/' . $file_path); + // } } } From faacc26b638ce41e85b2180295af49096d422015 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Mon, 29 Apr 2024 15:37:38 +0800 Subject: [PATCH 212/434] Laravel Vapor - sync code for download files in bulk from S3 to more files --- vapor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vapor.yml b/vapor.yml index 4328e569..a0d31602 100644 --- a/vapor.yml +++ b/vapor.yml @@ -55,7 +55,7 @@ environments: - exchange-default-development - exchange-high_priority-development database: cief-rds-mysql - storage: exchange-2.0-production + storage: exchange-2.0-development runtime: 'docker' timeout: 180 build: From 7655853a6de4b28cbdf3f2751d88a125cbee3af2 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Mon, 29 Apr 2024 21:19:34 +0800 Subject: [PATCH 213/434] -open refund function for all admin (ignore whether the booking has invoice or not) -when refund is before the whiteform, auto approve the transaction --- .../ControllersLogic/CreateBookingRefundLogic.php | 15 +++++++++++++-- .../UpdateRefundTransactionStatusLogic.php | 4 ++-- .../bookings/elements/PaymentHistoryComponent.vue | 2 +- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php index 7e176363..171b4360 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php @@ -14,6 +14,7 @@ use App\Classes\General\Abstracts\AbstractControllerLogic; use App\Classes\Modules\Transactions\Services\CreatesTransaction; use App\Classes\Modules\Transactions\Services\FetchesTransaction; use App\Classes\Modules\Bookings\Services\FetchesBookingQuotation; +use App\Classes\Modules\Transactions\ControllersLogic\UpdateRefundTransactionStatusLogic; use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus; use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject; use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber; @@ -48,6 +49,9 @@ class CreateBookingRefundLogic extends AbstractControllerLogic /** @var CreatesTransaction */ private $createsTransaction; + /** @var UpdateRefundTransactionStatusLogic */ + private $updateRefundTransactionStatusLogic; + /** * CreateBookingPaymentLogic constructor. * @param FetchesBookingQuotation $fetchBookingQuotation @@ -55,14 +59,16 @@ class CreateBookingRefundLogic extends AbstractControllerLogic * @param UpdatesTransactionStatus $updatesTransactionStatus * @param GeneratesTransactionBillNumber $generatesTransactionBillNumber * @param CreatesTransaction $createsTransaction + * @param UpdateRefundTransactionStatusLogic $updateRefundTransactionStatusLogic */ - public function __construct(FetchesBookingQuotation $fetchBookingQuotation, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatesTransaction $createsTransaction) + public function __construct(FetchesBookingQuotation $fetchBookingQuotation, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatesTransaction $createsTransaction, UpdateRefundTransactionStatusLogic $updateRefundTransactionStatusLogic) { $this->fetchBookingQuotation = $fetchBookingQuotation; $this->fetchesTransaction = $fetchesTransaction; $this->updatesTransactionStatus = $updatesTransactionStatus; $this->generatesTransactionBillNumber = $generatesTransactionBillNumber; $this->createsTransaction = $createsTransaction; + $this->updateRefundTransactionStatusLogic = $updateRefundTransactionStatusLogic; } /** @@ -79,7 +85,7 @@ class CreateBookingRefundLogic extends AbstractControllerLogic $invoice = $booking->transactions()->where('type', TransactionType::INVOICE)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->first(); - if(auth()->user()->type === 3 || ($invoice && !(auth()->user()->type === 0 || auth()->user()->type === 1))) { + if(auth()->user()->type === 3) { throw new MalformedRequestException('You do not have the permission to refund the order.'); } @@ -119,6 +125,11 @@ class CreateBookingRefundLogic extends AbstractControllerLogic 0, 0, null, ApprovalStatus::PENDING_VERIFICATION, [], $transaction->bill_no); $transaction = $this->createsTransaction->execute($transaction, $object); + } else { + $request->route()->setParameter('id', $refund_transaction->id); + $request->route()->setParameter('status', ApprovalStatus::APPROVED); + $this->updateRefundTransactionStatusLogic->execute($request); + } return $this->resourceResponse(new TransactionResource($refund_transaction)); diff --git a/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php index d2fa5ec6..cc98847a 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php @@ -86,8 +86,8 @@ class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic */ public function logic(Request $request) : JsonResponse { - if (!(Auth::user()->type === 0 || Auth::user()->type === 1)) { - throw new MalformedRequestException('Only super admin can update refund status.'); + if(auth()->user()->type === 3) { + throw new MalformedRequestException('You do not have the permission to refund the order.'); } $refundTransaction = $this->fetchesTransaction->execute(['id' => $request->route('id')]); diff --git a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue index ec0c0d7a..7679b807 100644 --- a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue +++ b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue @@ -290,7 +290,7 @@
-
+
From e7357fd9da2d2391af196f69bf9c96720e5be56e Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Tue, 30 Apr 2024 11:25:07 +0800 Subject: [PATCH 214/434] Laravel Vapor - sync code for download files in bulk from S3 to more files --- .../DownloadBookingDocumentLogic.php | 160 ++++++++++++------ .../BulkDownloadCustomerInvoicesLogic.php | 4 +- .../BulkDownloadSupplierWhiteFormsLogic.php | 2 +- 3 files changed, 108 insertions(+), 58 deletions(-) diff --git a/app/Classes/Modules/Bookings/ControllersLogic/DownloadBookingDocumentLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/DownloadBookingDocumentLogic.php index ff9427fe..561357b6 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/DownloadBookingDocumentLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/DownloadBookingDocumentLogic.php @@ -15,6 +15,7 @@ use Illuminate\Support\Facades\Storage; use App\Classes\Exceptions\MalformedRequestException; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\DocumentType; +use Illuminate\Support\Facades\Log; class DownloadBookingDocumentLogic { @@ -32,71 +33,120 @@ class DownloadBookingDocumentLogic $zip_file = $document_type.'.zip'; $attachment = storage_path().'/app/documents/collections/' . $zip_file; - $zip = new ZipArchive(); - if ($zip->open($attachment, ZIPARCHIVE::CREATE | ZipArchive::OVERWRITE)) { + $bookings = Booking::where('status', ApprovalStatus::COMPLETED) + ->whereDate('created_at', '>=', Carbon::parse($request->input('startDate'))) + ->whereDate('created_at', '<=', Carbon::parse($request->input('endDate'))) + ->whereHas('transactions', function ($query) use ($request){ + return $query->where('type', TransactionType::PAYMENT)->whereHas('transactions', function ($query) use ($request){ + return $query->where('type', TransactionType::BILL)->where('issuer', $request->input('supplier')); + }); + })->get(); - $bookings = Booking::where('status', ApprovalStatus::COMPLETED) - ->whereDate('created_at', '>=', Carbon::parse($request->input('startDate'))) - ->whereDate('created_at', '<=', Carbon::parse($request->input('endDate'))) - ->whereHas('transactions', function ($query) use ($request){ - return $query->where('type', TransactionType::PAYMENT)->whereHas('transactions', function ($query) use ($request){ - return $query->where('type', TransactionType::BILL)->where('issuer', $request->input('supplier')); - }); - })->get(); + if (!count($bookings)) { + return response()->json(['no file to download']); + } + $filesystemDriver = Storage::getDefaultDriver(); + if($filesystemDriver === 's3'){ + $zip = new ZipArchive(); + if ($zip->open($attachment, ZIPARCHIVE::CREATE | ZipArchive::OVERWRITE)) { + foreach ($bookings as $booking) { - if (!count($bookings)) { - return response()->json(['no file to download']); - } + if ($document_type == 'INVOICEPODO' || $document_type == 'INVOICEPODOSDO') { + $invoice_file = $booking->documents()->where('document_type', DocumentType::INVOICE)->first()->files()->first(); + $purchase_file = $booking->documents()->where('document_type', DocumentType::PURCHASE_ORDER)->first()->files()->first(); + $deliver_file = $booking->documents()->where('document_type', DocumentType::DELIVER_ORDER)->first()->files()->first(); + if ($document_type == 'INVOICEPODOSDO') { + $supplier_deliver_order_file = $booking->documents()->where('document_type', DocumentType::SUPPLIER_DELIVER_ORDER)->first()->files()->first(); + } + $fileContent = Storage::disk('s3')->get('documents/'.$invoice_file->file->file_info->original->file); + $zip->addFromString('invoice-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf', $fileContent); - foreach ($bookings as $booking) { + $fileContent = Storage::disk('s3')->get('documents/'.$purchase_file->file->file_info->original->file); + $zip->addFromString('purchase-order-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf', $fileContent); - if ($document_type == 'INVOICEPODO' || $document_type == 'INVOICEPODOSDO') { - $invoice_file = $booking->documents()->where('document_type', DocumentType::INVOICE)->first()->files()->first(); - $purchase_file = $booking->documents()->where('document_type', DocumentType::PURCHASE_ORDER)->first()->files()->first(); - $deliver_file = $booking->documents()->where('document_type', DocumentType::DELIVER_ORDER)->first()->files()->first(); - if ($document_type == 'INVOICEPODOSDO') { - $supplier_deliver_order_file = $booking->documents()->where('document_type', DocumentType::SUPPLIER_DELIVER_ORDER)->first()->files()->first(); + $fileContent = Storage::disk('s3')->get('documents/'.$deliver_file->file->file_info->original->file); + $zip->addFromString('deliver-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf', $fileContent); + + $fileContent = Storage::disk('s3')->get('documents/'.$supplier_deliver_order_file->file->file_info->original->file); + $zip->addFromString('supplier-deliver-order-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf', $fileContent); + } + else { + $file = $booking->documents()->where('document_type', $document_type)->first()->files()->first(); + $fileContent = Storage::disk('s3')->get('documents/'.$file->file->file_info->original->file); + $zip->addFromString($booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf', $fileContent); } - $zip->addFile(Storage::disk('documents')->path($invoice_file->file->file_info->original->file), 'invoice-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf'); - - $zip->addFile(Storage::disk('documents')->path($purchase_file->file->file_info->original->file), 'purchase-order-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf'); - - $zip->addFile(Storage::disk('documents')->path($deliver_file->file->file_info->original->file), 'deliver-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf'); - - $zip->addFile(Storage::disk('documents')->path($supplier_deliver_order_file->file->file_info->original->file), 'supplier-deliver-order-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf'); - } - else { - $file = $booking->documents()->where('document_type', $document_type)->first()->files()->first(); - $zip->addFile(Storage::disk('documents')->path($file->file->file_info->original->file), $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf'); } + $zip->close(); + $filePathForS3 = 'collections/'.$zip_file; + Storage::disk('s3')->put($filePathForS3, file_get_contents($attachment)); + + Log::info('DownloadBookingDocumentLogic finished processing files to zip count: '.count($bookings)); + + $temporaryUrl = Storage::disk('s3')->temporaryUrl( + $filePathForS3, + Carbon::now()->addMinutes(10) + ); + + return response(['src' => $temporaryUrl ]); } - $zip->close(); - while (ob_get_level()) { - ob_end_clean(); - } - ob_start(); - header($_SERVER['SERVER_PROTOCOL'] . ' 200 OK'); - header("Content-Type: application/zip"); - header("Content-Transfer-Encoding: Binary"); - header("Content-Length: " . filesize($attachment)); - header('Pragma: no-cache'); - header("Content-Disposition: attachment; filename=\"" . basename($attachment) . "\""); - ob_flush(); - ob_clean(); - - readfile($attachment); - File::delete($attachment); - - exit; - -// header('Content-Type: application/zip'); -// header('Content-Length: ' . filesize($attachment)); -// readfile($attachment); -// unlink($attachment); - } + else{ + $zip = new ZipArchive(); + if ($zip->open($attachment, ZIPARCHIVE::CREATE | ZipArchive::OVERWRITE)) { + + foreach ($bookings as $booking) { + + if ($document_type == 'INVOICEPODO' || $document_type == 'INVOICEPODOSDO') { + $invoice_file = $booking->documents()->where('document_type', DocumentType::INVOICE)->first()->files()->first(); + $purchase_file = $booking->documents()->where('document_type', DocumentType::PURCHASE_ORDER)->first()->files()->first(); + $deliver_file = $booking->documents()->where('document_type', DocumentType::DELIVER_ORDER)->first()->files()->first(); + if ($document_type == 'INVOICEPODOSDO') { + $supplier_deliver_order_file = $booking->documents()->where('document_type', DocumentType::SUPPLIER_DELIVER_ORDER)->first()->files()->first(); + } + + $zip->addFile(Storage::disk('documents')->path($invoice_file->file->file_info->original->file), 'invoice-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf'); + + $zip->addFile(Storage::disk('documents')->path($purchase_file->file->file_info->original->file), 'purchase-order-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf'); + + $zip->addFile(Storage::disk('documents')->path($deliver_file->file->file_info->original->file), 'deliver-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf'); + + $zip->addFile(Storage::disk('documents')->path($supplier_deliver_order_file->file->file_info->original->file), 'supplier-deliver-order-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf'); + } + else { + $file = $booking->documents()->where('document_type', $document_type)->first()->files()->first(); + $zip->addFile(Storage::disk('documents')->path($file->file->file_info->original->file), $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf'); + } + + } + $zip->close(); + while (ob_get_level()) { + ob_end_clean(); + } + ob_start(); + header($_SERVER['SERVER_PROTOCOL'] . ' 200 OK'); + header("Content-Type: application/zip"); + header("Content-Transfer-Encoding: Binary"); + header("Content-Length: " . filesize($attachment)); + header('Pragma: no-cache'); + header("Content-Disposition: attachment; filename=\"" . basename($attachment) . "\""); + ob_flush(); + ob_clean(); + + readfile($attachment); + File::delete($attachment); + + exit; + + //header('Content-Type: application/zip'); + //header('Content-Length: ' . filesize($attachment)); + //readfile($attachment); + //unlink($attachment); + + } + } + } } diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php index f4d875c0..faca4dcd 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php @@ -75,10 +75,10 @@ class BulkDownloadCustomerInvoicesLogic } $zip->close(); - $filePathForS3 = 'bulk_whiteform/'.$zipFileName; + $filePathForS3 = 'bulk_invoice/'.$zipFileName; Storage::disk('s3')->put($filePathForS3, file_get_contents($zip_file)); - Log::info('BulkDownloadCustomerInvoicesLogic finished processing files count: '.count($invoicebookings)); + Log::info('BulkDownloadCustomerInvoicesLogic finished processing files to zip count: '.count($invoicebookings)); $temporaryUrl = Storage::disk('s3')->temporaryUrl( $filePathForS3, diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php index 29d2720c..ae1c035e 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadSupplierWhiteFormsLogic.php @@ -71,7 +71,7 @@ class BulkDownloadSupplierWhiteFormsLogic $filePathForS3 = 'bulk_whiteform/'.$zipFileName; Storage::disk('s3')->put($filePathForS3, file_get_contents($zip_file)); - Log::info('BulkDownloadSupplierWhiteFormsLogic finished processing files count: '.count($groups)); + Log::info('BulkDownloadSupplierWhiteFormsLogic finished processing files to zip count: '.count($groups)); $temporaryUrl = Storage::disk('s3')->temporaryUrl( $filePathForS3, From 2c9c5d49ed94ba401df633b71c294d6debd257f8 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Tue, 30 Apr 2024 11:26:59 +0800 Subject: [PATCH 215/434] Laravel Vapor - sync code for download files in bulk from S3 to more files --- vapor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vapor.yml b/vapor.yml index a0d31602..4328e569 100644 --- a/vapor.yml +++ b/vapor.yml @@ -55,7 +55,7 @@ environments: - exchange-default-development - exchange-high_priority-development database: cief-rds-mysql - storage: exchange-2.0-development + storage: exchange-2.0-production runtime: 'docker' timeout: 180 build: From 78fbd66a53cd4b09dda35d91527bdc685363f036 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Tue, 30 Apr 2024 12:15:16 +0800 Subject: [PATCH 216/434] Laravel Vapor - sync code for download files in bulk from S3 to more files --- app/Classes/General/ExcelHandel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Classes/General/ExcelHandel.php b/app/Classes/General/ExcelHandel.php index 31034ff8..cc476b0d 100644 --- a/app/Classes/General/ExcelHandel.php +++ b/app/Classes/General/ExcelHandel.php @@ -72,13 +72,13 @@ class ExcelHandel if($filesystemDriver === 's3'){ $filePathForS3 = 'public/excels/' . $path . '/' . $filename . '.' . $extension; Storage::disk('s3')->put($filePathForS3, $exceldata); + $file_info['original']['file'] = Storage::disk('s3')->path($filePathForS3); } else{ $file = Storage::disk('public')->put('excels/' . $path . '/' . $filename . '.' . $extension, $exceldata); + $file_info['original']['file'] = storage_path('app/public/excels/' . $path . '/' . $filename . '.' . $extension); } - $file_info['original']['file'] = storage_path('app/public/excels/' . $path . '/' . $filename . '.' . $extension); - return $file_info; } From 608297c77c4b4b72bc3897fe063c5be7afdc7d5d Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Tue, 30 Apr 2024 13:07:25 +0800 Subject: [PATCH 217/434] Laravel Vapor - sync code for download files in bulk from S3 to more files --- .../Imports/ImportUpdateDebtorController.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Imports/ImportUpdateDebtorController.php b/app/Http/Controllers/Imports/ImportUpdateDebtorController.php index b3d5a534..77ed1e92 100644 --- a/app/Http/Controllers/Imports/ImportUpdateDebtorController.php +++ b/app/Http/Controllers/Imports/ImportUpdateDebtorController.php @@ -13,6 +13,7 @@ use Illuminate\Support\Facades\Auth; use Illuminate\Support\Str; use Maatwebsite\Excel\Facades\Excel; use Maatwebsite\Excel\Excel as ExcelFileTypes; +use Illuminate\Support\Facades\Storage; class ImportUpdateDebtorController { @@ -23,7 +24,18 @@ class ImportUpdateDebtorController */ public function import(Request $request) { $object = new DocumentObject('', $request->input('files'), '', ApprovalStatus::APPROVED, 'imports'); - Excel::import(new ImportsDebtor(), json_decode($object->getFiles()[0])->file_info->original->file); + $file = json_decode($object->getFiles()[0])->file_info->original->file; + + $filesystemDriver = Storage::getDefaultDriver(); + if($filesystemDriver === 's3'){ + $file = Storage::disk('s3')->path('documents/' . $file); + } + //Shipping Portal requires the following (NOT TESTED) + // else{ + // $file = 'documents/' . $file; + // } + + Excel::import(new ImportsDebtor(), $file); return []; } } From 0fd70fde1b90c15196aca0b06ad6b07cbae6fffa Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Tue, 30 Apr 2024 14:31:56 +0800 Subject: [PATCH 218/434] Laravel Vapor - sync code for download files in bulk from S3 to more files --- .../Commands/V2/EmailDoToVTV2CommandJob.php | 96 +++++++++++++------ .../bookings/elements/BillingComponent.vue | 22 ++++- 2 files changed, 86 insertions(+), 32 deletions(-) diff --git a/app/Classes/Jobs/Commands/V2/EmailDoToVTV2CommandJob.php b/app/Classes/Jobs/Commands/V2/EmailDoToVTV2CommandJob.php index 555f1f56..2c4bf7d1 100644 --- a/app/Classes/Jobs/Commands/V2/EmailDoToVTV2CommandJob.php +++ b/app/Classes/Jobs/Commands/V2/EmailDoToVTV2CommandJob.php @@ -37,38 +37,80 @@ class EmailDoToVTV2CommandJob implements ShouldQueue $startDate = Carbon::yesterday(); $endDate = Carbon::yesterday(); - $zip = new ZipArchive(); - if ($zip->open($attachment, ZIPARCHIVE::CREATE | ZipArchive::OVERWRITE)) { + $bookings = \App\Models\Booking::where('status', ApprovalStatus::COMPLETED)->whereDate('updated_at', '>=', $startDate)->whereDate('updated_at', '<=', $endDate) + ->whereHas('transactions', function ($query){ + return $query->where('type', TransactionType::PAYMENT)->whereHas('transactions', function ($query){ + return $query->where('issuer', 2); + }); + })->get(); - $bookings = \App\Models\Booking::where('status', ApprovalStatus::COMPLETED)->whereDate('updated_at', '>=', $startDate)->whereDate('updated_at', '<=', $endDate) - ->whereHas('transactions', function ($query){ - return $query->where('type', TransactionType::PAYMENT)->whereHas('transactions', function ($query){ - return $query->where('issuer', 2); - }); - })->get(); + if(!count($bookings)){ return; } - if(!count($bookings)){ return; } + $filesystemDriver = Storage::getDefaultDriver(); + if($filesystemDriver === 's3'){ + $zip = new ZipArchive(); + if ($zip->open($attachment, ZIPARCHIVE::CREATE | ZipArchive::OVERWRITE)) { + //STEP 1: Go through each of the booking from query + foreach ($bookings as $booking) { + $file = $booking->documents()->where('document_type', DocumentType::SUPPLIER_DELIVER_ORDER)->first()->files()->first(); + $fileContent = Storage::disk('s3')->get('documents/'.$file->file->file_info->original->file); + $zip->addFromString($booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf', $fileContent); + } - foreach ($bookings as $booking) { - $file = $booking->documents()->where('document_type', DocumentType::SUPPLIER_DELIVER_ORDER)->first()->files()->first(); - $zip->addFile(Storage::disk('documents')->path($file->file->file_info->original->file), $booking->created_at->format('d_m_Y').'_'.$booking->marking.'.pdf'); + $zip->close(); + + //STEP 2: Upload the zip file to S3 + $filePathForS3 = 'collections/'.$zip_file; + Storage::disk('s3')->put($filePathForS3, file_get_contents($attachment)); + + Log::info('DownloadBookingDocumentLogic finished processing files to zip count: '.count($bookings)); + + $temporaryUrl = Storage::disk('s3')->temporaryUrl( + $filePathForS3, + Carbon::now()->addMinutes(10) + ); + + //STEP 3: Send Email + Mail::raw( "Attention to VT Admin team:\r\n\r\nKindly refer to the attachment for our DAILY DO COMPILATION ".$startDate->format('d-m-Y')." - ".$endDate->format('d-m-Y').".\r\n\r\n**This is an automatically generated email – please do not reply to it. If you have any queries kindly contact our admin team through Wechat.\r\n\r\n\r\nCIEF WORLDWIDE SDN BHD", function($message) use ($attachment, $startDate, $endDate){ + $message->from('exchange@cief-malaysia.com'); + $message->to(['vtnation16@gmail.com', 'vtnation@gmail.com', 'atvantic04@gmail.com', 'vtnation2@gmail.com']); + $message->cc(['shafiqa_sukeri@cief-malaysia.com', 'frontendcief@gmail.com', 'pm@cief-malaysia.com', 'hasan@cief-malaysia.com', 'shipping_admin@cief-malaysia.com', 'hasanakbar27@gmail.com', 'pmwong2019@gmail.com', 'uldvstar@gmail.com']); + $message->subject('CIEF DO COMPILATION '.$startDate->format('d-m-Y').' - '.$endDate->format('d-m-Y')); + + $message->attach($attachment); + }); + + File::delete($attachment); + Log::info('success'); + + //STEP 4. No Response needed because this is a job + //return response(['src' => $temporaryUrl ]); + } + } + else{ + $zip = new ZipArchive(); + if ($zip->open($attachment, ZIPARCHIVE::CREATE | ZipArchive::OVERWRITE)) { + + foreach ($bookings as $booking) { + $file = $booking->documents()->where('document_type', DocumentType::SUPPLIER_DELIVER_ORDER)->first()->files()->first(); + $zip->addFile(Storage::disk('documents')->path($file->file->file_info->original->file), $booking->created_at->format('d_m_Y').'_'.$booking->marking.'.pdf'); + } + + $zip->close(); + + Mail::raw( "Attention to VT Admin team:\r\n\r\nKindly refer to the attachment for our DAILY DO COMPILATION ".$startDate->format('d-m-Y')." - ".$endDate->format('d-m-Y').".\r\n\r\n**This is an automatically generated email – please do not reply to it. If you have any queries kindly contact our admin team through Wechat.\r\n\r\n\r\nCIEF WORLDWIDE SDN BHD", function($message) use ($attachment, $startDate, $endDate){ + $message->from('exchange@cief-malaysia.com'); + $message->to(['vtnation16@gmail.com', 'vtnation@gmail.com', 'atvantic04@gmail.com', 'vtnation2@gmail.com']); + $message->cc(['shafiqa_sukeri@cief-malaysia.com', 'frontendcief@gmail.com', 'pm@cief-malaysia.com', 'hasan@cief-malaysia.com', 'shipping_admin@cief-malaysia.com', 'hasanakbar27@gmail.com', 'pmwong2019@gmail.com', 'uldvstar@gmail.com']); + $message->subject('CIEF DO COMPILATION '.$startDate->format('d-m-Y').' - '.$endDate->format('d-m-Y')); + + $message->attach($attachment); + }); + + File::delete($attachment); + Log::info('success'); } - - $zip->close(); - - Mail::raw( "Attention to VT Admin team:\r\n\r\nKindly refer to the attachment for our DAILY DO COMPILATION ".$startDate->format('d-m-Y')." - ".$endDate->format('d-m-Y').".\r\n\r\n**This is an automatically generated email – please do not reply to it. If you have any queries kindly contact our admin team through Wechat.\r\n\r\n\r\nCIEF WORLDWIDE SDN BHD", function($message) use ($attachment, $startDate, $endDate){ - $message->from('exchange@cief-malaysia.com'); - $message->to(['vtnation16@gmail.com', 'vtnation@gmail.com', 'atvantic04@gmail.com', 'vtnation2@gmail.com']); - $message->cc(['shafiqa_sukeri@cief-malaysia.com', 'frontendcief@gmail.com', 'pm@cief-malaysia.com', 'hasan@cief-malaysia.com', 'shipping_admin@cief-malaysia.com', 'hasanakbar27@gmail.com', 'pmwong2019@gmail.com', 'uldvstar@gmail.com']); - $message->subject('CIEF DO COMPILATION '.$startDate->format('d-m-Y').' - '.$endDate->format('d-m-Y')); - - $message->attach($attachment); - }); - - File::delete($attachment); - Log::info('success'); - } $end = new Carbon(); diff --git a/resources/assets/vue/components/bookings/elements/BillingComponent.vue b/resources/assets/vue/components/bookings/elements/BillingComponent.vue index f24078ed..ba1ce85c 100644 --- a/resources/assets/vue/components/bookings/elements/BillingComponent.vue +++ b/resources/assets/vue/components/bookings/elements/BillingComponent.vue @@ -85,9 +85,9 @@ export default { supplier: null }, documents: [ - 'INVOICE', - 'PURCHASE_ORDER', - 'DELIVER_ORDER', + 'INVOICE', + 'PURCHASE_ORDER', + 'DELIVER_ORDER', 'SUPPLIER_DELIVER_ORDER', 'INVOICE + PO + DO', 'INVOICE + PO + DO + SDO' @@ -112,12 +112,24 @@ export default { methods: { submitSearch(){ if(!this.validate()){ return; } - window.open(route('documents.download')+'?type='+this.parameters.type+'&startDate='+this.parameters.startDate+'&endDate='+this.parameters.endDate+'&supplier='+this.parameters.supplier, '_blank'); + if(window.LARAVEL_VAPOR_ENABLED){ + this.submit(this.route('documents.download')+'?type='+this.parameters.type+'&startDate='+this.parameters.startDate+'&endDate='+this.parameters.endDate+'&supplier='+this.parameters.supplier, 'get', this.section, false, false); + } + else{ + window.open(route('documents.download')+'?type='+this.parameters.type+'&startDate='+this.parameters.startDate+'&endDate='+this.parameters.endDate+'&supplier='+this.parameters.supplier, '_blank'); + } }, updateDocumentType(documentType) { this.parameters.type = documentType; this.selectedDocumentStatus = !this.selectedDocumentStatus - } + }, + successHandler(response) { + if(window.LARAVEL_VAPOR_ENABLED){ + if (response.src) { + window.location.href = response.src; + } + } + }, }, mixins: [componentHandler] }; From b528ac66fcdff4a0e02debe14c7a29451b0cc54e Mon Sep 17 00:00:00 2001 From: Omair Saleh Date: Tue, 30 Apr 2024 17:46:25 +0800 Subject: [PATCH 219/434] update estimated delivery date for E2E --- .../Services/GeneratesBookingQuotation.php | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/app/Classes/Modules/Bookings/Services/GeneratesBookingQuotation.php b/app/Classes/Modules/Bookings/Services/GeneratesBookingQuotation.php index 8ea1b88d..3a0b1536 100644 --- a/app/Classes/Modules/Bookings/Services/GeneratesBookingQuotation.php +++ b/app/Classes/Modules/Bookings/Services/GeneratesBookingQuotation.php @@ -19,7 +19,31 @@ class GeneratesBookingQuotation $hours = $date->diffInHours($date->copy()->addMinutes($paymentAttemptLimit)->subDays($days)) ; $minutes = $date->diffInMinutes($date->copy()->addMinutes($paymentAttemptLimit)->subDays($days)->subHours($hours)); - $receive_date = $currencyConversionObject ? Carbon::now()->endOfDay()->addWeekdays($currencyConversionObject->getServiceId() === 3 ? 3 : 1)->timezone('Asia/Singapore')->format('4:00 \P\M, jS M, Y \G\M\T T') : null; + // Initialize $receive_date to null by default + $receive_date = null; + + if ($currencyConversionObject) { + $serviceId = $currencyConversionObject->getServiceId(); + + switch ($serviceId) { + case 3: + $daysToAdd = 3; + break; + case 5: + $daysToAdd = 7; + break; + default: + $daysToAdd = 1; + break; + } + + $receive_date = Carbon::now() + ->endOfDay() + ->addWeekdays($daysToAdd) + ->timezone('Asia/Singapore') + ->format('4:00 PM, jS M, Y GMT T'); + } + return [ 'bank' => new BankResource(Bank::find($calculationObject->getConfigurations()->getBankId())), From f57b1e625f001e8fc9a00a2f1b4547643742398e Mon Sep 17 00:00:00 2001 From: Omair Saleh Date: Tue, 30 Apr 2024 17:49:30 +0800 Subject: [PATCH 220/434] update estimated delivery date for E2E --- .../Modules/Bookings/Services/GeneratesBookingQuotation.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Classes/Modules/Bookings/Services/GeneratesBookingQuotation.php b/app/Classes/Modules/Bookings/Services/GeneratesBookingQuotation.php index 3a0b1536..5c1ecdd9 100644 --- a/app/Classes/Modules/Bookings/Services/GeneratesBookingQuotation.php +++ b/app/Classes/Modules/Bookings/Services/GeneratesBookingQuotation.php @@ -41,7 +41,7 @@ class GeneratesBookingQuotation ->endOfDay() ->addWeekdays($daysToAdd) ->timezone('Asia/Singapore') - ->format('4:00 PM, jS M, Y GMT T'); + ->format('4:00 \P\M, jS M, Y \G\M\T T'); } From dec26e53fa631bc37d49780fc0d629db5dd0d945 Mon Sep 17 00:00:00 2001 From: Dillon Ngo Date: Wed, 1 May 2024 11:26:32 +0800 Subject: [PATCH 221/434] Laravel Vapor - sync code for download files in bulk from S3 to more files --- vapor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vapor.yml b/vapor.yml index 4328e569..a0d31602 100644 --- a/vapor.yml +++ b/vapor.yml @@ -55,7 +55,7 @@ environments: - exchange-default-development - exchange-high_priority-development database: cief-rds-mysql - storage: exchange-2.0-production + storage: exchange-2.0-development runtime: 'docker' timeout: 180 build: From 76e76e077ac97bbc6a097c89b878b691fee63ddf Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Mon, 6 May 2024 17:20:01 +0800 Subject: [PATCH 222/434] edit transfer fee functionality for individual whiteform --- .../UpdateGroupTransferFeeLogic.php | 82 +++++++++++++++++++ .../Services/CreatesTransaction.php | 7 +- .../UpdateGroupTransferFeeController.php | 20 +++++ app/Http/Resources/GroupResource.php | 8 ++ app/Models/Group.php | 8 ++ .../bookings/elements/BillGroupComponent.vue | 6 ++ .../elements/EditTransferFeeFormComponent.vue | 79 ++++++++++++++++++ .../TransactionGroupPaymentComponent.vue | 18 ++++ routes/transaction.php | 1 + 9 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 app/Classes/Modules/Transactions/ControllersLogic/UpdateGroupTransferFeeLogic.php create mode 100644 app/Http/Controllers/Transactions/UpdateGroupTransferFeeController.php create mode 100644 resources/assets/vue/components/bookings/elements/EditTransferFeeFormComponent.vue diff --git a/app/Classes/Modules/Transactions/ControllersLogic/UpdateGroupTransferFeeLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/UpdateGroupTransferFeeLogic.php new file mode 100644 index 00000000..2864eb73 --- /dev/null +++ b/app/Classes/Modules/Transactions/ControllersLogic/UpdateGroupTransferFeeLogic.php @@ -0,0 +1,82 @@ + 'Update Group Transfer Fee', + 'message' => 'You have successfully updated transfer fee for this Group Transaction' + ]; + } + + /** @var FetchesGroup */ + private $fetchesGroup; + + /** @var CreatesTransaction */ + private $createsTransaction; + + /** @var GeneratesTransactionBillNumber */ + private $generatesTransactionBillNumber; + + /** + * UpdateGroupTransferFeeLogic constructor. + * @param FetchesGroup $fetchesGroup + * @param CreatesTransaction $createsTransaction + * @param GeneratesTransactionBillNumber $generatesTransactionBillNumber + */ + public function __construct(FetchesGroup $fetchesGroup, CreatesTransaction $createsTransaction, GeneratesTransactionBillNumber $generatesTransactionBillNumber) + { + $this->fetchesGroup = $fetchesGroup; + $this->createsTransaction = $createsTransaction; + $this->generatesTransactionBillNumber = $generatesTransactionBillNumber; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\MalformedRequestException + */ + public function logic(Request $request) : JsonResponse + { + $group = $this->fetchesGroup->execute(['id' => $request->route('id')]); + $supplier = $group->issuerCompany; + $fee = $request->input('fee'); + + $transfer_fee = $group->morphTransactions()->where('type', TransactionType::TRANSFER_FEE)->first(); + + if ($transfer_fee) { + $transfer_fee->amount = $fee; + $transfer_fee->original_amount = $fee; + $transfer_fee->save(); + } else { + $transferFeeNumber = $this->generatesTransactionBillNumber->execute('TRFR-'); + $object = new TransactionObject($transferFeeNumber, TransactionType::TRANSFER_FEE, 1, $supplier->id, + $supplier->banks()->where('default', true)->first()->id, PaymentMethodType::CASH, + $fee, $fee, $group->original_currency_id, $group->original_currency_id, + 1, 0, 0, null, ApprovalStatus::APPROVED); + + $this->createsTransaction->execute($group, $object); + } + + return $this->resourceResponse(new GroupResource($group)); + } + +} diff --git a/app/Classes/Modules/Transactions/Services/CreatesTransaction.php b/app/Classes/Modules/Transactions/Services/CreatesTransaction.php index 06530564..b545c5ed 100644 --- a/app/Classes/Modules/Transactions/Services/CreatesTransaction.php +++ b/app/Classes/Modules/Transactions/Services/CreatesTransaction.php @@ -5,6 +5,7 @@ namespace App\Classes\Modules\Transactions\Services; use App\Classes\General\Eloquent\AbstractUpdateRelationshipRecord; use App\Classes\General\Interfaces\Transactionable; use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject; +use App\Models\Group; use App\Models\Transaction; class CreatesTransaction extends AbstractUpdateRelationshipRecord @@ -15,7 +16,7 @@ class CreatesTransaction extends AbstractUpdateRelationshipRecord * @return \Illuminate\Database\Eloquent\Model * @throws \App\Classes\Exceptions\MalformedRequestException */ - public function execute(Transactionable $transactionable, TransactionObject $object) { + public function execute(Transactionable|Group $transactionable, TransactionObject $object) { $model = new Transaction(); $model->bill_no = $object->getBillNo(); $model->type = $object->getTransactionType(); @@ -34,6 +35,10 @@ class CreatesTransaction extends AbstractUpdateRelationshipRecord $model->status = $object->getStatus(); $model->payment_reference = $object->getPaymentReference(); + if ($transactionable instanceof Group) { + return $this->handler($transactionable->morphTransactions(), $model); + } + return $this->handler($transactionable->transactions(), $model); } diff --git a/app/Http/Controllers/Transactions/UpdateGroupTransferFeeController.php b/app/Http/Controllers/Transactions/UpdateGroupTransferFeeController.php new file mode 100644 index 00000000..948dff39 --- /dev/null +++ b/app/Http/Controllers/Transactions/UpdateGroupTransferFeeController.php @@ -0,0 +1,20 @@ +execute($request); + } +} diff --git a/app/Http/Resources/GroupResource.php b/app/Http/Resources/GroupResource.php index abd017ec..fdddd195 100644 --- a/app/Http/Resources/GroupResource.php +++ b/app/Http/Resources/GroupResource.php @@ -21,6 +21,13 @@ class GroupResource extends JsonResource */ public function toArray($request) { + $transfer_fee = $this->morphTransactions()->where('type', TransactionType::TRANSFER_FEE)->first(); + + if ($transfer_fee) { + $transfer_fee = (float) $transfer_fee->amount; + } else { + $transfer_fee = 0; + } if(!$this->issuerCompany){ dd($this->id); @@ -36,6 +43,7 @@ class GroupResource extends JsonResource 'currency' => new CurrencyResource($this->currency), 'created_at' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A'), 'currency_rate' => (float) $this->currency_rate, + 'transfer_fee' => $transfer_fee, 'transactions' => $this->transactions()->get()->pluck('owner.owner.marking'), 'complete_transactions' => $this->transactions()->whereHasMorph('owner', [Transaction::class], function($query){ return $query->whereHas('booking', function($query){ diff --git a/app/Models/Group.php b/app/Models/Group.php index 8cb6cd8a..2b8cceae 100644 --- a/app/Models/Group.php +++ b/app/Models/Group.php @@ -21,6 +21,14 @@ class Group extends Model implements Documentable return $this->belongsToMany(Transaction::class, GroupTransaction::class); } + /** + * @return MorphMany + */ + public function morphTransactions(): MorphMany + { + return $this->MorphMany(Transaction::class, 'owner'); + } + /** * @return MorphMany */ diff --git a/resources/assets/vue/components/bookings/elements/BillGroupComponent.vue b/resources/assets/vue/components/bookings/elements/BillGroupComponent.vue index e93eb1ad..9a309cde 100644 --- a/resources/assets/vue/components/bookings/elements/BillGroupComponent.vue +++ b/resources/assets/vue/components/bookings/elements/BillGroupComponent.vue @@ -216,6 +216,12 @@ {{ group.currency.short_code }} {{formatAmount(group.amount)}}
+
+
Transfer Fee
+
+ {{ group.original_currency.short_code }} {{formatAmount(group.transfer_fee)}} +
+
PO Completion
diff --git a/resources/assets/vue/components/bookings/elements/EditTransferFeeFormComponent.vue b/resources/assets/vue/components/bookings/elements/EditTransferFeeFormComponent.vue new file mode 100644 index 00000000..93b01124 --- /dev/null +++ b/resources/assets/vue/components/bookings/elements/EditTransferFeeFormComponent.vue @@ -0,0 +1,79 @@ + + diff --git a/resources/assets/vue/components/bookings/elements/TransactionGroupPaymentComponent.vue b/resources/assets/vue/components/bookings/elements/TransactionGroupPaymentComponent.vue index 7fdd579f..2696ceb5 100644 --- a/resources/assets/vue/components/bookings/elements/TransactionGroupPaymentComponent.vue +++ b/resources/assets/vue/components/bookings/elements/TransactionGroupPaymentComponent.vue @@ -36,6 +36,12 @@ {{item.original_currency.short_code}} {{(Math.round((item.original_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
+
+
Transfer Fee
+
+ {{item.original_currency.short_code}} {{(Math.round((item.transfer_fee + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}} +
+
Amount
@@ -75,6 +81,18 @@
+
+
+
+ + + + +
+
+
diff --git a/routes/transaction.php b/routes/transaction.php index d20d160d..654b3fb8 100644 --- a/routes/transaction.php +++ b/routes/transaction.php @@ -32,6 +32,7 @@ Route::group(['prefix' => 'transactions', 'namespace' => 'Transactions', 'as' => Route::get('/list', 'ListGroupsController@list')->name('list'); Route::delete('/{id}/delete', 'DeleteGroupController@delete')->name('delete'); Route::put('/{id}/update', 'UpdateGroupController@update')->name('update'); + Route::put('/{id}/update/fee', 'UpdateGroupTransferFeeController@update')->name('fee.update'); Route::post('/{id}/approve', 'CreateBulkPurchaseOrderDocumentController@aprove')->name('approve'); Route::post('/bulk/po', 'CreateBulkPurchaseOrderDocumentController@create')->name('bulk.po'); From f3413b9c6c22a5d7986317671f2debe3f3d9b5a4 Mon Sep 17 00:00:00 2001 From: Omair Saleh Date: Tue, 7 May 2024 11:20:14 +0800 Subject: [PATCH 223/434] change service description --- .../vue/components/bookings/forms/BookingFormComponent.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/assets/vue/components/bookings/forms/BookingFormComponent.vue b/resources/assets/vue/components/bookings/forms/BookingFormComponent.vue index d9c009b5..9593e940 100644 --- a/resources/assets/vue/components/bookings/forms/BookingFormComponent.vue +++ b/resources/assets/vue/components/bookings/forms/BookingFormComponent.vue @@ -93,8 +93,8 @@
-

Recipient will receive the transfer on the next working day. Check out our three-day transfer option to get a better rate!

-

Enjoy a better rate with this option! The recipient will receive the transfer after three working days.

+

The recipient can expect to receive the transfer within 1-3 working days. Explore our BANK TRANSFER (SAVER) option for a better rate!

+

Enjoy a better rate with this option! The recipient will receive the transfer after 3-5 working days..

From 26f8ca87cd5a5ded079e5da27d259ee67c83b148 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Wed, 8 May 2024 12:58:23 +0800 Subject: [PATCH 224/434] fix partial refund bug --- .../ControllersLogic/UpdateRefundTransactionStatusLogic.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php index cc98847a..6b755db1 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/UpdateRefundTransactionStatusLogic.php @@ -100,7 +100,7 @@ class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic $booking = $paymentTransaction->owner; - $reference = $refundTransaction->amount == $paymentTransaction->amount ? 'Fully Refund for Ref. ' . $booking->marking : 'Partially Refund for Ref. ' . $booking->marking; + $reference = $refundTransaction->amount - $paymentTransaction->amount < 0.01 ? 'Fully Refund for Ref. ' . $booking->marking : 'Partially Refund for Ref. ' . $booking->marking; $refundAmount = $this->calculatesBookingRefundAmount->calculateRefundAmount($paymentTransaction, $booking->fix_currency_id); @@ -114,7 +114,7 @@ class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic $this->updatesTransactionStatus->execute($po_transaction, (float) number_format($po_transaction->amount, 2, '.', '') === (float) number_format((float)$booking->fix_amount - $refundAmount, 2, '.', '') ? ApprovalStatus::PENDING_VERIFICATION : ApprovalStatus::PENDING_SUBMISSION); } - $request['fix_amount'] = $booking->fix_amount - $refundAmount; + $request['fix_amount'] = $paidAmount; $request->route()->setParameter('id', $booking->id); $this->updateBookingAmountLogic->execute($request); } From b8d741f57ce70b4d310504d67469168a19d6c189 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Wed, 8 May 2024 20:07:06 +0800 Subject: [PATCH 225/434] fix edit transfer fee bug --- .../UpdateGroupTransferFeeLogic.php | 21 ++++++++++++++++++- .../Services/CreatesTransaction.php | 7 +------ .../elements/EditTransferFeeFormComponent.vue | 2 +- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/app/Classes/Modules/Transactions/ControllersLogic/UpdateGroupTransferFeeLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/UpdateGroupTransferFeeLogic.php index 2864eb73..b4cd4d02 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/UpdateGroupTransferFeeLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/UpdateGroupTransferFeeLogic.php @@ -11,6 +11,7 @@ use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\PaymentMethodType; use App\Classes\ValueObjects\Constants\TransactionType; +use App\Models\Transaction; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -73,7 +74,25 @@ class UpdateGroupTransferFeeLogic extends AbstractControllerLogic $fee, $fee, $group->original_currency_id, $group->original_currency_id, 1, 0, 0, null, ApprovalStatus::APPROVED); - $this->createsTransaction->execute($group, $object); + $model = new Transaction(); + $model->bill_no = $object->getBillNo(); + $model->type = $object->getTransactionType(); + $model->issuer = $object->getIssuer(); + $model->receiver = $object->getReceiver(); + $model->recipient_bank_account_id = $object->getRecipientBankAccountId(); + $model->payment_method = $object->getPaymentMethod(); + $model->amount = $object->getAmount(); + $model->original_amount = $object->getOriginalAmount(); + $model->currency_id = $object->getCurrencyId(); + $model->original_currency_id = $object->getOriginalCurrencyId(); + $model->currency_rate = $object->getCurrencyRate(); + $model->tax = $object->getTax(); + $model->service_charge = $object->getServiceCharge(); + $model->expires_on = $object->getExpiresOn(); + $model->status = $object->getStatus(); + $model->payment_reference = $object->getPaymentReference(); + + $group->morphTransactions()->save($model); } return $this->resourceResponse(new GroupResource($group)); diff --git a/app/Classes/Modules/Transactions/Services/CreatesTransaction.php b/app/Classes/Modules/Transactions/Services/CreatesTransaction.php index b545c5ed..06530564 100644 --- a/app/Classes/Modules/Transactions/Services/CreatesTransaction.php +++ b/app/Classes/Modules/Transactions/Services/CreatesTransaction.php @@ -5,7 +5,6 @@ namespace App\Classes\Modules\Transactions\Services; use App\Classes\General\Eloquent\AbstractUpdateRelationshipRecord; use App\Classes\General\Interfaces\Transactionable; use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject; -use App\Models\Group; use App\Models\Transaction; class CreatesTransaction extends AbstractUpdateRelationshipRecord @@ -16,7 +15,7 @@ class CreatesTransaction extends AbstractUpdateRelationshipRecord * @return \Illuminate\Database\Eloquent\Model * @throws \App\Classes\Exceptions\MalformedRequestException */ - public function execute(Transactionable|Group $transactionable, TransactionObject $object) { + public function execute(Transactionable $transactionable, TransactionObject $object) { $model = new Transaction(); $model->bill_no = $object->getBillNo(); $model->type = $object->getTransactionType(); @@ -35,10 +34,6 @@ class CreatesTransaction extends AbstractUpdateRelationshipRecord $model->status = $object->getStatus(); $model->payment_reference = $object->getPaymentReference(); - if ($transactionable instanceof Group) { - return $this->handler($transactionable->morphTransactions(), $model); - } - return $this->handler($transactionable->transactions(), $model); } diff --git a/resources/assets/vue/components/bookings/elements/EditTransferFeeFormComponent.vue b/resources/assets/vue/components/bookings/elements/EditTransferFeeFormComponent.vue index 93b01124..bb82964a 100644 --- a/resources/assets/vue/components/bookings/elements/EditTransferFeeFormComponent.vue +++ b/resources/assets/vue/components/bookings/elements/EditTransferFeeFormComponent.vue @@ -60,7 +60,7 @@ return { error: '', parameters: { - fee: (Math.round((this.transfer_fee + Number.EPSILON) * 10000) / 10000).toFixed(5) + fee: (Math.round((this.transfer_fee + Number.EPSILON) * 100) / 100).toFixed(2) }, } }, From 2ad1841e54cf7fdff3f2e98d0d21bd44b2a875dc Mon Sep 17 00:00:00 2001 From: edmondlang Date: Thu, 9 May 2024 15:46:12 +0800 Subject: [PATCH 226/434] clean up web export route --- routes/web.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/routes/web.php b/routes/web.php index 861f5bdf..0d14a526 100644 --- a/routes/web.php +++ b/routes/web.php @@ -220,12 +220,6 @@ Route::post('/support', function (Request $request) { Route::get('/online_payment/redirect', 'Billplz\CallbackBillplzController@callback')->name('online_payment.redirect'); -Route::get('/export/customers/f614e339d7058904a831aad742e24d55', 'Exports\ExportCustomersToExcelController@export'); -Route::get('/export/transactions/f614e339d7058904a831aad742e24d55', 'Exports\ExportCustomersToExcelController@transactions'); -Route::get('/export/analytic/booking', 'Exports\ExportAnalyticToExcelController@bookingData'); -Route::get('/export/analytic/bills', 'Exports\ExportAnalyticToExcelController@billingData'); -Route::get('/export/customers/leads', 'Exports\ExportCustomersToExcelController@leadsData')->name('leads.export'); - Route::get('/products', function (\App\Classes\Modules\Exports\Services\ExportsProducts $exportsProducts) { return $exportsProducts->download('products.csv', Excel::CSV, ['Content-Type' => 'text/csv']); })->name('products.random'); @@ -293,6 +287,9 @@ Route::get('/export/invoice-transactions/f614e339d7058904a831aad742e24d55', 'Exp Route::get('/export/receipt-transactions/f614e339d7058904a831aad742e24d55', 'Exports\ExportCustomersToExcelController@receiptTransactions')->name('receiptTransactions.export'); Route::get('/export/imported-invoice-mapped', 'Exports\ExportCustomersToExcelController@importedInvoiceMapped')->name('importedInvoiceMapped.export'); Route::get('/export/imported-receipt-mapped', 'Exports\ExportCustomersToExcelController@importedReceiptMapped')->name('importedReceiptMapped.export'); +Route::get('/export/analytic/booking', 'Exports\ExportAnalyticToExcelController@bookingData'); +Route::get('/export/analytic/bills', 'Exports\ExportAnalyticToExcelController@billingData'); +Route::get('/export/customers/leads', 'Exports\ExportCustomersToExcelController@leadsData')->name('leads.export'); Route::get('/products', function (\App\Classes\Modules\Exports\Services\ExportsProducts $exportsProducts) { $bookings = Booking::where(function($query){ From f03d91ba422a1e5d0f29e559b788a66dbbbb3f9d Mon Sep 17 00:00:00 2001 From: edmondlang Date: Fri, 10 May 2024 00:00:01 +0800 Subject: [PATCH 227/434] add remarks for refund --- .../General/Abstracts/AbstractRule.php | 4 +-- app/Classes/General/Interfaces/Remarkable.php | 13 ++++++++++ .../CreateBookingRefundLogic.php | 14 ++++++++++- .../Standards/Rules/CanCreateRemark.php | 2 +- .../Standards/Rules/CanDeleteRemark.php | 2 +- .../Standards/Rules/CanFetchRemark.php | 2 +- .../Standards/Rules/CanListRemarks.php | 2 +- .../Standards/Rules/CanUpdateRemark.php | 2 +- app/Http/Resources/TransactionResource.php | 1 + app/Models/Transaction.php | 3 ++- .../elements/PaymentHistoryComponent.vue | 8 ++++++ .../elements/RefundConfirmationComponent.vue | 13 +++++++++- .../general/elements/RemarkComponent.vue | 25 ++++++++++++++++--- .../general/elements/RemarkListComponent.vue | 4 +-- .../forms/RemarkCommentFormComponent.vue | 5 +++- 15 files changed, 83 insertions(+), 17 deletions(-) create mode 100644 app/Classes/General/Interfaces/Remarkable.php diff --git a/app/Classes/General/Abstracts/AbstractRule.php b/app/Classes/General/Abstracts/AbstractRule.php index d2e0568b..8a9b6f86 100644 --- a/app/Classes/General/Abstracts/AbstractRule.php +++ b/app/Classes/General/Abstracts/AbstractRule.php @@ -27,7 +27,7 @@ abstract class AbstractRule public function passes(?DataTransferObject $object = null): bool { try { if(!$this->authorized()){ - throw new AccessForbiddenException('You don\'t have permission to preform this action'); + throw new AccessForbiddenException('You don\'t have permission to perform this action'); } $this->validators($object); @@ -36,7 +36,7 @@ abstract class AbstractRule return true; } catch(AccessForbiddenException $exception){ - throw new AccessForbiddenException('You don\'t have permission to preform this action'); + throw new AccessForbiddenException('You don\'t have permission to perform this action'); } catch(\Exception $exception){ throw new RequestValidationException($exception->getMessage()); } diff --git a/app/Classes/General/Interfaces/Remarkable.php b/app/Classes/General/Interfaces/Remarkable.php new file mode 100644 index 00000000..dcbd94ce --- /dev/null +++ b/app/Classes/General/Interfaces/Remarkable.php @@ -0,0 +1,13 @@ +fetchBookingQuotation = $fetchBookingQuotation; $this->fetchesTransaction = $fetchesTransaction; @@ -69,6 +75,7 @@ class CreateBookingRefundLogic extends AbstractControllerLogic $this->generatesTransactionBillNumber = $generatesTransactionBillNumber; $this->createsTransaction = $createsTransaction; $this->updateRefundTransactionStatusLogic = $updateRefundTransactionStatusLogic; + $this->createRemarkProcessor = $createRemarkProcessor; } /** @@ -132,6 +139,11 @@ class CreateBookingRefundLogic extends AbstractControllerLogic } + if($request->input('refundRemark')){ + $remarkObject = new RemarkObject($request->input('refundRemark'), Auth()->user()->id); + $this->createRemarkProcessor->execute($this->fetchesTransaction->execute(['id' => $refund_transaction->id]), $remarkObject); + } + return $this->resourceResponse(new TransactionResource($refund_transaction)); } diff --git a/app/Classes/Modules/Remarks/Standards/Rules/CanCreateRemark.php b/app/Classes/Modules/Remarks/Standards/Rules/CanCreateRemark.php index a7d2e5b1..fc51178f 100644 --- a/app/Classes/Modules/Remarks/Standards/Rules/CanCreateRemark.php +++ b/app/Classes/Modules/Remarks/Standards/Rules/CanCreateRemark.php @@ -26,7 +26,7 @@ class CanCreateRemark extends AbstractRule /** * @return bool */ - protected function authorized($object): bool + protected function authorized(): bool { // TODO Set Authorization rules return true; diff --git a/app/Classes/Modules/Remarks/Standards/Rules/CanDeleteRemark.php b/app/Classes/Modules/Remarks/Standards/Rules/CanDeleteRemark.php index 1c61ac9d..7ddece31 100644 --- a/app/Classes/Modules/Remarks/Standards/Rules/CanDeleteRemark.php +++ b/app/Classes/Modules/Remarks/Standards/Rules/CanDeleteRemark.php @@ -13,7 +13,7 @@ class CanDeleteRemark extends AbstractRule /** * @return bool */ - protected function authorized($object): bool + protected function authorized(): bool { // TODO Set Authorization rules return true; diff --git a/app/Classes/Modules/Remarks/Standards/Rules/CanFetchRemark.php b/app/Classes/Modules/Remarks/Standards/Rules/CanFetchRemark.php index 31ae8301..6642611c 100644 --- a/app/Classes/Modules/Remarks/Standards/Rules/CanFetchRemark.php +++ b/app/Classes/Modules/Remarks/Standards/Rules/CanFetchRemark.php @@ -13,7 +13,7 @@ class CanFetchRemark extends AbstractRule /** * @return bool */ - protected function authorized($object): bool + protected function authorized(): bool { // TODO Set Authorization rules return true; diff --git a/app/Classes/Modules/Remarks/Standards/Rules/CanListRemarks.php b/app/Classes/Modules/Remarks/Standards/Rules/CanListRemarks.php index b1372049..4911a53b 100644 --- a/app/Classes/Modules/Remarks/Standards/Rules/CanListRemarks.php +++ b/app/Classes/Modules/Remarks/Standards/Rules/CanListRemarks.php @@ -13,7 +13,7 @@ class CanListRemarks extends AbstractRule /** * @return bool */ - protected function authorized($object): bool + protected function authorized(): bool { // TODO Set Authorization rules return true; diff --git a/app/Classes/Modules/Remarks/Standards/Rules/CanUpdateRemark.php b/app/Classes/Modules/Remarks/Standards/Rules/CanUpdateRemark.php index f6fd6587..8a8c10e8 100644 --- a/app/Classes/Modules/Remarks/Standards/Rules/CanUpdateRemark.php +++ b/app/Classes/Modules/Remarks/Standards/Rules/CanUpdateRemark.php @@ -26,7 +26,7 @@ class CanUpdateRemark extends AbstractRule /** * @return bool */ - protected function authorized($object): bool + protected function authorized(): bool { // TODO Set Authorization rules return true; diff --git a/app/Http/Resources/TransactionResource.php b/app/Http/Resources/TransactionResource.php index b431c854..d259d777 100644 --- a/app/Http/Resources/TransactionResource.php +++ b/app/Http/Resources/TransactionResource.php @@ -53,6 +53,7 @@ class TransactionResource extends JsonResource 'value' => $days->gt(Carbon::now()) ? '+' : '-', 'duration' => $days->diff(Carbon::now())->format('%d'), ], + 'remarks' => RemarkResource::collection($this->remarks), 'redemption' => new VoucherRedemptionResource($this->voucherRedemption) ]; } diff --git a/app/Models/Transaction.php b/app/Models/Transaction.php index aba5decc..31b67e69 100644 --- a/app/Models/Transaction.php +++ b/app/Models/Transaction.php @@ -3,6 +3,7 @@ namespace App\Models; use App\Classes\General\Interfaces\Documentable; +use App\Classes\General\Interfaces\Remarkable; use App\Classes\General\Interfaces\Transactionable; use App\Classes\General\Interfaces\Voucherifiable; use App\Classes\General\Traits\LogData; @@ -21,7 +22,7 @@ use Staudenmeir\EloquentHasManyDeep\HasTableAlias; use App\Models\StatementTransactionOwner; -class Transaction extends AbstractModel implements Documentable, Transactionable, Voucherifiable +class Transaction extends AbstractModel implements Documentable, Transactionable, Voucherifiable, Remarkable { use HasTableAlias; use SoftDeletes; diff --git a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue index 7679b807..ac77bc06 100644 --- a/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue +++ b/resources/assets/vue/components/bookings/elements/PaymentHistoryComponent.vue @@ -332,6 +332,14 @@
{{ refund.status === 1 ? 'Pending Verification' : refund.status === 2 ? 'Approved' : 'Rejected'}}
+
+ + + + + + +
Amount
diff --git a/resources/assets/vue/components/bookings/elements/RefundConfirmationComponent.vue b/resources/assets/vue/components/bookings/elements/RefundConfirmationComponent.vue index c87122a5..3470891a 100644 --- a/resources/assets/vue/components/bookings/elements/RefundConfirmationComponent.vue +++ b/resources/assets/vue/components/bookings/elements/RefundConfirmationComponent.vue @@ -35,6 +35,14 @@
+
+
+ + + + +
+
Paid Amount: {{ paidAmount }}
@@ -71,6 +79,7 @@ export default { data() { return { refundAmount: (Math.round((this.data.original_amount - this.data.refunded_amount + Number.EPSILON) * 100) / 100).toFixed(2), + refundRemark: '', refundMethod: { name: 'Fully Refund', status: false }, refundMethods: [ { name: 'Fully Refund', label: 'Full Refund' }, @@ -82,7 +91,8 @@ export default { return { refundAmount: { maxValue: maxValue(this.refundMaxValue) - } + }, + refundRemark: {} } }, computed: { @@ -96,6 +106,7 @@ export default { methods: { submitForm() { this.parameters.amount = this.refundAmount; + this.parameters.refundRemark = this.refundRemark; this.submit(this.route('api.booking.refund.create', this.data.booking.id, this.data.id), 'post', this.section, true, true) }, updateRefundType(refund) { diff --git a/resources/assets/vue/components/general/elements/RemarkComponent.vue b/resources/assets/vue/components/general/elements/RemarkComponent.vue index f2f9bf30..bd96c5e8 100644 --- a/resources/assets/vue/components/general/elements/RemarkComponent.vue +++ b/resources/assets/vue/components/general/elements/RemarkComponent.vue @@ -3,17 +3,34 @@
-
- +
+

Remarks

- +
+
+
+
+
+
+
+
+
+

Nothing To + Show Here Yet!

+
+
+
+
+
+
+
-
diff --git a/resources/assets/vue/components/general/elements/RemarkListComponent.vue b/resources/assets/vue/components/general/elements/RemarkListComponent.vue index da218ea9..85d8a6a8 100644 --- a/resources/assets/vue/components/general/elements/RemarkListComponent.vue +++ b/resources/assets/vue/components/general/elements/RemarkListComponent.vue @@ -41,12 +41,12 @@

{{item.content}}

- +
- +
diff --git a/resources/assets/vue/components/general/forms/RemarkCommentFormComponent.vue b/resources/assets/vue/components/general/forms/RemarkCommentFormComponent.vue index 7da26ca8..0bada956 100644 --- a/resources/assets/vue/components/general/forms/RemarkCommentFormComponent.vue +++ b/resources/assets/vue/components/general/forms/RemarkCommentFormComponent.vue @@ -1,5 +1,5 @@