94 lines
4.0 KiB
PHP
94 lines
4.0 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\Collection;
|
|
use App\Models\User;
|
|
use App\Services\CollectionHealthService;
|
|
use App\Services\CollectionHistoryService;
|
|
use App\Services\CollectionQualityService;
|
|
use Illuminate\Validation\ValidationException;
|
|
|
|
class CollectionWorkflowService
|
|
{
|
|
public function __construct(
|
|
private readonly CollectionHealthService $health,
|
|
) {
|
|
}
|
|
|
|
public function update(Collection $collection, array $attributes, ?User $actor = null): Collection
|
|
{
|
|
$nextWorkflow = isset($attributes['workflow_state']) ? (string) $attributes['workflow_state'] : (string) $collection->workflow_state;
|
|
$this->assertTransition((string) $collection->workflow_state, $nextWorkflow);
|
|
|
|
$before = [
|
|
'workflow_state' => $collection->workflow_state,
|
|
'program_key' => $collection->program_key,
|
|
'partner_key' => $collection->partner_key,
|
|
'experiment_key' => $collection->experiment_key,
|
|
'placement_eligibility' => (bool) $collection->placement_eligibility,
|
|
];
|
|
|
|
$collection->forceFill([
|
|
'workflow_state' => $nextWorkflow !== '' ? $nextWorkflow : null,
|
|
'program_key' => array_key_exists('program_key', $attributes) ? ($attributes['program_key'] ?: null) : $collection->program_key,
|
|
'partner_key' => array_key_exists('partner_key', $attributes) ? ($attributes['partner_key'] ?: null) : $collection->partner_key,
|
|
'experiment_key' => array_key_exists('experiment_key', $attributes) ? ($attributes['experiment_key'] ?: null) : $collection->experiment_key,
|
|
'placement_eligibility' => array_key_exists('placement_eligibility', $attributes) ? (bool) $attributes['placement_eligibility'] : $collection->placement_eligibility,
|
|
])->save();
|
|
|
|
$fresh = $this->health->refresh($collection->fresh(), $actor, 'workflow');
|
|
|
|
app(CollectionHistoryService::class)->record(
|
|
$fresh,
|
|
$actor,
|
|
'workflow_updated',
|
|
'Collection workflow updated.',
|
|
$before,
|
|
[
|
|
'workflow_state' => $fresh->workflow_state,
|
|
'program_key' => $fresh->program_key,
|
|
'partner_key' => $fresh->partner_key,
|
|
'experiment_key' => $fresh->experiment_key,
|
|
'placement_eligibility' => (bool) $fresh->placement_eligibility,
|
|
]
|
|
);
|
|
|
|
return $fresh;
|
|
}
|
|
|
|
public function qualityRefresh(Collection $collection, ?User $actor = null): Collection
|
|
{
|
|
$collection = app(CollectionQualityService::class)->sync($collection->fresh());
|
|
$collection = $this->health->refresh($collection, $actor, 'quality-refresh');
|
|
$collection = app(CollectionRankingService::class)->refresh($collection);
|
|
|
|
app(CollectionHistoryService::class)->record($collection, $actor, 'quality_refreshed', 'Collection quality and ranking refreshed.');
|
|
|
|
return $collection;
|
|
}
|
|
|
|
private function assertTransition(string $current, string $next): void
|
|
{
|
|
if ($next === '' || $next === $current) {
|
|
return;
|
|
}
|
|
|
|
$allowed = [
|
|
'' => [Collection::WORKFLOW_DRAFT, Collection::WORKFLOW_APPROVED],
|
|
Collection::WORKFLOW_DRAFT => [Collection::WORKFLOW_IN_REVIEW, Collection::WORKFLOW_APPROVED],
|
|
Collection::WORKFLOW_IN_REVIEW => [Collection::WORKFLOW_DRAFT, Collection::WORKFLOW_APPROVED],
|
|
Collection::WORKFLOW_APPROVED => [Collection::WORKFLOW_PROGRAMMED, Collection::WORKFLOW_ARCHIVED, Collection::WORKFLOW_IN_REVIEW],
|
|
Collection::WORKFLOW_PROGRAMMED => [Collection::WORKFLOW_APPROVED, Collection::WORKFLOW_ARCHIVED],
|
|
Collection::WORKFLOW_ARCHIVED => [Collection::WORKFLOW_APPROVED],
|
|
];
|
|
|
|
if (! in_array($next, $allowed[$current] ?? [], true)) {
|
|
throw ValidationException::withMessages([
|
|
'workflow_state' => 'This workflow transition is not allowed.',
|
|
]);
|
|
}
|
|
}
|
|
} |