Publier Globinours 1.0.0-rc.3

This commit is contained in:
Alexandre NOEL 2026-09-03 12:39:15 +02:00
commit 9a2b4068da
325 changed files with 38230 additions and 20 deletions

View file

@ -0,0 +1,115 @@
<?php
declare(strict_types=1);
final class LocationHistoryService
{
private const TRACKED = ['status', 'refuge_room', 'care_box_key', 'current_address'];
public static function snapshot(array $animal): array
{
$snapshot = [];
foreach (self::TRACKED as $field) {
$value = trim((string) ($animal[$field] ?? ''));
$snapshot[$field] = $value === '' ? null : $value;
}
return $snapshot;
}
public static function record(
PDO $db,
int $animalId,
?array $before,
array $after,
string $source,
?string $reason = null,
?string $movedAt = null,
): bool {
$from = self::snapshot($before ?? []);
$to = self::snapshot($after);
if ($before !== null && $from === $to) {
return false;
}
$stmt = $db->prepare('INSERT INTO animal_location_history (
animal_id,from_status,from_refuge_room,from_care_box_key,from_address,
to_status,to_refuge_room,to_care_box_key,to_address,reason,source,moved_at,user_id
) VALUES (
:animal,:from_status,:from_room,:from_box,:from_address,
:to_status,:to_room,:to_box,:to_address,:reason,:source,:moved_at,:user
)');
$stmt->execute([
':animal' => $animalId,
':from_status' => $from['status'],
':from_room' => $from['refuge_room'],
':from_box' => $from['care_box_key'],
':from_address' => $from['current_address'],
':to_status' => $to['status'],
':to_room' => $to['refuge_room'],
':to_box' => $to['care_box_key'],
':to_address' => $to['current_address'],
':reason' => ($reason = trim((string) $reason)) !== '' ? $reason : null,
':source' => $source,
':moved_at' => $movedAt ?: date('Y-m-d H:i:s'),
':user' => Auth::id(),
]);
return true;
}
public static function label(array $row, string $prefix): string
{
$status = trim((string) ($row[$prefix . '_status'] ?? ''));
$room = trim((string) ($row[$prefix . '_refuge_room'] ?? ''));
$box = trim((string) ($row[$prefix . '_care_box_key'] ?? ''));
$address = trim((string) ($row[$prefix . '_address'] ?? ''));
$label = match ($status) {
'refuge' => $room !== '' ? 'Refuge · ' . self::roomName($room) : 'Refuge · Salle non attribuée',
'soin' => $room !== '' ? self::roomName($room) : 'Infirmerie',
'quarantaine' => $room !== '' ? self::roomName($room) : 'Salle de quarantaine',
'fa' => 'Famille daccueil',
'fa_permanente' => 'FA permanente',
'reserve', 'réservé' => 'Réservé',
'adopte', 'adopté' => 'Adopté',
'hospitalise', 'hospitalisé' => 'Hospitalisé',
'isolation' => 'Isolation',
'decede', 'décédé' => 'Décédé',
'enfui', 'fugue' => 'Enfui',
'' => 'Emplacement antérieur inconnu',
default => ucfirst(str_replace('_', ' ', $status)),
};
if ($box !== '' && in_array($status, ['soin', 'quarantaine'], true)) {
$label .= ' · Box ' . self::boxLabel($box);
}
if (
$address !== '' &&
in_array($status, ['fa', 'fa_permanente', 'adopte', 'adopté', 'hospitalise', 'hospitalisé'], true)
) {
$label .= ' · ' . $address;
}
return $label;
}
private static function boxLabel(string $box): string
{
return match ($box) {
'top_a' => 'haut gauche',
'top_b' => 'haut centre',
'top_c' => 'haut droite',
'top_ab' => 'haut gauche double',
'top_bc' => 'haut droite double',
'top_all' => 'haut complet',
'bottom_a' => 'bas gauche',
'bottom_b' => 'bas droite',
'bottom_all' => 'bas complet',
default => str_replace('_', ' ', $box),
};
}
private static function roomName(string $code): string
{
static $rooms = null;
$rooms ??= ShelterRoomService::byCode(false);
return (string) ($rooms[$code]['name'] ?? $code);
}
}