This commit is contained in:
Martin Folkerts 2024-01-09 19:20:58 +01:00
parent da9d94880f
commit a1bba242cb
8 changed files with 106 additions and 66 deletions

View file

@ -65,10 +65,11 @@ public function handle(): void
public static function handleForDate(Project $project, Carbon $date) public static function handleForDate(Project $project, Carbon $date)
{ {
if ($project->downloads()->where(['status' => 'completed', 'date' => $date])->count() > 0) { $filename = sprintf('%s.tif', $date->format('Y-m-d'));
if ($project->downloads()->where(['status' => 'completed', 'name' => $filename])->count() > 0) {
return; return;
} }
$filename = sprintf('%s.tif', $date->format('Y-m-d'));
$path = sprintf('%s/%s/%s', $project->download_path, 'merged_final_tif', $filename); $path = sprintf('%s/%s/%s', $project->download_path, 'merged_final_tif', $filename);
return new self( return new self(
$project->downloads()->create([ $project->downloads()->create([

View file

@ -74,6 +74,8 @@ public static function handleFor(Project $project, $year, $startWeekNumber) {
return; return;
} }
$mosaic = $project->mosaics()->create([ $mosaic = $project->mosaics()->create([
'name' => sprintf('Week %d, %d', $startWeekNumber, $year),
'path' => sprintf('%s/%s/%s', $project->download_path, 'mosaics', sprintf('week_%d_%d.tif', $startWeekNumber, $year)),
'year' => $year, 'year' => $year,
'week' => $startWeekNumber, 'week' => $startWeekNumber,
'status' => 'pending', 'status' => 'pending',

View file

@ -27,7 +27,7 @@ public function render()
]); ]);
} }
public function saveMosiac(){ public function saveMosaic(){
$this->validate([ $this->validate([
'formData.year' => 'required', 'formData.year' => 'required',
'formData.week' => 'required', 'formData.week' => 'required',

View file

@ -3,6 +3,8 @@
namespace App\Models; namespace App\Models;
use App\Jobs\ProjectDownloadTiffJob; use App\Jobs\ProjectDownloadTiffJob;
use App\Jobs\ProjectMosiacGeneratorJob;
use Carbon\CarbonPeriod;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Carbon\Carbon; use Carbon\Carbon;
@ -135,7 +137,7 @@ public function downloads(): \Illuminate\Database\Eloquent\Relations\HasMany
return $this->hasMany(ProjectDownload::class); return $this->hasMany(ProjectDownload::class);
} }
public function mosaics() : \Illuminate\Database\Eloquent\Relations\HasMany public function mosaics(): \Illuminate\Database\Eloquent\Relations\HasMany
{ {
return $this->hasMany(ProjectMosaic::class); return $this->hasMany(ProjectMosaic::class);
} }
@ -237,12 +239,12 @@ public function getMergedTiffList()
->values(); ->values();
} }
public function hasPendingDownload() : bool public function hasPendingDownload(): bool
{ {
return $this->downloads()->where('status', 'pending')->count() > 0; return $this->downloads()->where('status', 'pending')->count() > 0;
} }
public function hasPendingMosaic() : bool public function hasPendingMosaic(): bool
{ {
return $this->mosaics()->where('status', 'pending')->count() > 0; return $this->mosaics()->where('status', 'pending')->count() > 0;
} }
@ -252,13 +254,57 @@ public function startDownload(Carbon $date)
$downloadRequest = $this->downloads()->updateOrCreate( $downloadRequest = $this->downloads()->updateOrCreate(
[ [
'project_id' => $this->id, // of een andere manier om project_id te bepalen 'project_id' => $this->id, // of een andere manier om project_id te bepalen
'name' => sprintf('%s.tif', $date->format('Y-m-d')), 'name' => sprintf('%s.tif', $date->format('Y-m-d')),
], ],
[ [
'path' => sprintf('%s/%s/%s.tif', $this->download_path, 'merged_final_tif', $date->format('Y-m-d')), 'path' => sprintf('%s/%s/%s.tif', $this->download_path, 'merged_final_tif', $date->format('Y-m-d')),
'status' => 'pending', 'status' => 'pending',
] ]
); );
ProjectDownloadTiffJob::dispatch($downloadRequest, $date); ProjectDownloadTiffJob::dispatch($downloadRequest, $date);
} }
public function scheduleReport($year, $week)
{
if ($this->reports()->where(['year' => $year, 'week' => $week])->count() > 0) {
return;
}
Bus::chain([
Bus::batch(self::getFileDownloadsFor($year, $week)),
Bus::batch(self::getMosiacsFor($year, $week)),
Bus::batch(self::getReport($year, $week)),
])->dispatch();
}
public function getReport($year, $week)
{
$report = $this->reports()->create([
'name' => 'Report for week '.$week.' of '.$year,
'week' => $week,
'year' => $year,
'path' => 'reports/week_'.$week.'_'.$year.'.docx',
]);
return new ProjectReportGeneratorJob($report);
}
public function getFileDownloadsFor($year, $startWeekNumber): Collection
{
$endOfRange = \Illuminate\Support\Carbon::now()->setISODate($year, $startWeekNumber)->endOfWeek();
$startOfRange = (clone $endOfRange)->subWeeks(2)->startOfWeek();
$dateRange = CarbonPeriod::create($startOfRange, $endOfRange);
return collect($dateRange)
->map(fn($date) => ProjectDownloadTiffJob::handleForDate($this, $date))
->filter();
}
public function getMosaicsFor($year, $startWeekNumber)
{
return collect(range(0, 2))
->map(fn($weekDiff) => ProjectMosiacGeneratorJob::handleFor($this, $year, $startWeekNumber - $weekDiff));
}
} }

View file

@ -82,38 +82,5 @@ public function deleteMe()
$this->delete(); $this->delete();
} }
public static function schedule($year, $week)
{
Bus::chain([
Bus::batch(self::getFileDownloadsFor($year, $week)),
Bus::batch(self::getMosiacsFor($year, $week)),
Bus::batch(self::getReport($year, $week)),
]);
}
public static function getFileDownloadsFor($project, $year, $startWeekNumber)
{
$endOfRange = Carbon::now()->setISODate($year, $startWeekNumber)->endOfWeek();
$startOfRange = (clone $endOfRange)->subWeeks(2)->startOfWeek();
$dateRange = CarbonPeriod::create($startOfRange, $endOfRange);
return collect($dateRange)
->map(fn ($date) => ProjectDownloadTiffJob::handleForDate($project, $date))
->filter();
}
public static function getMosaicsFor($project, $year, $startWeekNumber)
{
$jobs = [];
foreach (range(0,2) as $weekDiff) {
$job = ProjectMosiacGeneratorJob::handleFor($project, $year, $startWeekNumber - $weekDiff);
if ($job) {
$jobs[] = $job;
}
}
return $jobs;
}
} }

View file

@ -5,13 +5,13 @@
]) ])
<x-modal wire:model.live="showCreateModal" {{ $attributes }} > <x-modal wire:model.live="showCreateModal" {{ $attributes }} >
<x-form-modal submit="saveMosiac" wire:loading.class="opacity-50"> <x-form-modal submit="saveMosaic" wire:loading.class="opacity-50">
<x-slot name="title"> <x-slot name="title">
{{ __('Project') }} {{ __('Mosaic') }}
</x-slot> </x-slot>
<x-slot name="description"> <x-slot name="description">
{{ __('Report generator for generating reports') }} {{ __('Mosaic generator for generating reports') }}
</x-slot> </x-slot>

View file

@ -98,27 +98,7 @@ public static function reportDateProvider()
]; ];
} }
/** @test */
public function it_can_calculate_mosaic_dependencies()
{
$project = Project::create([
'name' => 'project_name',
'download_path' => 'project_download_path',
]);
$projectReport = $project->reports()->create([
'name' => 'name',
'year' => 2021,
'week' => 25,
'path' => 'path/doc.pdf',
]);
Bus::fake();
$projectReport->schedule();
}
} }

View file

@ -2,6 +2,8 @@
namespace Tests\Unit\Models; namespace Tests\Unit\Models;
use App\Jobs\ProjectDownloadTiffJob;
use App\Jobs\ProjectMosiacGeneratorJob;
use App\Models\Project; use App\Models\Project;
use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\RefreshDatabase;
@ -81,6 +83,7 @@ public function when_not_all_mosaics_are_present_it_should_return_an_exception()
//$lastDate->getWeekOfYear(); //$lastDate->getWeekOfYear();
$project->allMosaicsPresent($lastDate); $project->allMosaicsPresent($lastDate);
} }
/** @test */ /** @test */
public function when_all_mosaics_are_present_it_should_return_true() public function when_all_mosaics_are_present_it_should_return_true()
{ {
@ -116,7 +119,7 @@ public function when_not_mosaics_are_present_it_should_throw_an_exception_listin
$project->allMosaicsPresent($lastDate); $project->allMosaicsPresent($lastDate);
} }
/** @test */ /** @test */
public function when_all_mosaics_are_present_is_called_with_future_date_it_should_throw_an_expection() public function when_all_mosaics_are_present_is_called_with_future_date_it_should_throw_an_expection()
{ {
$this->expectException(\Exception::class); $this->expectException(\Exception::class);
@ -126,7 +129,7 @@ public function when_all_mosaics_are_present_is_called_with_future_date_it_shoul
Carbon::setTestNow(Carbon::parse('2020-01-01')); Carbon::setTestNow(Carbon::parse('2020-01-01'));
$lastDate = Carbon::parse('2021-01-01'); $lastDate = Carbon::parse('2021-01-01');
// stub getMosiacList() to return a list containing four filenames; // stub getMosiacList() to return a list containing four filenames;
($project->allMosaicsPresent($lastDate)); ($project->allMosaicsPresent($lastDate));
} }
/** @test */ /** @test */
@ -144,4 +147,45 @@ public function getMosiacFileListByEndDate_should_return_four_filenames()
"week_50_2020.tif", "week_50_2020.tif",
], $list->toArray()); ], $list->toArray());
} }
/** @test */
public function when_getFileDownloadsFor_is_called_it_returns_a_collection_of_seven_downloads_jobs()
{
$project = Project::create([
'name' => 'project_name',
'download_path' => 'project_download_path',
]);
$downloads = $project->getFileDownloadsFor(2023, 2);
$this->assertCount(3 * 7, $downloads);
$downloads->each(fn($job) => $this->assertInstanceOf(ProjectDownloadTiffJob::class, $job));
}
/** @test */
public function when_getMosaicsFor_is_called_it_returns_a_collection_of_seven_downloads_jobs()
{
$project = Project::create([
'name' => 'project_name',
'download_path' => 'project_download_path',
]);
$mosaics = $project->getMosaicsFor(2023, 2);
$this->assertCount(3, $mosaics);
$mosaics->each(fn($job) => $this->assertInstanceOf(ProjectMosiacGeneratorJob::class, $job));
}
/** @test */
public function it_can_create_a_chain_of_batches_that_result_in_a_report()
{
$project = Project::create([
'name' => 'project_name',
'download_path' => 'project_download_path',
]);
Bus::fake();
$project->scheduleReport(2023, 50);
}
} }