115 lines
4.2 KiB
PHP
115 lines
4.2 KiB
PHP
<?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 d’accueil',
|
||
'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);
|
||
}
|
||
}
|