SmartCane/laravel_app/app/Models/Project.php
Martin Folkerts eb1def36a1 wip
2023-12-22 16:55:40 +01:00

178 lines
5.1 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
class Project extends Model
{
use HasFactory;
protected $fillable = [
'name',
'mail_template',
'mail_subject',
'mail_frequency',
'mail_day',
'download_path',
];
public static function saveWithFormData(mixed $formData)
{
$uniqueIdentifier = ['id' => $formData['id'] ?? null];
$project = Project::updateOrCreate($uniqueIdentifier, $formData);
$project->upsertBoundingBox($formData);
$project->upsertMailRecipients($formData);
}
private function upsertBoundingBox($formData)
{
$boundingBoxesData = array_map(function ($boundingBox) {
$boundingBox['project_id'] = $this->id;
unset($boundingBox['created_at']);
unset($boundingBox['updated_at']);
$boundingBox['id'] ??= null;
return $boundingBox;
}, $formData['boundingBoxes'] ?? []);
ProjectBoundingBox::upsert(
$boundingBoxesData,
['id', 'project_id'],
[
'name',
'top_left_latitude',
'top_left_longitude',
'bottom_right_latitude',
'bottom_right_longitude'
]
);
}
private function upsertMailRecipients($formData)
{
$mailRecipientsData = array_map(function ($mailRecipient) {
$mailRecipient['project_id'] = $this->id;
unset($mailRecipient['created_at']);
unset($mailRecipient['updated_at']);
$mailRecipient['id'] ??= null;
return $mailRecipient;
}, $formData['mail_recipients'] ?? []);
ProjectEmailRecipient::upsert(
$mailRecipientsData,
['id', 'project_id'],
['name', 'email',]
);
}
private function getMosaicPath()
{
return sprintf('%s/%s', $this->download_path, 'weekly_mosaic');
}
public function getMosaicList(): \Illuminate\Support\Collection
{
return collect(Storage::files($this->getMosaicPath()))
->filter(fn($file) => Str::endsWith($file, '.tif'))
->sortByDesc(function ($file) {
$parts = explode('_', str_replace('.tif', '', $file));
$week = $parts[1];
$year = $parts[2];
return $year.sprintf('%02d', $week);
})
->values();
}
protected static function boot()
{
parent::boot(); // TODO: Change the autogenerated stub
static::deleting(function ($project) {
$project->boundingBoxes()->delete();
$project->emailRecipients()->delete();
$project->mailings()->each(function ($mailing) {
$mailing->attachments()->delete();
$mailing->recipients()->delete();
});
$project->mailings()->delete();
});
}
public function reports()
{
return $this->hasMany(ProjectReport::class);
}
public function getAttachmentPathAttribute()
{
return storage_path(sprintf('%s/attachments', $this->download_path));
return '/storage/'.$this->download_path.'/attachments';
}
public function boundingBoxes()
{
return $this->hasMany(ProjectBoundingBox::class);
}
public function emailRecipients()
{
return $this->hasMany(ProjectEmailRecipient::class);
}
public function mailings()
{
return $this->hasMany(ProjectMailing::class);
}
public function downloads()
{
return $this->hasMany(ProjectDownload::class);
}
public function allMosaicsPresent(Carbon $endDate)
{
// end date is in the future
if ($endDate->isFuture()) {
throw new \Exception('End date is in the future');
}
$mosaicsNotPresentInFilesystem = $this->getMosiacFilenameListByEndDate($endDate)
->filter(function ($filename) {
return !$this->getMosaicList()->contains(function ($mosaicFilename) use ($filename) {
return Str::endsWith( $mosaicFilename, substr($filename, -16));
});
});
if ($mosaicsNotPresentInFilesystem->count() === 0) {
return true;
}
$message = sprintf(
'Missing mosaics: %s',
$mosaicsNotPresentInFilesystem->implode(', ')
);
throw new \Exception($message);
}
public function getMosiacFilenameListByEndDate(Carbon $endDate): \Illuminate\Support\Collection
{
$result = collect([]);
for ($i = 0; $i < 4; $i++) {
$week = $endDate->weekOfYear;
$year = $endDate->year;
if ($week === 53) {
$year--;
}
$result->add(sprintf('week_%02d_%04d.tif', $week, $year));
$endDate = $endDate->subWeek();
}
return $result;
}
}