diff --git a/app/Http/Controllers/V2/Terrafund/TerrafundClipGeometryController.php b/app/Http/Controllers/V2/Terrafund/TerrafundClipGeometryController.php index fcd6f6c8..67d92f8f 100644 --- a/app/Http/Controllers/V2/Terrafund/TerrafundClipGeometryController.php +++ b/app/Http/Controllers/V2/Terrafund/TerrafundClipGeometryController.php @@ -5,7 +5,7 @@ use App\Helpers\GeometryHelper; use App\Http\Resources\DelayedJobResource; use App\Jobs\FixPolygonOverlapJob; -use App\Models\DelayedJob; +use App\Models\DelayedJobProgress; use App\Models\V2\Sites\CriteriaSite; use App\Models\V2\Sites\Site; use App\Models\V2\Sites\SitePolygon; @@ -25,7 +25,9 @@ public function clipOverlappingPolygonsBySite(string $uuid) ini_set('memory_limit', '-1'); $user = Auth::user(); $polygonUuids = GeometryHelper::getSitePolygonsUuids($uuid)->toArray(); - $delayedJob = DelayedJob::create(); + $delayedJob = DelayedJobProgress::create([ + 'processed_content' => 0, + ]); $job = new FixPolygonOverlapJob($delayedJob->id, $polygonUuids, $user->id); dispatch($job); @@ -75,7 +77,10 @@ public function clipOverlappingPolygonsOfProjectBySite(string $uuid) if (empty($uniquePolygonUuids)) { return response()->json(['message' => 'No overlapping polygons found for the project.'], 204); } - $delayedJob = DelayedJob::create(); + + $delayedJob = DelayedJobProgress::create([ + 'processed_content' => 0, + ]); $job = new FixPolygonOverlapJob($delayedJob->id, $uniquePolygonUuids, $user->id); dispatch($job); @@ -123,7 +128,9 @@ public function clipOverlappingPolygons(Request $request) $delayedJob = null; if (! empty($uniquePolygonUuids)) { $user = Auth::user(); - $delayedJob = DelayedJob::create(); + $delayedJob = DelayedJobProgress::create([ + 'processed_content' => 0, + ]); $job = new FixPolygonOverlapJob($delayedJob->id, $polygonUuids, $user->id); dispatch($job); } diff --git a/app/Http/Controllers/V2/Terrafund/TerrafundCreateGeometryController.php b/app/Http/Controllers/V2/Terrafund/TerrafundCreateGeometryController.php index 262687b1..dab1bddb 100755 --- a/app/Http/Controllers/V2/Terrafund/TerrafundCreateGeometryController.php +++ b/app/Http/Controllers/V2/Terrafund/TerrafundCreateGeometryController.php @@ -8,6 +8,7 @@ use App\Jobs\InsertGeojsonToDBJob; use App\Jobs\RunSitePolygonsValidationJob; use App\Models\DelayedJob; +use App\Models\DelayedJobProgress; use App\Models\V2\PolygonGeometry; use App\Models\V2\Sites\Site; use App\Models\V2\Sites\SitePolygon; @@ -1219,7 +1220,10 @@ public function runSiteValidationPolygon(Request $request) $uuid = $request->input('uuid'); $sitePolygonsUuids = GeometryHelper::getSitePolygonsUuids($uuid)->toArray(); - $delayedJob = DelayedJob::create(); + $delayedJob = DelayedJobProgress::create([ + 'total_content' => count($sitePolygonsUuids), + 'processed_content' => 0, + ]); $job = new RunSitePolygonsValidationJob($delayedJob->id, $sitePolygonsUuids); dispatch($job); @@ -1235,7 +1239,10 @@ public function runPolygonsValidation(Request $request) { try { $uuids = $request->input('uuids'); - $delayedJob = DelayedJob::create(); + $delayedJob = DelayedJobProgress::create([ + 'total_content' => count($uuids), + 'processed_content' => 0, + ]); $job = new RunSitePolygonsValidationJob($delayedJob->id, $uuids); dispatch($job); diff --git a/app/Http/Resources/DelayedJobProgressResource.php b/app/Http/Resources/DelayedJobProgressResource.php new file mode 100644 index 00000000..234c2ad8 --- /dev/null +++ b/app/Http/Resources/DelayedJobProgressResource.php @@ -0,0 +1,25 @@ + + */ + public function toArray(Request $request): array + { + return [ + 'message' => $this->message ?? 'Job dispatched', + 'job_uuid' => $this->uuid, + 'proccessed_content' => $this->processed_content, + 'total_content' => $this->total_content, + 'proccess_message' => $this->proccess_message, + ]; + } +} diff --git a/app/Jobs/FixPolygonOverlapJob.php b/app/Jobs/FixPolygonOverlapJob.php index 6196c339..a272f869 100644 --- a/app/Jobs/FixPolygonOverlapJob.php +++ b/app/Jobs/FixPolygonOverlapJob.php @@ -4,6 +4,7 @@ use App\Http\Middleware\SetAuthenticatedUserForJob; use App\Models\DelayedJob; +use App\Models\DelayedJobProgress; use App\Services\PolygonService; use Exception; use Illuminate\Bus\Queueable; @@ -63,14 +64,15 @@ public function handle(): void { try { - $delayedJob = DelayedJob::findOrFail($this->delayed_job_id); + $delayedJob = DelayedJobProgress::findOrFail($this->delayed_job_id); $user = Auth::user(); if ($user) { - $polygonsClipped = App::make(PolygonService::class)->processClippedPolygons($this->polygonUuids); + $polygonsClipped = App::make(PolygonService::class)->processClippedPolygons($this->polygonUuids, $this->delayed_job_id); $delayedJob->update([ - 'status' => DelayedJob::STATUS_SUCCEEDED, + 'status' => DelayedJobProgress::STATUS_SUCCEEDED, 'payload' => json_encode(['updated_polygons' => $polygonsClipped]), 'status_code' => Response::HTTP_OK, + 'progress' => 100, ]); } } catch (Exception $e) { diff --git a/app/Jobs/RunSitePolygonsValidationJob.php b/app/Jobs/RunSitePolygonsValidationJob.php index 96fe5e6f..9bba9777 100644 --- a/app/Jobs/RunSitePolygonsValidationJob.php +++ b/app/Jobs/RunSitePolygonsValidationJob.php @@ -3,6 +3,7 @@ namespace App\Jobs; use App\Models\DelayedJob; +use App\Models\DelayedJobProgress; use App\Services\PolygonValidationService; use Exception; use Illuminate\Bus\Queueable; @@ -48,7 +49,7 @@ public function __construct(string $delayed_job_id, array $sitePolygonsUuids) public function handle(PolygonValidationService $validationService) { try { - $delayedJob = DelayedJob::findOrFail($this->delayed_job_id); + $delayedJob = DelayedJobProgress::findOrFail($this->delayed_job_id); foreach ($this->sitePolygonsUuids as $polygonUuid) { $request = new Request(['uuid' => $polygonUuid]); $validationService->validateOverlapping($request); @@ -60,12 +61,17 @@ public function handle(PolygonValidationService $validationService) $validationService->getGeometryType($request); $validationService->validateEstimatedArea($request); $validationService->validateDataInDB($request); + + $delayedJob->increment('processed_content'); + $delayedJob->processMessage(); + $delayedJob->save(); } $delayedJob->update([ - 'status' => DelayedJob::STATUS_SUCCEEDED, + 'status' => DelayedJobProgress::STATUS_SUCCEEDED, 'payload' => ['message' => 'Validation completed for all site polygons'], 'status_code' => Response::HTTP_OK, + 'progress' => 100, ]); } catch (Exception $e) { diff --git a/app/Models/DelayedJobProgress.php b/app/Models/DelayedJobProgress.php new file mode 100644 index 00000000..a01fda4f --- /dev/null +++ b/app/Models/DelayedJobProgress.php @@ -0,0 +1,36 @@ +fillable = array_merge($this->fillable, [ + 'processed_content', + 'total_content', + 'proccess_message', + ]); + + $this->casts = array_merge($this->casts, [ + 'processed_content' => 'integer', + 'total_content' => 'integer', + 'proccess_message' => 'string', + ]); + } + + public function processMessage(): string + { + $progress = 0; + if ($this->total_content > 0) { + $progress = (int)(($this->processed_content / $this->total_content) * 100); + } else { + $progress = 0; + } + + return $this->proccess_message = 'Running '. $this->processed_content .' out of ' + .$this->total_content. ' polygons ('.$progress.'%)' ; + } +} diff --git a/app/Services/PolygonService.php b/app/Services/PolygonService.php index c6712bb7..5213b9af 100755 --- a/app/Services/PolygonService.php +++ b/app/Services/PolygonService.php @@ -5,6 +5,7 @@ use App\Helpers\CreateVersionPolygonGeometryHelper; use App\Helpers\GeometryHelper; use App\Helpers\PolygonGeometryHelper; +use App\Models\DelayedJobProgress; use App\Models\V2\PointGeometry; use App\Models\V2\PolygonGeometry; use App\Models\V2\ProjectPitch; @@ -562,13 +563,16 @@ public function insertGeojsonToDBFromContent(string $geojsonData, ?string $entit } } - public function processClippedPolygons(array $polygonUuids) + public function processClippedPolygons(array $polygonUuids, $delayed_job_id = null) { $geojson = GeometryHelper::getPolygonsGeojson($polygonUuids); $clippedPolygons = App::make(PythonService::class)->clipPolygons($geojson); $uuids = []; + $delayedJob = DelayedJobProgress::findOrFail($delayed_job_id); + + Log::info('test now selected plygons'); if (isset($clippedPolygons['type']) && $clippedPolygons['type'] === 'FeatureCollection' && isset($clippedPolygons['features'])) { foreach ($clippedPolygons['features'] as $feature) { if (isset($feature['properties']['poly_id'])) { @@ -591,8 +595,13 @@ public function processClippedPolygons(array $polygonUuids) } if (! empty($uuids)) { + $delayedJob->total_content = count($newPolygonUuids); + $delayedJob->save(); foreach ($newPolygonUuids as $polygonUuid) { App::make(PolygonValidationService::class)->runValidationPolygon($polygonUuid); + $delayedJob->increment('processed_content'); + $delayedJob->processMessage(); + $delayedJob->save(); } } diff --git a/database/migrations/2024_11_27_103000_add_fields_to_delayed_job_table.php b/database/migrations/2024_11_27_103000_add_fields_to_delayed_job_table.php new file mode 100644 index 00000000..c537ca06 --- /dev/null +++ b/database/migrations/2024_11_27_103000_add_fields_to_delayed_job_table.php @@ -0,0 +1,33 @@ +unsignedInteger('processed_content')->nullable()->after('payload'); + $table->unsignedInteger('total_content')->nullable()->after('processed_content'); + $table->string('proccess_message')->nullable()->after('total_content'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('delayed_jobs', function (Blueprint $table) { + $table->dropColumn(['proccessed_content', 'total_content', 'proccess_message']); + }); + } +};