Files
termanager2/app/Models/GruppoServizio.php
Francesco Picone aaffeb7de7 ++ gruppi: il gruppo sciolto si elimina; il sorvegliante entra con un nome utente dal nome del gruppo
- Sciolto, il gruppo non resta nello storico: si elimina (via sciolto_at;
  la migrazione elimina anche quelli gia' sciolti). I territori solo nel
  pacchetto tornano in reparto; quelli gia' dati restano ai membri, e
  l'assegnazione conserva il nome del gruppo (assegnazioni.gruppo_nome).
- Creando il gruppo non si chiede l'email: users.username dal nome del
  gruppo ("Gruppo Zisa" -> gruppo.zisa), users.email facoltativa. Login con
  "Email o nome utente". Nome del gruppo unico.
- Sciolto il gruppo il nome utente si libera (l'utenza disattivata prende
  ex.sorvegliante.<id>). XML: nome utente e gruppo_nome.
- Profilo, testata, cambio password e Utenti mostrano il nome utente dove
  manca l'email. Informativa privacy, README, HANDOFF e test aggiornati.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 11:45:00 +02:00

86 lines
2.7 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Traits\LogsActivity;
/**
* Gruppo di servizio: un sorvegliante (proclamatore con un'utenza limitata
* al gruppo), i membri (proclamatori, un solo gruppo a testa) e un pacchetto
* di territori che il sorvegliante distribuisce ai membri.
*
* Il pacchetto non è un'assegnazione: un territorio del pacchetto non ancora
* dato a nessuno è "in carico al gruppo" e non entra nelle statistiche. Quando
* il sorvegliante lo dà a un membro nasce un'assegnazione normale, con
* gruppo_servizio_id per dire da dove viene. Al rientro il territorio torna in
* reparto ed esce dal pacchetto.
*
* Sciolto, il gruppo si elimina: non resta nello storico (decisione del 20
* ottobre 2026). Le assegnazioni già date dal sorvegliante ne conservano solo
* il nome (assegnazioni.gruppo_nome). Logica in App\Services\GruppiServizio.
*/
class GruppoServizio extends Model
{
use LogsActivity;
protected $table = 'gruppi_servizio';
protected $fillable = ['nome', 'sorvegliante_id'];
protected function casts(): array
{
return ['sorvegliante_id' => 'integer'];
}
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->logOnly(['nome', 'sorvegliante_id'])
->logOnlyDirty()
->dontSubmitEmptyLogs();
}
public function sorvegliante()
{
return $this->belongsTo(Proclamatore::class, 'sorvegliante_id')->withTrashed();
}
public function membri()
{
return $this->hasMany(Proclamatore::class, 'gruppo_servizio_id');
}
/** Il pacchetto: i territori in carico al gruppo, dati o non ancora dati. */
public function territori()
{
return $this->hasMany(Territorio::class, 'gruppo_servizio_id');
}
public function assegnazioni()
{
return $this->hasMany(Assegnazione::class, 'gruppo_servizio_id');
}
/**
* I numeri del gruppo per la scheda del proclamatore e il profilo del
* sorvegliante: solo conteggi in SQL, nessun nome da decifrare.
*
* @return array{membri: int, pacchetto: int, da_dare: int, dati: int, assegnazioni: int}
*/
public function riepilogo(): array
{
$pacchetto = $this->territori()->count();
$dati = $this->territori()->whereHas('assegnazioni', fn ($q) => $q->whereNull('returned_at'))->count();
return [
'membri' => $this->membri()->count(),
'pacchetto' => $pacchetto,
'da_dare' => $pacchetto - $dati,
'dati' => $dati,
'assegnazioni' => $this->assegnazioni()->count(),
];
}
}