86 lines
3 KiB
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',
|
|
];
|
|
}
|
|
}
|