++ gruppi di servizio: utenza dell'ex sorvegliante riattivabile, cestino e anonimizzazione, registro senza nomi
Un ex sorvegliante puo' guidare un gruppo nuovo: si riattiva la sua utenza. Il sorvegliante di un gruppo attivo non si cestina ne' si anonimizza; anonimizzando un ex sorvegliante si anonimizza anche l'utenza. Nel registro delle attivita' nome ed email dell'utenza del sorvegliante diventano "proclamatore #id". La voce "Il mio gruppo" dipende dal ruolo: l'amministratore passa ogni @can. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -77,10 +77,10 @@ class GruppiIndex extends Component
|
||||
->get();
|
||||
|
||||
// Possono diventare sorveglianti i proclamatori attivi senza gruppo e
|
||||
// senza già un'utenza.
|
||||
// senza un'utenza attiva (quella di un gruppo sciolto si riattiva).
|
||||
$candidati = Proclamatore::attivi()
|
||||
->whereNull('gruppo_servizio_id')
|
||||
->whereDoesntHave('utente')
|
||||
->whereDoesntHave('utente', fn ($q) => $q->whereNull('disattivato_at'))
|
||||
->get();
|
||||
|
||||
return view('livewire.gruppi.gruppi-index', [
|
||||
|
||||
@@ -6,6 +6,7 @@ use App\Livewire\Concerns\Avvisa;
|
||||
use Livewire\Attributes\Url;
|
||||
use Livewire\Component;
|
||||
use Livewire\WithPagination;
|
||||
use App\Models\GruppoServizio;
|
||||
use App\Models\Proclamatore;
|
||||
|
||||
class ProclamatoreIndex extends Component
|
||||
@@ -70,7 +71,12 @@ class ProclamatoreIndex extends Component
|
||||
$this->avvisaErrore("Il proclamatore {$proclamatore->nome_completo} ha assegnazioni aperte. Rientra prima i territori.");
|
||||
return;
|
||||
}
|
||||
if ($this->sorveglianteDiUnGruppo($proclamatore, 'spostarlo nel cestino')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Nel cestino non resta membro di un gruppo.
|
||||
$proclamatore->update(['gruppo_servizio_id' => null]);
|
||||
$proclamatore->delete();
|
||||
$this->avvisa("Proclamatore {$proclamatore->nome_completo} spostato nel cestino.");
|
||||
}
|
||||
@@ -80,10 +86,27 @@ class ProclamatoreIndex extends Component
|
||||
$this->authorize('settings.manage');
|
||||
|
||||
$proclamatore = Proclamatore::findOrFail($id);
|
||||
if ($this->sorveglianteDiUnGruppo($proclamatore, 'anonimizzarlo')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$proclamatore->anonimizza();
|
||||
$this->avvisa("Dati personali del proclamatore anonimizzati (GDPR).");
|
||||
}
|
||||
|
||||
/** Il sorvegliante di un gruppo attivo si toglie sciogliendo il gruppo, non da qui. */
|
||||
private function sorveglianteDiUnGruppo(Proclamatore $proclamatore, string $azione): bool
|
||||
{
|
||||
$gruppo = GruppoServizio::attivi()->where('sorvegliante_id', $proclamatore->id)->first();
|
||||
if (! $gruppo) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->avvisaErrore("{$proclamatore->nome_completo} è il sorvegliante del gruppo {$gruppo->nome}: per {$azione} va prima sciolto il gruppo (Gruppi di servizio).");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
// withCount rather than letting the view call
|
||||
|
||||
@@ -108,7 +108,22 @@ class Proclamatore extends Model
|
||||
$this->nome = 'Anonimo';
|
||||
$this->cognome = 'Proclamatore #' . $this->id;
|
||||
$this->attivo = false;
|
||||
$this->gruppo_servizio_id = null;
|
||||
$this->save();
|
||||
$this->delete(); // soft delete
|
||||
|
||||
// L'utenza di un ex sorvegliante (già disattivata: il sorvegliante di
|
||||
// un gruppo attivo non si anonimizza) porta nome ed email in chiaro.
|
||||
$utente = $this->utente()->first();
|
||||
if ($utente) {
|
||||
$utente->syncRoles([]);
|
||||
$utente->forceFill([
|
||||
'name' => 'Anonimo',
|
||||
'email' => "utente-{$utente->id}@anonimo.invalid",
|
||||
'password' => \Illuminate\Support\Str::random(40),
|
||||
'remember_token' => null,
|
||||
'disattivato_at' => $utente->disattivato_at ?? now(),
|
||||
])->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +91,32 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||
->dontSubmitEmptyLogs();
|
||||
}
|
||||
|
||||
/**
|
||||
* L'utenza di un sorvegliante porta nome (ed email, spesso) di un
|
||||
* proclamatore: nel registro delle attività i proclamatori compaiono solo
|
||||
* con l'identificativo, quindi anche qui.
|
||||
*/
|
||||
public function tapActivity(\Spatie\Activitylog\Contracts\Activity $activity, string $eventName): void
|
||||
{
|
||||
$proclamatoreId = $this->proclamatore_id ?? $this->getOriginal('proclamatore_id');
|
||||
if (! $proclamatoreId) {
|
||||
return;
|
||||
}
|
||||
|
||||
$activity->properties = collect($activity->properties)->map(function ($valori) use ($proclamatoreId) {
|
||||
if (! is_array($valori)) {
|
||||
return $valori;
|
||||
}
|
||||
foreach (['name', 'email'] as $campo) {
|
||||
if (array_key_exists($campo, $valori)) {
|
||||
$valori[$campo] = "proclamatore #{$proclamatoreId}";
|
||||
}
|
||||
}
|
||||
|
||||
return $valori;
|
||||
});
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
// Un indirizzo nuovo va confermato di nuovo, chiunque lo cambi.
|
||||
|
||||
@@ -42,28 +42,32 @@ class GruppiServizio
|
||||
if ($sorvegliante->gruppo_servizio_id) {
|
||||
throw new InvalidArgumentException("{$sorvegliante->nome_completo} fa già parte di un altro gruppo.");
|
||||
}
|
||||
if ($sorvegliante->utente()->exists()) {
|
||||
// Chi è stato sorvegliante di un gruppo sciolto ha già un'utenza,
|
||||
// disattivata: si riattiva quella (un proclamatore, un'utenza).
|
||||
$esistente = $sorvegliante->utente()->first();
|
||||
if ($esistente && ! $esistente->isDisattivato()) {
|
||||
throw new InvalidArgumentException("{$sorvegliante->nome_completo} ha già un'utenza.");
|
||||
}
|
||||
if (User::where('email', $email)->exists()) {
|
||||
if (User::where('email', $email)->when($esistente, fn ($q) => $q->whereKeyNot($esistente->id))->exists()) {
|
||||
throw new InvalidArgumentException("L'email {$email} è già usata da un altro utente.");
|
||||
}
|
||||
|
||||
$password = Str::password(12, symbols: false);
|
||||
|
||||
$gruppo = DB::transaction(function () use ($nome, $sorvegliante, $email, $membri, $password) {
|
||||
$gruppo = DB::transaction(function () use ($nome, $sorvegliante, $email, $membri, $password, $esistente) {
|
||||
$gruppo = GruppoServizio::create(['nome' => $nome, 'sorvegliante_id' => $sorvegliante->id]);
|
||||
$sorvegliante->update(['gruppo_servizio_id' => $gruppo->id]);
|
||||
$this->aggiungiMembri($gruppo, $membri);
|
||||
|
||||
$utente = User::create([
|
||||
$utente = $esistente ?? new User(['proclamatore_id' => $sorvegliante->id]);
|
||||
$utente->forceFill([
|
||||
'name' => $sorvegliante->nome_completo,
|
||||
'email' => $email,
|
||||
'password' => $password,
|
||||
'password_change_required' => true,
|
||||
'proclamatore_id' => $sorvegliante->id,
|
||||
]);
|
||||
$utente->assignRole('sorvegliante');
|
||||
'disattivato_at' => null,
|
||||
])->save();
|
||||
$utente->syncRoles(['sorvegliante']);
|
||||
|
||||
activity()->causedBy(auth()->user())->performedOn($gruppo)
|
||||
->withProperties(['sorvegliante_id' => $sorvegliante->id, 'utente_id' => $utente->id])
|
||||
|
||||
Reference in New Issue
Block a user