From 223d44300c950af209bc3b8a82edf2e24c489dfd Mon Sep 17 00:00:00 2001 From: Francesco Picone Date: Mon, 19 Oct 2026 10:18:09 +0200 Subject: [PATCH] ++ fix statistiche campagne MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Dettaglio campagna: mostra tutti i territori conteggiati (stessa base della percentuale), non solo quelli assegnati dopo l'inizio. - Rientro: se più campagne corrispondono propone la più recente invece della prima creata; testo del banner chiarito. - Dettaglio campagna: nuova sezione "In corso" con i territori fuori durante la campagna e non ancora rientrati. - README: regola di conteggio documentata. Co-Authored-By: Claude Opus 5.5 --- README.md | 12 +++++-- app/Livewire/Campagne/CampagnaShow.php | 24 +++++++++---- app/Models/Assegnazione.php | 12 +++++-- app/Models/Campagna.php | 10 ++++++ .../livewire/assegnazioni/rientra.blade.php | 6 ++-- .../livewire/campagne/campagna-show.blade.php | 36 +++++++++++++++++++ 6 files changed, 87 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index c8ab211..491e9c2 100644 --- a/README.md +++ b/README.md @@ -684,8 +684,16 @@ sempre** sul flag: l'amministratore può aggiungere priorità, non toglierla quando la soglia è scattata. ### Percentuale di percorrenza delle campagne -- **Denominatore**: tutti i territori assegnati nel periodo della campagna -- **Numeratore**: le assegnazioni contrassegnate come conteggiate +- **Denominatore**: tutti i territori attivi +- **Numeratore**: le assegnazioni collegate alla campagna e contrassegnate come + conteggiate al rientro + +Al rientro la campagna viene proposta se il territorio era fuori almeno in +parte del periodo: assegnato durante la campagna, rientrato durante la +campagna, oppure fuori per tutta la sua durata. Se sia stato davvero percorso +lo decide l'operatore con la spunta. Se più campagne corrispondono viene +proposta la più recente. I territori fuori durante la campagna e non ancora +rientrati compaiono nel dettaglio come "in corso". --- diff --git a/app/Livewire/Campagne/CampagnaShow.php b/app/Livewire/Campagne/CampagnaShow.php index a18febf..8ba2d6e 100644 --- a/app/Livewire/Campagne/CampagnaShow.php +++ b/app/Livewire/Campagne/CampagnaShow.php @@ -18,16 +18,27 @@ class CampagnaShow extends Component public function render() { - // Assignments counted for this campaign: - // - assigned on or after campaign start - // - linked to this campaign (campaign_id), regardless of returned_at (retroactive returns allowed) - $conteggiate = Assegnazione::where('campaign_id', $this->campagna->id) - ->where('counted_in_campaign', true) - ->where('assigned_at', '>=', $this->campagna->start_date) + // Assignments counted for this campaign: linked via campaign_id and + // flagged as counted — the same set used by the percentage + // (Campagna::percentuale_percorrenza). Which campaign is offered on + // return is decided by Assegnazione::campagnaApplicabile(). + $conteggiate = $this->campagna->assegnazioniConteggiate() ->with(['territorio', 'proclamatore']) ->orderBy('returned_at') ->get(); + // Open assignments can still be counted for this campaign only while + // no later campaign has started: on return the most recent one is + // offered (see Assegnazione::campagnaApplicabile()). + $superata = Campagna::where('start_date', '>', $this->campagna->start_date) + ->where('start_date', '<=', now()->toDateString()) + ->exists(); + + $inCorso = $superata ? null : $this->campagna->assegnazioniInCorso() + ->with(['territorio', 'proclamatore']) + ->orderBy('assigned_at') + ->get(); + // All assignments that were active during this campaign range $assegnateNelRange = Assegnazione::where('assigned_at', '<=', $this->campagna->end_date) ->where(function ($q) { @@ -38,6 +49,7 @@ class CampagnaShow extends Component return view('livewire.campagne.campagna-show', [ 'conteggiate' => $conteggiate, + 'inCorso' => $inCorso, 'assegnateNelRange' => $assegnateNelRange, ]); } diff --git a/app/Models/Assegnazione.php b/app/Models/Assegnazione.php index 01e99d6..f3ad3a2 100644 --- a/app/Models/Assegnazione.php +++ b/app/Models/Assegnazione.php @@ -203,10 +203,18 @@ class Assegnazione extends Model */ public function campagnaApplicabile(?\Carbon\Carbon $returnDate = null): ?Campagna { - $returnDate = $returnDate ?? now(); + $returnDate = ($returnDate ?? now())->toDateString(); + $assignedAt = $this->assigned_at->toDateString(); + // Il territorio può essere conteggiato per una campagna se è rimasto + // in mano al proclamatore almeno in parte del periodo: assegnato + // durante la campagna, rientrato durante la campagna, oppure fuori per + // tutta la sua durata (assegnato prima e rientrato dopo). Se sia stato + // davvero percorso lo decide l'operatore con la spunta. + // Se più campagne corrispondono si propone la più recente. return Campagna::where('start_date', '<=', $returnDate) - ->where('end_date', '>=', $this->assigned_at) + ->where('end_date', '>=', $assignedAt) + ->orderByDesc('start_date') ->first(); } } diff --git a/app/Models/Campagna.php b/app/Models/Campagna.php index b5f0678..121c9d3 100644 --- a/app/Models/Campagna.php +++ b/app/Models/Campagna.php @@ -60,6 +60,16 @@ class Campagna extends Model ->where('counted_in_campaign', true); } + /** + * Assignments still open that were out during this campaign (assigned + * on or before its end): they can be counted for it when they come back. + */ + public function assegnazioniInCorso() + { + return Assegnazione::whereNull('returned_at') + ->where('assigned_at', '<=', $this->end_date); + } + /** * All assignments with assigned_at in this campaign's range. */ diff --git a/resources/views/livewire/assegnazioni/rientra.blade.php b/resources/views/livewire/assegnazioni/rientra.blade.php index 70aaaae..79000ca 100644 --- a/resources/views/livewire/assegnazioni/rientra.blade.php +++ b/resources/views/livewire/assegnazioni/rientra.blade.php @@ -40,12 +40,12 @@ @if($showCampaignPrompt && $campagna)

- ⚠️ Campagna Attiva: {{ $campagna->descrizione }} + ⚠️ Campagna: {{ $campagna->descrizione }}

- Questo territorio è stato assegnato durante la campagna "{{ $campagna->descrizione }}" + Questo territorio era assegnato durante la campagna "{{ $campagna->descrizione }}" ({{ $campagna->start_date->format('d/m/Y') }} — {{ $campagna->end_date->format('d/m/Y') }}). - Vuoi conteggiarlo nella percentuale di percorrenza? + È stato percorso per la campagna? Se sì, conteggialo nella percentuale di percorrenza.

diff --git a/resources/views/livewire/campagne/campagna-show.blade.php b/resources/views/livewire/campagne/campagna-show.blade.php index efa5f5e..fa0e779 100644 --- a/resources/views/livewire/campagne/campagna-show.blade.php +++ b/resources/views/livewire/campagne/campagna-show.blade.php @@ -78,4 +78,40 @@
+ + {{-- Out during the campaign, not yet returned (hidden once a later campaign has started) --}} + @if($inCorso !== null) +
+
+

In corso ({{ $inCorso->count() }})

+

Fuori durante la campagna e non ancora rientrati: si potranno conteggiare al rientro.

+
+
+ + + + + + + + + + + @forelse($inCorso as $a) + + + + + + + @empty + + + + @endforelse + +
TerritorioProclamatoreAssegnatoGiorni
N° {{ $a->territorio?->numero }}{{ $a->proclamatore?->nome_completo ?? 'N/A' }}{{ $a->assigned_at->format('d/m/Y') }}{{ $a->giorni }}
Nessun territorio in corso.
+
+
+ @endif