From 58ae950a719f0b0dab9a4259a0342e345d33b6fa Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Fri, 8 Sep 2023 14:49:39 +0800 Subject: [PATCH 01/66] bulk download invoices --- .../BulkDownloadCustomerInvoicesLogic.php | 55 +++++++++++++++++++ ...BulkDownloadCustomerInvoicesController.php | 20 +++++++ .../customer_invoices_bulk_download.blade.php | 35 ++++++++++++ routes/web.php | 6 ++ 4 files changed, 116 insertions(+) create mode 100644 app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php create mode 100644 app/Http/Controllers/Companies/BulkDownloadCustomerInvoicesController.php create mode 100644 resources/views/pages/customer_invoices_bulk_download.blade.php diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php new file mode 100644 index 00000000..25821b03 --- /dev/null +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php @@ -0,0 +1,55 @@ +input('marking'))->first(); + + $startDate = $request->input('startDate'); + $endDate = $request->input('endDate'); + if ($company) { + $invoicebookings = $company->bookings()->whereDate('created_at', '>=', $startDate) + ->whereDate('created_at', '<=', $endDate) + ->whereHas('transactions', function ($query) { + $query->where('transactions.type', TransactionType::INVOICE) + ->whereIn('transactions.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); + })->orderBy('created_at')->get(); + + + $zip_file = "invoices_{$startDate}_to_{$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); + } + } + } +} diff --git a/app/Http/Controllers/Companies/BulkDownloadCustomerInvoicesController.php b/app/Http/Controllers/Companies/BulkDownloadCustomerInvoicesController.php new file mode 100644 index 00000000..4d6944d4 --- /dev/null +++ b/app/Http/Controllers/Companies/BulkDownloadCustomerInvoicesController.php @@ -0,0 +1,20 @@ +execute($request); + } + +} \ No newline at end of file diff --git a/resources/views/pages/customer_invoices_bulk_download.blade.php b/resources/views/pages/customer_invoices_bulk_download.blade.php new file mode 100644 index 00000000..faae46a5 --- /dev/null +++ b/resources/views/pages/customer_invoices_bulk_download.blade.php @@ -0,0 +1,35 @@ +@extends('layouts.base_portal') +@section('inner_content') +
+
+
+
+
+ @csrf +
+
+ + +
+
+
+ + +
+
+
+
+ + +
+
+
+ +
+
+
+
+
+
+
+@endsection diff --git a/routes/web.php b/routes/web.php index a9e51a50..3a541f2d 100644 --- a/routes/web.php +++ b/routes/web.php @@ -141,6 +141,12 @@ Route::get('/purchase_orders', function () { return view('pages.purchase_orders'); })->name('purchase_orders'); +Route::get('/customers/invoices', function () { + return view('pages.customer_invoices_bulk_download'); +})->name('customers.invoices'); + +Route::post('/customers/invoices', 'Companies\BulkDownloadCustomerInvoicesController@download')->name('customers.invoices'); + Route::get('/support', function () { return view('pages.customer_support', [ 'marking' => null, From be2e00297b1dc379bf0adb105097a0f6f4f0d85f Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Mon, 11 Sep 2023 20:43:21 +0800 Subject: [PATCH 02/66] fix if customer or no invoices found --- .../BulkDownloadCustomerInvoicesLogic.php | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php index 25821b03..1c9caddb 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php @@ -34,22 +34,28 @@ class BulkDownloadCustomerInvoicesLogic })->orderBy('created_at')->get(); - $zip_file = "invoices_{$startDate}_to_{$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(); - } + if (count($invoicebookings) > 0) { + $zip_file = "invoices_{$startDate}_to_{$endDate}_{$company->reference}.zip"; - return response()->download($zip_file); + $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("No invoices found for this customer in the given date range."); } + } else { + return response("Customer not found"); } } } From 9f2b431f215c04c255b42b9edf546e634bf8607b Mon Sep 17 00:00:00 2001 From: edmondlang Date: Sat, 16 Sep 2023 14:38:02 +0800 Subject: [PATCH 03/66] 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 ec83540a4056a0a1303d8632fc69cf6de888d462 Mon Sep 17 00:00:00 2001 From: JiaSheng Date: Sat, 30 Sep 2023 12:48:49 +0800 Subject: [PATCH 04/66] wallet pagination filters --- .../Eloquent/Filters/CreatedAfterOrEqual.php | 4 +- .../Eloquent/Filters/CreatedBeforeOrEqual.php | 4 +- .../General/Eloquent/Filters/OwnerId.php | 3 +- .../General/Eloquent/Filters/OwnerType.php | 3 +- .../General/Eloquent/Filters/StatusIn.php | 3 +- .../Filters/WithBookingMarkingLike.php | 29 +++++++++ .../elements/CustomerTransactionComponent.vue | 65 ++++++++++++++++++- 7 files changed, 104 insertions(+), 7 deletions(-) create mode 100644 app/Classes/General/Eloquent/Filters/WithBookingMarkingLike.php diff --git a/app/Classes/General/Eloquent/Filters/CreatedAfterOrEqual.php b/app/Classes/General/Eloquent/Filters/CreatedAfterOrEqual.php index 7e563aee..9df98f40 100644 --- a/app/Classes/General/Eloquent/Filters/CreatedAfterOrEqual.php +++ b/app/Classes/General/Eloquent/Filters/CreatedAfterOrEqual.php @@ -16,6 +16,8 @@ class CreatedAfterOrEqual implements Filter */ public static function apply(Builder $builder, $value) { - return $builder->where('created_at', '>=', Carbon::parse($value)); + $table = $builder->getModel()->getTable(); + $startDate = Carbon::createFromFormat('d-m-Y', $value)->startOfDay(); + return $builder->where("{$table}.created_at", '>=', $startDate); } } \ No newline at end of file diff --git a/app/Classes/General/Eloquent/Filters/CreatedBeforeOrEqual.php b/app/Classes/General/Eloquent/Filters/CreatedBeforeOrEqual.php index ed97b48f..5b349540 100644 --- a/app/Classes/General/Eloquent/Filters/CreatedBeforeOrEqual.php +++ b/app/Classes/General/Eloquent/Filters/CreatedBeforeOrEqual.php @@ -15,6 +15,8 @@ class CreatedBeforeOrEqual implements Filter */ public static function apply(Builder $builder, $value) { - return $builder->where('created_at', '<=', Carbon::parse($value)); + $table = $builder->getModel()->getTable(); + $endDate = Carbon::createFromFormat('d-m-Y', $value)->endOfDay(); + return $builder->where("{$table}.created_at", '<=', $endDate); } } diff --git a/app/Classes/General/Eloquent/Filters/OwnerId.php b/app/Classes/General/Eloquent/Filters/OwnerId.php index eac7e32d..c2dfa685 100644 --- a/app/Classes/General/Eloquent/Filters/OwnerId.php +++ b/app/Classes/General/Eloquent/Filters/OwnerId.php @@ -14,7 +14,8 @@ class OwnerId implements Filter */ public static function apply(Builder $builder, $value) { - return $builder->where('owner_id', $value); + $table = $builder->getModel()->getTable(); + return $builder->where("{$table}.owner_id", $value); } } \ No newline at end of file diff --git a/app/Classes/General/Eloquent/Filters/OwnerType.php b/app/Classes/General/Eloquent/Filters/OwnerType.php index 6a13fb08..3feedccd 100644 --- a/app/Classes/General/Eloquent/Filters/OwnerType.php +++ b/app/Classes/General/Eloquent/Filters/OwnerType.php @@ -14,7 +14,8 @@ class OwnerType implements Filter */ public static function apply(Builder $builder, $value) { - return $builder->where('owner_type', $value); + $table = $builder->getModel()->getTable(); + return $builder->where("{$table}.owner_type", $value); } } \ No newline at end of file diff --git a/app/Classes/General/Eloquent/Filters/StatusIn.php b/app/Classes/General/Eloquent/Filters/StatusIn.php index cbfdfbd0..85425802 100644 --- a/app/Classes/General/Eloquent/Filters/StatusIn.php +++ b/app/Classes/General/Eloquent/Filters/StatusIn.php @@ -14,7 +14,8 @@ class StatusIn implements Filter */ public static function apply(Builder $builder, $value) { - return $builder->whereIn('status', $value); + $table = $builder->getModel()->getTable(); + return $builder->whereIn("{$table}.status", $value); } } \ No newline at end of file diff --git a/app/Classes/General/Eloquent/Filters/WithBookingMarkingLike.php b/app/Classes/General/Eloquent/Filters/WithBookingMarkingLike.php new file mode 100644 index 00000000..ed35cc31 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/WithBookingMarkingLike.php @@ -0,0 +1,29 @@ +join('transactions as t2', 't2.payment_reference', '=', 'transactions.bill_no') + ->join('bookings', function ($join) use ($value) { + $join->on('bookings.id', '=', 't2.owner_id') + ->where('bookings.marking', 'LIKE', '%'.$value.'%'); + }) + ->addSelect(['transactions.*','t2.owner_id as bookingId', 'bookings.marking as bookingMarking']); + } +} \ No newline at end of file diff --git a/resources/assets/vue/components/wallets/elements/CustomerTransactionComponent.vue b/resources/assets/vue/components/wallets/elements/CustomerTransactionComponent.vue index 1250432b..aeb045ce 100644 --- a/resources/assets/vue/components/wallets/elements/CustomerTransactionComponent.vue +++ b/resources/assets/vue/components/wallets/elements/CustomerTransactionComponent.vue @@ -1,6 +1,29 @@