Il gruppo ha un sorvegliante (proclamatore con utenza: email e password temporanea, senza conferma dell'email) e dei membri; l'amministratore mette in blocco dei territori nel pacchetto del gruppo. Il pacchetto non e' un'assegnazione e non tocca le statistiche; quando il sorvegliante da' un territorio a un membro nasce un'assegnazione normale con gruppo_servizio_id. Al rientro il territorio torna in reparto. Sciogliere il gruppo libera pacchetto e membri e disattiva l'utenza. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
192 lines
6.1 KiB
PHP
192 lines
6.1 KiB
PHP
<?php
|
|
|
|
namespace App\Livewire\Gruppi;
|
|
|
|
use App\Livewire\Concerns\Avvisa;
|
|
use App\Livewire\Concerns\InviaLink;
|
|
use App\Models\Assegnazione;
|
|
use App\Models\GruppoServizio;
|
|
use App\Models\Proclamatore;
|
|
use App\Models\Territorio;
|
|
use App\Services\GruppiServizio;
|
|
use Carbon\Carbon;
|
|
use InvalidArgumentException;
|
|
use Livewire\Attributes\Locked;
|
|
use Livewire\Component;
|
|
|
|
/**
|
|
* "Il mio gruppo": la sola pagina del sorvegliante di gruppo. Vede il
|
|
* pacchetto del suo gruppo e i membri; dà i territori ai membri (o a sé),
|
|
* manda il link, registra i rientri (pagina Rientra), apre la piantina e
|
|
* rimanda in reparto quelli non ancora dati. Le regole stanno in
|
|
* App\Services\GruppiServizio; qui ogni azione ricontrolla che il territorio
|
|
* o l'assegnazione siano del suo gruppo.
|
|
*/
|
|
class MioGruppo extends Component
|
|
{
|
|
use Avvisa;
|
|
use InviaLink;
|
|
|
|
/** Il territorio del pacchetto che si sta assegnando. */
|
|
#[Locked]
|
|
public ?int $territorioDaAssegnare = null;
|
|
|
|
public ?int $membroId = null;
|
|
|
|
public string $dataAssegnazione = '';
|
|
|
|
public function mount(): void
|
|
{
|
|
$this->dataAssegnazione = now()->format('Y-m-d');
|
|
}
|
|
|
|
private function gruppo(): ?GruppoServizio
|
|
{
|
|
return auth()->user()->gruppoSorvegliato();
|
|
}
|
|
|
|
private function gruppoOFallisci(): GruppoServizio
|
|
{
|
|
$gruppo = $this->gruppo();
|
|
abort_unless($gruppo, 403, 'Non sei il sorvegliante di un gruppo di servizio attivo.');
|
|
|
|
return $gruppo;
|
|
}
|
|
|
|
private function territorioDelPacchetto(int $id): Territorio
|
|
{
|
|
$gruppo = $this->gruppoOFallisci();
|
|
$territorio = Territorio::find($id);
|
|
abort_unless($territorio && $territorio->gruppo_servizio_id === $gruppo->id, 403);
|
|
|
|
return $territorio;
|
|
}
|
|
|
|
// ─── Assegnare un territorio del pacchetto ──────────────────
|
|
|
|
public function apriAssegnazione(int $territorioId): void
|
|
{
|
|
$this->territorioDelPacchetto($territorioId);
|
|
$this->territorioDaAssegnare = $territorioId;
|
|
$this->membroId = null;
|
|
$this->dataAssegnazione = now()->format('Y-m-d');
|
|
$this->resetValidation();
|
|
}
|
|
|
|
public function annullaAssegnazione(): void
|
|
{
|
|
$this->reset(['territorioDaAssegnare', 'membroId']);
|
|
$this->resetValidation();
|
|
}
|
|
|
|
public function assegna(): void
|
|
{
|
|
$this->validate([
|
|
'membroId' => 'required|integer',
|
|
'dataAssegnazione' => 'required|date|before_or_equal:today',
|
|
], [
|
|
'membroId.required' => 'Scegli a chi dare il territorio.',
|
|
'dataAssegnazione.before_or_equal' => 'La data non può essere nel futuro.',
|
|
]);
|
|
|
|
$gruppo = $this->gruppoOFallisci();
|
|
$territorio = $this->territorioDelPacchetto((int) $this->territorioDaAssegnare);
|
|
$membro = Proclamatore::find($this->membroId);
|
|
|
|
if (! $membro) {
|
|
$this->addError('membroId', 'Scegli un membro del gruppo.');
|
|
|
|
return;
|
|
}
|
|
|
|
try {
|
|
$assegnazione = app(GruppiServizio::class)->assegna($gruppo, $territorio, $membro, Carbon::parse($this->dataAssegnazione));
|
|
} catch (InvalidArgumentException $e) {
|
|
$this->addError('membroId', $e->getMessage());
|
|
|
|
return;
|
|
}
|
|
|
|
$this->reset(['territorioDaAssegnare', 'membroId']);
|
|
|
|
// Come dalla pagina Assegna: si apre l'invio del link.
|
|
$this->apriInvio($assegnazione->id);
|
|
}
|
|
|
|
// ─── Rimandare in reparto ───────────────────────────────────
|
|
|
|
public function rimanda(int $territorioId): void
|
|
{
|
|
$territorio = $this->territorioDelPacchetto($territorioId);
|
|
|
|
try {
|
|
app(GruppiServizio::class)->rimandaInReparto($this->gruppoOFallisci(), $territorio);
|
|
} catch (InvalidArgumentException $e) {
|
|
$this->avvisaErrore($e->getMessage());
|
|
|
|
return;
|
|
}
|
|
|
|
$this->avvisa("Territorio {$territorio->numero} rimandato in reparto.");
|
|
}
|
|
|
|
// ─── Link già inviato / condiviso dall'elenco ───────────────
|
|
|
|
private function assegnazioneDelGruppo(int $id): Assegnazione
|
|
{
|
|
$assegnazione = Assegnazione::aperte()->with('territorio')->find($id);
|
|
abort_unless($assegnazione && $this->puoInviare($assegnazione), 403);
|
|
|
|
return $assegnazione;
|
|
}
|
|
|
|
public function toggleLinkSent(int $assegnazioneId): void
|
|
{
|
|
$assegnazione = $this->assegnazioneDelGruppo($assegnazioneId);
|
|
$assegnazione->registraInvioLink(! $assegnazione->link_sent, $assegnazione->link_canale);
|
|
}
|
|
|
|
/** "Condividi" dall'elenco andato a buon fine (elencoCercabile.condividi). */
|
|
public function segnaCondiviso(int $assegnazioneId): void
|
|
{
|
|
$this->assegnazioneDelGruppo($assegnazioneId)->registraInvioLink(true, 'condividi');
|
|
}
|
|
|
|
// ─── Invio del link (trait InviaLink) ───────────────────────
|
|
|
|
protected function puoInviare(Assegnazione $assegnazione): bool
|
|
{
|
|
$gruppo = $this->gruppo();
|
|
|
|
return $gruppo !== null
|
|
&& ($assegnazione->gruppo_servizio_id === $gruppo->id
|
|
|| $assegnazione->territorio?->gruppo_servizio_id === $gruppo->id);
|
|
}
|
|
|
|
protected function paginaDopoInvio(): string
|
|
{
|
|
return route('mio-gruppo');
|
|
}
|
|
|
|
public function render()
|
|
{
|
|
$gruppo = $this->gruppo();
|
|
|
|
$territori = $gruppo
|
|
? $gruppo->territori()->with(['zona', 'assegnazioneCorrente.proclamatore'])->get()->sortBy('numero', SORT_NATURAL)->values()
|
|
: collect();
|
|
|
|
$membri = $gruppo
|
|
? $gruppo->membri()->where('attivo', true)->get()->sortBy(fn ($p) => mb_strtolower($p->cognome . ' ' . $p->nome))->values()
|
|
: collect();
|
|
|
|
return view('livewire.gruppi.mio-gruppo', [
|
|
'gruppo' => $gruppo,
|
|
'territori' => $territori,
|
|
'membri' => $membri,
|
|
'opzioniMembri' => Proclamatore::opzioniScelta($membri),
|
|
'invio' => $this->invioCorrente(),
|
|
]);
|
|
}
|
|
}
|