Files
fotospiel-app/app/Services/Tenant/TaskCollectionImportService.php
Codex Agent 1a4bdb1fe1 tenant admin startseite schicker gestaltet und super-admin und tenant admin (filament) aufgesplittet.
Es gibt nun task collections und vordefinierte tasks für alle. Onboarding verfeinert und webseite-carousel gefixt (logging später entfernen!)
2025-10-14 15:17:52 +02:00

162 lines
5.4 KiB
PHP

<?php
namespace App\Services\Tenant;
use App\Models\Event;
use App\Models\Task;
use App\Models\TaskCollection;
use Illuminate\Database\DatabaseManager;
use Illuminate\Support\Str;
use RuntimeException;
class TaskCollectionImportService
{
public function __construct(private readonly DatabaseManager $db)
{
}
/**
* @return array{collection: TaskCollection, created_task_ids: array<int>, attached_task_ids: array<int>}
*/
public function import(TaskCollection $collection, Event $event): array
{
if ($collection->tenant_id && $collection->tenant_id !== $event->tenant_id) {
throw new RuntimeException('Task collection is not accessible for this tenant.');
}
$collection->loadMissing('tasks');
return $this->db->transaction(function () use ($collection, $event) {
$tenantId = $event->tenant_id;
$targetCollection = $this->resolveTenantCollection($collection, $tenantId);
$createdTaskIds = [];
$attachedTaskIds = [];
foreach ($collection->tasks as $task) {
$tenantTask = $this->resolveTenantTask($task, $targetCollection, $tenantId);
if ($tenantTask->wasRecentlyCreated) {
$createdTaskIds[] = $tenantTask->id;
}
if (! $tenantTask->assignedEvents()->where('event_id', $event->id)->exists()) {
$tenantTask->assignedEvents()->attach($event->id);
$attachedTaskIds[] = $tenantTask->id;
}
}
$event->taskCollections()->syncWithoutDetaching([
$targetCollection->id => ['sort_order' => $targetCollection->position ?? 0],
]);
return [
'collection' => $targetCollection->fresh(),
'created_task_ids' => $createdTaskIds,
'attached_task_ids' => $attachedTaskIds,
];
});
}
protected function resolveTenantCollection(TaskCollection $collection, int $tenantId): TaskCollection
{
if ($collection->tenant_id === $tenantId) {
return $collection;
}
$existing = TaskCollection::query()
->where('tenant_id', $tenantId)
->where('source_collection_id', $collection->id)
->first();
if ($existing) {
return $existing;
}
return TaskCollection::create([
'tenant_id' => $tenantId,
'source_collection_id' => $collection->id,
'event_type_id' => $collection->event_type_id,
'slug' => $this->buildCollectionSlug($collection->slug, $tenantId),
'name_translations' => $collection->name_translations,
'description_translations' => $collection->description_translations,
'is_default' => false,
'position' => $collection->position,
]);
}
protected function resolveTenantTask(Task $templateTask, TaskCollection $targetCollection, int $tenantId): Task
{
if ($templateTask->tenant_id === $tenantId) {
if ($templateTask->collection_id !== $targetCollection->id) {
$templateTask->update(['collection_id' => $targetCollection->id]);
}
return $templateTask;
}
$sourceId = $templateTask->source_task_id ?: $templateTask->id;
$existing = Task::query()
->where('tenant_id', $tenantId)
->where('source_task_id', $sourceId)
->first();
if ($existing) {
$existing->update([
'collection_id' => $targetCollection->id,
'source_collection_id' => $templateTask->source_collection_id ?: $targetCollection->source_collection_id ?: $targetCollection->id,
]);
return tap($existing)->refresh();
}
$slugBase = $templateTask->slug ?: ($templateTask->title['en'] ?? $templateTask->title['de'] ?? 'task');
$slug = $this->buildTaskSlug($slugBase);
$cloned = Task::create([
'tenant_id' => $tenantId,
'slug' => $slug,
'emotion_id' => $templateTask->emotion_id,
'event_type_id' => $templateTask->event_type_id,
'title' => $templateTask->title,
'description' => $templateTask->description,
'example_text' => $templateTask->example_text,
'due_date' => null,
'is_completed' => false,
'priority' => $templateTask->priority,
'collection_id' => $targetCollection->id,
'difficulty' => $templateTask->difficulty,
'sort_order' => $templateTask->sort_order,
'is_active' => true,
'source_task_id' => $sourceId,
'source_collection_id' => $templateTask->source_collection_id ?: $templateTask->collection_id,
]);
return $cloned;
}
protected function buildCollectionSlug(?string $slug, int $tenantId): string
{
$base = Str::slug(($slug ?: 'collection') . '-' . $tenantId);
do {
$candidate = $base . '-' . Str::random(4);
} while (TaskCollection::where('slug', $candidate)->exists());
return $candidate;
}
protected function buildTaskSlug(string $base): string
{
$slugBase = Str::slug($base) ?: 'task';
do {
$candidate = $slugBase . '-' . Str::random(6);
} while (Task::where('slug', $candidate)->exists());
return $candidate;
}
}