diff --git a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php index b2bac4fd..f32e786f 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/BulkDownloadCustomerInvoicesLogic.php @@ -8,60 +8,87 @@ use ZipArchive; use Illuminate\Http\Request; use Illuminate\Support\Facades\Storage; use App\Classes\Exceptions\MalformedRequestException; +use Illuminate\Support\Facades\File; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\DocumentType; use App\Models\Company; +use Carbon\Carbon; +use Illuminate\Support\Facades\Log; class BulkDownloadCustomerInvoicesLogic { /** * @param Request $request - * @return void - * @throws MalformedRequestException + * @return \Illuminate\Http\JsonResponse|\Symfony\Component\HttpFoundation\BinaryFileResponse */ public function execute(Request $request) { - $company = Company::where('reference', $request->input('marking'))->first(); + try { + $company = Company::where('reference', $request->input('marking'))->first(); - $startDate = $request->input('startDate'); - $endDate = $request->input('endDate'); - if ($company) { - $invoicebookings = $company->bookings()->whereDate('created_at', '>=', $startDate) + if (!$company) { + return response()->json([ + 'status' => 'Failed', + 'message' => 'Customer not found.', + ]); + } + + $startDate = Carbon::createFromFormat('d-m-Y', $request->input('startDate'))->startOfDay(); + $endDate = Carbon::createFromFormat('d-m-Y', $request->input('endDate'))->endOfDay(); + + $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(); + ->whereIn('transactions.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); + }) + ->orderBy('created_at') + ->get(); - - if (count($invoicebookings) > 0) { - $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); - } - } else { + if ($invoicebookings->isEmpty()) { return response()->json([ 'status' => 'Failed', 'message' => 'No invoices found for this customer in the given date range.', ]); } - } 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(); + 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' => 'Failed', + 'message' => 'Failed to create the Zip archive.', + ]); + } + } catch (\Exception $e) { + // Log the exception for debugging + Log::error('Error in BulkDownloadCustomerInvoicesLogic: ' . $e->getMessage()); + return response()->json([ 'status' => 'Failed', - 'message' => 'Customer not found.', + 'message' => 'An error occurred while processing the request.', ]); } } -} \ No newline at end of file +} diff --git a/app/Console/Commands/DeleteBulkInvoiceFiles.php b/app/Console/Commands/DeleteBulkInvoiceFiles.php new file mode 100644 index 00000000..52ebf121 --- /dev/null +++ b/app/Console/Commands/DeleteBulkInvoiceFiles.php @@ -0,0 +1,52 @@ +logOutput('Process started'); + + $directory = storage_path('app/bulk_invoice'); + + if (File::isDirectory($directory)) { + File::cleanDirectory($directory); + $this->info('All files in the bulk_invoice directory have been deleted.'); + } else { + $this->error('The bulk_invoice directory does not exist.'); + } + + $end = new Carbon(); + $elapsedTime = $start->diff($end)->format('%H:%I:%S'); + + $this->logOutput('Process ended. ElapsedTime: ' . $elapsedTime); + } + + public function logOutput($text) + { + if (is_array($text)) { + $text = implode(', ', $text); + } + + $this->info(Carbon::now() . ' : ' . $text); + + $filePath = storage_path('logs/delete-orders.log'); + $textToAppend = Carbon::now()->format('[Y-m-d H:i:s]') . ' ' . $text . PHP_EOL; + file_put_contents($filePath, $textToAppend, FILE_APPEND); + } +} diff --git a/resources/assets/vue/components/companies/elements/BulkDownloadInvoiceComponent.vue b/resources/assets/vue/components/companies/elements/BulkDownloadInvoiceComponent.vue index 7b6786b3..0ae4b102 100644 --- a/resources/assets/vue/components/companies/elements/BulkDownloadInvoiceComponent.vue +++ b/resources/assets/vue/components/companies/elements/BulkDownloadInvoiceComponent.vue @@ -91,7 +91,11 @@ }, successHandler(response) { this.isLoading = false; - this.returnData = response; + if (response.message) { + this.returnData = response; + } else { + this.returnData = null; + } }, hasMarkingParameter() { const urlSearchParams = new URLSearchParams(window.location.search); diff --git a/resources/assets/vue/general/mixins/request.js b/resources/assets/vue/general/mixins/request.js index a3c212e8..4c3e5929 100644 --- a/resources/assets/vue/general/mixins/request.js +++ b/resources/assets/vue/general/mixins/request.js @@ -13,19 +13,39 @@ export default { let statusCode = response.status, success = response.ok; - response.json().then(response => { + if (response.headers.get("content-type") === "application/zip") { + const fileName = response.headers.get('Content-Disposition').split('filename=')[1]; - if(!success){ - this.openModal(); - errorNotification ? this.$store.dispatch('createNotification', {title: response.title, message: response.message, type: 'error'}): null; - this.errorHandler(response, statusCode); return; - } + response.blob().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) + successNotification ? this.$store.dispatch('createNotification', { title: response.title, message: response.message, type: 'success' }) : null; + + const link = document.createElement('a'); + link.href = window.URL.createObjectURL(response); + link.download = fileName; + link.click(); + this.successHandler(response) + }); + } else { + 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) => { console.log(error); this.$store.dispatch('createNotification', {title: 'Unexpected Error', message: 'An unexpected error has occurred. Try again!', type: 'error'});