pp-planer/app/Services/MacroResolutionService.php

86 lines
3 KiB
PHP

<?php
namespace App\Services;
use App\Models\Macro;
use App\Models\MacroAssignment;
use App\Models\Service;
use App\Models\ServiceMacroAssignment;
use App\Models\ServiceMacroOverride;
use Illuminate\Support\Collection;
class MacroResolutionService
{
/**
* Returns active (non-hidden) assignments for a given service + part type.
* Uses service-specific assignments if an override exists, otherwise global defaults.
*/
public function resolveAssignmentsForPart(Service $service, string $partType): Collection
{
$hasOverride = ServiceMacroOverride::where('service_id', $service->id)
->where('part_type', $partType)
->exists();
if ($hasOverride) {
$rows = ServiceMacroAssignment::with(['macro', 'label'])
->where('service_id', $service->id)
->where('part_type', $partType)
->orderBy('order')
->get();
} else {
$rows = MacroAssignment::with(['macro', 'label'])
->where('part_type', $partType)
->orderBy('order')
->get();
}
return $rows
->reject(fn ($r) => $r->macro === null || $r->macro->isHidden())
->reject(fn ($r) => $r->position === 'by_label' && ($r->label === null || $r->label->isHidden()));
}
/**
* Returns the macro export data for macros that apply to a specific slide.
*
* @param array $slideContext ['index' => int, 'total' => int, 'label_id' => int|null]
* @return array<int, array{name: string, uuid: string, collectionName: string, collectionUuid: string}>
*/
public function macrosForSlide(Service $service, string $partType, array $slideContext): array
{
$assignments = $this->resolveAssignmentsForPart($service, $partType);
$matched = $assignments->filter(function ($a) use ($slideContext) {
return match ($a->position) {
'all_slides' => true,
'first_slide' => $slideContext['index'] === 0,
'last_slide' => $slideContext['index'] === $slideContext['total'] - 1,
'by_label' => isset($slideContext['label_id'])
&& (int) $a->label_id === (int) $slideContext['label_id'],
default => false,
};
});
return $matched->map(fn ($a) => $this->toExportArray($a->macro))->values()->all();
}
/**
* Returns the count of active assignments for a service + part (for UI badges).
*/
public function countAssignmentsForPart(Service $service, string $partType): int
{
return $this->resolveAssignmentsForPart($service, $partType)->count();
}
private function toExportArray(Macro $macro): array
{
$collection = $macro->collections()->first();
return [
'name' => $macro->name,
'uuid' => $macro->uuid,
'collectionName' => $collection?->name ?? '--MAIN--',
'collectionUuid' => $collection?->uuid ?? '8D02FC57-83F8-4042-9B90-81C229728426',
];
}
}