From 49ca423096d9938cc35f5bc45be55fc17dfecd6c Mon Sep 17 00:00:00 2001 From: Limber Mamani <154026979+LimberHope@users.noreply.github.com> Date: Thu, 21 Nov 2024 10:22:58 -0400 Subject: [PATCH] [TM-1457] add delayed job to organisations export (#576) * [TM-1457] add delayed job to organisations export * [TM-1457] add delayed job functionality to export organisations * remove comment --- app/Exports/V2/OrganisationsExport.php | 5 ++ .../AdminExportOrganisationsController.php | 36 ++++++++-- app/Jobs/ExportAllOrganisationsJob.php | 66 +++++++++++++++++++ .../ExportAllOrganisationsService.php | 13 ++++ 4 files changed, 114 insertions(+), 6 deletions(-) create mode 100644 app/Jobs/ExportAllOrganisationsJob.php create mode 100644 app/Services/ExportAllOrganisationsService.php diff --git a/app/Exports/V2/OrganisationsExport.php b/app/Exports/V2/OrganisationsExport.php index 7bf937e58..ea5f44982 100644 --- a/app/Exports/V2/OrganisationsExport.php +++ b/app/Exports/V2/OrganisationsExport.php @@ -54,6 +54,11 @@ public function collection(): Collection ])->get(); } + public function chunkSize(): int + { + return 1000; + } + public function headings(): array { $headings = [ diff --git a/app/Http/Controllers/V2/Organisations/AdminExportOrganisationsController.php b/app/Http/Controllers/V2/Organisations/AdminExportOrganisationsController.php index 2e8628c4f..c3eced806 100644 --- a/app/Http/Controllers/V2/Organisations/AdminExportOrganisationsController.php +++ b/app/Http/Controllers/V2/Organisations/AdminExportOrganisationsController.php @@ -2,21 +2,45 @@ namespace App\Http\Controllers\V2\Organisations; -use App\Exports\V2\OrganisationsExport; use App\Http\Controllers\Controller; +use App\Http\Resources\DelayedJobResource; +use App\Jobs\ExportAllOrganisationsJob; +use App\Models\DelayedJob; use App\Models\V2\Organisation; use Illuminate\Http\Request; -use Maatwebsite\Excel\Excel; -use Symfony\Component\HttpFoundation\BinaryFileResponse; +use Illuminate\Support\Facades\Log; +use Illuminate\Support\Facades\Redis; class AdminExportOrganisationsController extends Controller { - public function __invoke(Request $request): BinaryFileResponse + public function __invoke(Request $request) { $this->authorize('export', Organisation::class); - $filename = 'organisations(' . now()->format('d-m-Y-H-i'). ').csv'; + $filename = 'organisations(' . now()->format('d-m-Y'). ').csv'; + $relativePath = 'exports/' . $filename; + $absolutePath = storage_path('app/' . $relativePath); - return (new OrganisationsExport())->download($filename, Excel::CSV)->deleteFileAfterSend(true); + try { + $binary_data = Redis::get('exports:organisations:'.$filename); + if (! $binary_data) { + $delayedJob = DelayedJob::create(); + $job = new ExportAllOrganisationsJob( + $delayedJob->id, + $filename + ); + dispatch($job); + + return (new DelayedJobResource($delayedJob))->additional(['message' => "Export for organisations $filename is being processed"]); + } else { + file_put_contents($absolutePath, $binary_data); + + return response()->download($absolutePath, $filename)->deleteFileAfterSend(true); + } + } catch (\Exception $e) { + Log::error('Error during export for organisations : ' . $e->getMessage()); + + return response()->json(['error' => 'An error occurred during organisations export'], 500); + } } } diff --git a/app/Jobs/ExportAllOrganisationsJob.php b/app/Jobs/ExportAllOrganisationsJob.php new file mode 100644 index 000000000..d10285b7d --- /dev/null +++ b/app/Jobs/ExportAllOrganisationsJob.php @@ -0,0 +1,66 @@ +file_name = $file_name; + $this->delayed_job_id = $delayed_job_id; + } + + public function handle(ExportAllOrganisationsService $exportAllOrganisationsService) + { + try { + $delayedJob = DelayedJob::findOrFail($this->delayed_job_id); + $relativePath = 'exports/' . $this->file_name; + + Excel::store($exportAllOrganisationsService->run(), $relativePath); + + $absolutePath = storage_path('app/' . $relativePath); + $binary_data = file_get_contents($absolutePath); + + Redis::set('exports:organisations:'.$this->file_name, $binary_data, 'EX', 7200); + $delayedJob->update([ + 'status' => DelayedJob::STATUS_SUCCEEDED, + 'payload' => ['message' => 'All Organisations Export completed'], + 'status_code' => Response::HTTP_OK, + ]); + } catch (Exception $e) { + Log::error('Error in ExportAllOrganisationsJob: ' . $e->getMessage()); + + DelayedJob::where('id', $this->delayed_job_id)->update([ + 'status' => DelayedJob::STATUS_FAILED, + 'payload' => json_encode(['error' => $e->getMessage()]), + 'status_code' => Response::HTTP_INTERNAL_SERVER_ERROR, + ]); + } + } +} diff --git a/app/Services/ExportAllOrganisationsService.php b/app/Services/ExportAllOrganisationsService.php new file mode 100644 index 000000000..f76901b18 --- /dev/null +++ b/app/Services/ExportAllOrganisationsService.php @@ -0,0 +1,13 @@ +