5.2: gemeinsamen Firmen-Sync-Kern als User::syncCompaniesWithRoles() gezogen
Analyse der beiden ~40/160-Zeilen-save()-Methoden (users/create vs edit): sie teilen nur den User-Attribut-Payload und den byte-identischen Firmen-Sync-Loop (Bearbeiten hat zusaetzlich Profil/Kontakte/volle Billing-CRUD). Ein voller UserUpsertService waere Over-Engineering (ueberwiegend Branches) — daher nur der wirklich gemeinsame Persistenz-Kern: User::syncCompaniesWithRoles(array $companyIds, array $roles) baut das Pivot-Payload (fehlende Rolle => 'member') und synct. Beide Formulare nutzen es; im Bearbeiten kommen die linkedCompanyIds nun direkt aus $validated. Test: UserSyncCompaniesTest (Rollen-Zuordnung, member-Default, Detach). 29 User-Tests gruen. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6b1d84fc01
commit
1729e35943
4 changed files with 57 additions and 15 deletions
|
|
@ -482,4 +482,23 @@ class User extends Authenticatable implements MustVerifyEmail
|
|||
|
||||
return in_array($companyId, $this->accessibleCompanyIds(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronisiert die Firmenzuordnungen samt Pivot-Rolle. Fehlt zu einer
|
||||
* Firma eine Rolle, greift 'member'. Gemeinsamer Persistenz-Kern des
|
||||
* Anlegen- und Bearbeiten-Formulars (admin/users).
|
||||
*
|
||||
* @param list<int|string> $companyIds
|
||||
* @param array<int|string, string> $roles companyId => role
|
||||
*/
|
||||
public function syncCompaniesWithRoles(array $companyIds, array $roles): void
|
||||
{
|
||||
$payload = [];
|
||||
|
||||
foreach ($companyIds as $companyId) {
|
||||
$payload[$companyId] = ['role' => $roles[$companyId] ?? 'member'];
|
||||
}
|
||||
|
||||
$this->companies()->sync($payload);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,13 +127,7 @@ new #[Layout('components.layouts.app'), Title('Benutzer anlegen')] class extends
|
|||
|
||||
$user->syncRoles($validated['selectedRoles']);
|
||||
|
||||
$companySyncPayload = [];
|
||||
foreach ($validated['linkedCompanyIds'] as $companyId) {
|
||||
$companySyncPayload[$companyId] = [
|
||||
'role' => $validated['companyRoles'][$companyId] ?? 'member',
|
||||
];
|
||||
}
|
||||
$user->companies()->sync($companySyncPayload);
|
||||
$user->syncCompaniesWithRoles($validated['linkedCompanyIds'], $validated['companyRoles']);
|
||||
|
||||
if ($this->billingIsComplete()) {
|
||||
$user->billingAddress()->create([
|
||||
|
|
|
|||
|
|
@ -447,15 +447,9 @@ new #[Layout('components.layouts.app'), Title('Benutzer bearbeiten')] class exte
|
|||
$user->profile()->delete();
|
||||
}
|
||||
|
||||
$companySyncPayload = [];
|
||||
foreach ($validated['linkedCompanyIds'] as $companyId) {
|
||||
$companySyncPayload[$companyId] = [
|
||||
'role' => $validated['companyRoles'][$companyId] ?? 'member',
|
||||
];
|
||||
}
|
||||
$user->companies()->sync($companySyncPayload);
|
||||
$user->syncCompaniesWithRoles($validated['linkedCompanyIds'], $validated['companyRoles']);
|
||||
|
||||
$linkedCompanyIds = array_keys($companySyncPayload);
|
||||
$linkedCompanyIds = $validated['linkedCompanyIds'];
|
||||
|
||||
$contactIds = collect($validated['contactForms'])
|
||||
->pluck('id')
|
||||
|
|
|
|||
35
tests/Feature/UserSyncCompaniesTest.php
Normal file
35
tests/Feature/UserSyncCompaniesTest.php
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
use App\Models\Company;
|
||||
use App\Models\User;
|
||||
|
||||
test('syncCompaniesWithRoles attaches companies with their pivot role', function () {
|
||||
$user = User::factory()->create();
|
||||
$a = Company::factory()->create();
|
||||
$b = Company::factory()->create();
|
||||
|
||||
$user->syncCompaniesWithRoles([$a->id, $b->id], [$a->id => 'owner', $b->id => 'responsible']);
|
||||
|
||||
expect($user->companies()->pluck('role', 'companies.id')->all())
|
||||
->toBe([$a->id => 'owner', $b->id => 'responsible']);
|
||||
});
|
||||
|
||||
test('syncCompaniesWithRoles defaults missing roles to member', function () {
|
||||
$user = User::factory()->create();
|
||||
$company = Company::factory()->create();
|
||||
|
||||
$user->syncCompaniesWithRoles([$company->id], []);
|
||||
|
||||
expect($user->companies()->first()->pivot->role)->toBe('member');
|
||||
});
|
||||
|
||||
test('syncCompaniesWithRoles detaches companies no longer listed', function () {
|
||||
$user = User::factory()->create();
|
||||
$a = Company::factory()->create();
|
||||
$b = Company::factory()->create();
|
||||
$user->syncCompaniesWithRoles([$a->id, $b->id], []);
|
||||
|
||||
$user->syncCompaniesWithRoles([$b->id], [$b->id => 'owner']);
|
||||
|
||||
expect($user->companies()->pluck('companies.id')->all())->toBe([$b->id]);
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue