++ audit log: evento "campagna_percorso" per la scelta sul conteggio in campagna

Registrato al rientro quando viene proposta una campagna (Sì/No) e nel
Registro quando l'amministratore imposta o modifica il conteggio.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Francesco Picone
2026-10-19 10:37:37 +02:00
parent 097aa4ff30
commit 1708890d48
4 changed files with 50 additions and 3 deletions

View File

@@ -98,6 +98,16 @@ class Rientra extends Component
])
->log('returned');
// The operator answered the campaign prompt: record the choice
// (counted or not) as its own audit entry.
if ($this->showCampaignPrompt && $this->campagna_id) {
$this->assegnazione->logCampagnaPercorso(
Campagna::find($this->campagna_id),
$this->counted_in_campaign,
'Rientro'
);
}
session()->flash('success', "Territorio {$territorio->numero} rientrato da {$proclamatore->nome_completo} dopo {$this->assegnazione->giorni} giorni.");
return $this->redirect(route('territori.show', $territorio), navigate: true);
}

View File

@@ -154,7 +154,10 @@ class Registro extends Component
'note' => $this->form_note ?: null,
];
$conflitto = DB::transaction(function () use ($data, $uscita, $rientro) {
$assegnazione = null;
$prima = [false, null];
$conflitto = DB::transaction(function () use ($data, $uscita, $rientro, &$assegnazione, &$prima) {
Territorio::whereKey($data['territorio_id'])->lockForUpdate()->first();
$conflitto = Assegnazione::sovrappostaA((int) $data['territorio_id'], $uscita, $rientro, $this->editingId);
@@ -163,9 +166,11 @@ class Registro extends Component
}
if ($this->editingId) {
Assegnazione::findOrFail($this->editingId)->update($data);
$assegnazione = Assegnazione::findOrFail($this->editingId);
$prima = [(bool) $assegnazione->counted_in_campaign, $assegnazione->campaign_id ? (int) $assegnazione->campaign_id : null];
$assegnazione->update($data);
} else {
Assegnazione::create($data + ['created_by' => auth()->id()]);
$assegnazione = Assegnazione::create($data + ['created_by' => auth()->id()]);
}
return null;
@@ -177,6 +182,16 @@ class Registro extends Component
return;
}
// Log the campaign choice when the admin sets or changes it here.
$dopo = [(bool) $assegnazione->counted_in_campaign, $assegnazione->campaign_id ? (int) $assegnazione->campaign_id : null];
if ($dopo !== $prima && ($dopo[0] || $prima[0])) {
$assegnazione->logCampagnaPercorso(
$assegnazione->campagna ?? ($prima[1] ? Campagna::find($prima[1]) : null),
$dopo[0],
'Registro'
);
}
$this->showModal = false;
}

View File

@@ -235,6 +235,27 @@ class Assegnazione extends Model
// ─── Business Logic ─────────────────────────────────────────
/**
* Registra nell'audit log la scelta dell'operatore sul conteggio in
* campagna: evento dedicato "campagna_percorso", leggibile senza dover
* interpretare le proprietà dell'evento "returned".
*/
public function logCampagnaPercorso(?Campagna $campagna, bool $percorso, string $origine): void
{
$this->loadMissing('territorio');
activity()->causedBy(auth()->user())
->performedOn($this)
->withProperties([
'territorio' => $this->territorio?->numero,
'proclamatore_id' => $this->proclamatore_id, // vedi Assegna: niente nomi in chiaro
'campagna' => $campagna?->descrizione,
'percorso_in_campagna' => $percorso ? 'Sì' : 'No',
'origine' => $origine,
])
->log('campagna_percorso');
}
/**
* Check if a campaign prompt should be shown when returning this assignment.
* Returns the matching campaign or null.

View File

@@ -49,6 +49,7 @@
'deleted' => 'bg-red-100 text-red-800',
'assigned' => 'bg-indigo-100 text-indigo-800',
'returned' => 'bg-amber-100 text-amber-800',
'campagna_percorso' => 'bg-orange-100 text-orange-800',
'restored' => 'bg-purple-100 text-purple-800',
'login' => 'bg-cyan-100 text-cyan-800',
default => 'bg-gray-100 text-gray-700',