Implement EAV system for dynamic event-specific registration fields with organisation-level templates, person section preferences with priority ranking, and TagSyncService for deferred tag_picker sync. New tables: registration_field_templates, registration_form_fields, person_field_values, person_section_preferences. New columns: persons.remarks, events.registration_show_section_preferences, events.registration_show_availability. 58 tests, 126 assertions — all 432 tests pass (zero regressions). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
52 lines
1.5 KiB
PHP
52 lines
1.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\Person;
|
|
use App\Models\PersonSectionPreference;
|
|
use Illuminate\Support\Collection;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
final class PersonSectionPreferenceService
|
|
{
|
|
public function getPreferences(Person $person): Collection
|
|
{
|
|
return PersonSectionPreference::where('person_id', $person->id)
|
|
->with('festivalSection')
|
|
->orderBy('priority')
|
|
->get();
|
|
}
|
|
|
|
public function replacePreferences(Person $person, array $preferences): void
|
|
{
|
|
$old = PersonSectionPreference::where('person_id', $person->id)->get()->toArray();
|
|
|
|
DB::transaction(function () use ($person, $preferences): void {
|
|
PersonSectionPreference::where('person_id', $person->id)->delete();
|
|
|
|
foreach ($preferences as $pref) {
|
|
PersonSectionPreference::create([
|
|
'person_id' => $person->id,
|
|
'festival_section_id' => $pref['festival_section_id'],
|
|
'priority' => $pref['priority'],
|
|
]);
|
|
}
|
|
});
|
|
|
|
$activityLogger = activity('section_preferences')
|
|
->performedOn($person)
|
|
->withProperties([
|
|
'old' => $old,
|
|
'attributes' => $preferences,
|
|
]);
|
|
|
|
if (auth()->user()) {
|
|
$activityLogger->causedBy(auth()->user());
|
|
}
|
|
|
|
$activityLogger->log('person.section_preferences.replaced');
|
|
}
|
|
}
|