- Proclamatore::booted: reso non attivo, spostato nel cestino o anonimizzato, il sorvegliante scioglie il gruppo (territori non dati in reparto, membri liberi, utenza disattivata); il motivo va nel registro. L'elenco chiede conferma, la modifica avvisa sotto "Attivo". Un membro nel cestino esce dal gruppo. - Scheda del proclamatore: gruppo guidato con membri, pacchetto, da dare, assegnazioni dal gruppo, utenza e ultimo accesso; oppure gruppo di cui e' membro; gruppi sciolti guidati in passato. - Profilo del sorvegliante: il suo gruppo con gli stessi numeri. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
96 lines
2.9 KiB
PHP
96 lines
2.9 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.
|
|
*
|
|
* Un gruppo sciolto (sciolto_at) non ha più membri né pacchetto, ma resta: le
|
|
* assegnazioni nate da lui continuano a citarlo. Logica in
|
|
* App\Services\GruppiServizio.
|
|
*/
|
|
class GruppoServizio extends Model
|
|
{
|
|
use LogsActivity;
|
|
|
|
protected $table = 'gruppi_servizio';
|
|
|
|
protected $fillable = ['nome', 'sorvegliante_id', 'sciolto_at'];
|
|
|
|
protected function casts(): array
|
|
{
|
|
return ['sciolto_at' => 'datetime', 'sorvegliante_id' => 'integer'];
|
|
}
|
|
|
|
public function getActivitylogOptions(): LogOptions
|
|
{
|
|
return LogOptions::defaults()
|
|
->logOnly(['nome', 'sorvegliante_id', 'sciolto_at'])
|
|
->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');
|
|
}
|
|
|
|
public function getScioltoAttribute(): bool
|
|
{
|
|
return $this->sciolto_at !== null;
|
|
}
|
|
|
|
public function scopeAttivi($query)
|
|
{
|
|
return $query->whereNull('sciolto_at');
|
|
}
|
|
|
|
/**
|
|
* 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(),
|
|
];
|
|
}
|
|
}
|