feat : cause d'entrée bovin + confirmation EDNOTIF asynchrone + historique entrées

- Champ entryCause sur Bovine (enum App\Enum\CauseEntree : Achat/Naissance/PretOuPension)
- Sélecteur "Cause d'entrée" sur le formulaire de saisie (default Achat, required)
- ednotif_confirmed_at sur Bovine : timestamp set par le sync EDNOTIF la première
  fois qu'un bovin remonte dans getInventory. Backfill des bovins existants au
  jour de la migration.
- Inventaire (page + export + stats) filtre les bovins encore "en attente
  EDNOTIF" : ils n'apparaissent qu'une fois confirmés par le sync.
- getter getConfirmedBovineCount sur Reception, exposé en reception:read.
- Tableau Historique full-width sur /entry-exit listant les entrées validées,
  avec filtres de colonnes (numéro, date, fournisseur), compteur Confirmés/Saisis,
  et badge de statut "Confirmée" / "EDNOTIF en attente".
- Tableau récap de l'écran de saisie passé en useDataTableServerState pour
  bénéficier du loading et de la pagination serveur.
- Validation entrée : confirm window obligatoire, message renforcé en cas
  d'écart entre saisis et déclarés.
- Pattern projet "submitted" sur le formulaire d'ajout pour le visuel required.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-29 17:29:46 +02:00
parent c64e0c7100
commit 476502c91c
13 changed files with 376 additions and 96 deletions

View File

@@ -72,6 +72,12 @@ final class BovineSyncInventoryProcessor implements ProcessorInterface
$this->applyEdnotifData($bovine, $animal);
$bovine->setExitedAt(null);
// Marque la confirmation EDNOTIF si c'est la première fois qu'on
// voit ce bovin remonter dans l'inventaire.
if (null === $bovine->getEdnotifConfirmedAt()) {
$bovine->setEdnotifConfirmedAt(new DateTimeImmutable());
}
}
$now = new DateTimeImmutable();