Files
termanager2/app/Livewire/Gruppi/GruppoShow.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

148 lines
4.9 KiB
PHP

<?php
namespace App\Livewire\Gruppi;
use App\Livewire\Concerns\Avvisa;
use App\Livewire\Concerns\RicordaRitorno;
use App\Models\GruppoServizio;
use App\Models\Proclamatore;
use App\Models\Territorio;
use App\Models\User;
use App\Services\GruppiServizio;
use Illuminate\Support\Str;
use InvalidArgumentException;
use Livewire\Attributes\Locked;
use Livewire\Component;
/**
* Un gruppo di servizio, lato amministratore: membri (aggiungere/togliere),
* pacchetto (aggiungere in blocco, rimandare in reparto quelli non dati),
* nuova password temporanea per il sorvegliante, scioglimento.
*/
class GruppoShow extends Component
{
use Avvisa;
use RicordaRitorno;
public GruppoServizio $gruppo;
/** @var int[] proclamatori da aggiungere */
public array $nuoviMembri = [];
/** @var int[] territori da aggiungere al pacchetto */
public array $nuoviTerritori = [];
#[Locked]
public ?string $passwordTemporanea = null;
public function mount(GruppoServizio $gruppo): void
{
$this->gruppo = $gruppo;
}
private function servizio(): GruppiServizio
{
$this->authorize('settings.manage');
return app(GruppiServizio::class);
}
private function esegui(callable $azione, string $ok): void
{
try {
$azione();
} catch (InvalidArgumentException $e) {
$this->avvisaErrore($e->getMessage());
return;
}
$this->gruppo->refresh();
$this->avvisa($ok);
}
public function aggiungiMembri(): void
{
$ids = array_map('intval', $this->nuoviMembri);
if ($ids === []) {
$this->avvisaErrore('Spunta almeno un proclamatore.');
return;
}
$this->esegui(fn () => $this->servizio()->aggiungiMembri($this->gruppo, $ids), count($ids) . ' membri aggiunti.');
$this->nuoviMembri = [];
}
public function togliMembro(int $proclamatoreId): void
{
$membro = Proclamatore::findOrFail($proclamatoreId);
$this->esegui(fn () => $this->servizio()->togliMembro($this->gruppo, $membro), "{$membro->nome_completo} tolto dal gruppo.");
}
public function aggiungiTerritori(): void
{
$ids = array_map('intval', $this->nuoviTerritori);
if ($ids === []) {
$this->avvisaErrore('Spunta almeno un territorio.');
return;
}
$this->esegui(fn () => $this->servizio()->aggiungiAlPacchetto($this->gruppo, $ids), count($ids) . ' territori aggiunti al pacchetto.');
$this->nuoviTerritori = [];
}
public function rimanda(int $territorioId): void
{
$territorio = Territorio::findOrFail($territorioId);
$this->esegui(fn () => $this->servizio()->rimandaInReparto($this->gruppo, $territorio), "Territorio {$territorio->numero} rimandato in reparto.");
}
/** Il sorvegliante ha perso la password: una nuova temporanea, da cambiare al primo accesso. */
public function nuovaPassword(): void
{
$this->servizio();
$utente = User::where('proclamatore_id', $this->gruppo->sorvegliante_id)->first();
if (! $utente) {
$this->avvisaErrore('Il gruppo non ha un sorvegliante con utenza attiva.');
return;
}
$password = Str::password(12, symbols: false);
$utente->forceFill(['password' => $password, 'password_change_required' => true])->save();
activity()->causedBy(auth()->user())->performedOn($utente)->log('password_reimpostata');
$this->passwordTemporanea = $password;
}
/**
* Toglie il ruolo di sorvegliante: il gruppo si scioglie e si elimina, si
* torna all'elenco dei gruppi.
*/
public function sciogli()
{
$nome = $this->gruppo->nome;
$this->servizio()->sciogli($this->gruppo);
session()->flash('success', "Gruppo {$nome} sciolto: i territori non ancora dati sono tornati in reparto e l'utenza del sorvegliante è disattivata.");
return $this->redirect(route('gruppi.index'), navigate: true);
}
public function render()
{
$this->gruppo->load(['sorvegliante.utente']);
$membri = $this->gruppo->membri()->get()->sortBy(fn ($p) => mb_strtolower($p->cognome . ' ' . $p->nome))->values();
$territori = $this->gruppo->territori()->with(['zona', 'assegnazioneCorrente.proclamatore'])->get()->sortBy('numero', SORT_NATURAL)->values();
return view('livewire.gruppi.gruppo-show', [
'membri' => $membri,
'territori' => $territori,
// Si possono aggiungere i proclamatori attivi senza gruppo...
'candidatiMembri' => Proclamatore::attivi()->whereNull('gruppo_servizio_id')->get()->sortBy(fn ($p) => mb_strtolower($p->cognome . ' ' . $p->nome))->values(),
// ...e i territori in reparto (attivi, non assegnati, fuori da ogni pacchetto).
'candidatiTerritori' => Territorio::inReparto()->with('zona')->get()->sortBy('numero', SORT_NATURAL)->values(),
]);
}
}