++ gruppi di servizio: sorvegliante con utenza limitata, pacchetto di territori, assegnazione ai membri
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>
This commit is contained in:
191
app/Livewire/Gruppi/MioGruppo.php
Normal file
191
app/Livewire/Gruppi/MioGruppo.php
Normal file
@@ -0,0 +1,191 @@
|
||||
<?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(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user