Publier Globinours 1.0.0-rc.3
This commit is contained in:
parent
ea8c24d622
commit
9a2b4068da
325 changed files with 38230 additions and 20 deletions
106
scripts/reconcile-animal-current-state.php
Normal file
106
scripts/reconcile-animal-current-state.php
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
$root = dirname(__DIR__);
|
||||
require $root . '/app/Services/DB.php';
|
||||
require $root . '/app/Services/BackupService.php';
|
||||
$apply = in_array('--apply', $argv, true);
|
||||
$db = DB::pdo();
|
||||
$backup = null;
|
||||
$user =
|
||||
(int) ($db->query("SELECT id FROM users WHERE role='admin' AND active=1 ORDER BY id LIMIT 1")->fetchColumn() ?:
|
||||
0) ?:
|
||||
null;
|
||||
$latest = $db
|
||||
->query(
|
||||
"WITH ranked AS (SELECT ap.*,ROW_NUMBER() OVER(PARTITION BY animal_id ORDER BY date(event_date) DESC,id DESC) rn FROM animal_placements ap) SELECT r.*,a.status current_status,a.archived_at current_archived,dc.name contact_name,dc.address contact_address,dc.postal_code contact_postal,dc.city contact_city,ad.adopter_address,ad.adopter_postal_code,ad.adopter_city FROM ranked r JOIN animals a ON a.id=r.animal_id LEFT JOIN animal_deaths d ON d.animal_id=a.id LEFT JOIN directory_contacts dc ON dc.id=r.contact_id LEFT JOIN adoptions ad ON ad.id=r.adoption_id WHERE r.rn=1 AND r.event_type='adoption' AND d.animal_id IS NULL AND a.deleted_at IS NULL ORDER BY r.event_date,r.animal_id",
|
||||
)
|
||||
->fetchAll(PDO::FETCH_ASSOC);
|
||||
$summary = [
|
||||
'adopted_states_checked' => count($latest),
|
||||
'statuses_fixed' => 0,
|
||||
'locations_fixed' => 0,
|
||||
'movements_created' => 0,
|
||||
'movements_updated' => 0,
|
||||
'history_created' => 0,
|
||||
];
|
||||
if ($apply) {
|
||||
$backup = BackupService::create('avant-reconciliation-etat-animaux');
|
||||
}
|
||||
$db->beginTransaction();
|
||||
try {
|
||||
foreach ($latest as $row) {
|
||||
$animal = (int) $row['animal_id'];
|
||||
$date = (string) $row['event_date'];
|
||||
$contact = trim((string) ($row['contact_name'] ?? '')) ?: 'Adoptant non renseigné';
|
||||
$address = implode(
|
||||
' ',
|
||||
array_filter([
|
||||
trim((string) ($row['contact_address'] ?? '' ?: $row['adopter_address'] ?? '')),
|
||||
trim((string) ($row['contact_postal'] ?? '' ?: $row['adopter_postal_code'] ?? '')),
|
||||
trim((string) ($row['contact_city'] ?? '' ?: $row['adopter_city'] ?? '')),
|
||||
]),
|
||||
);
|
||||
if ($address === '') {
|
||||
$address = 'Adopté par ' . $contact;
|
||||
}
|
||||
if ($row['current_status'] !== 'adopte' || empty($row['current_archived'])) {
|
||||
$summary['statuses_fixed']++;
|
||||
}
|
||||
$current = $db->prepare('SELECT current_address FROM animals WHERE id=?');
|
||||
$current->execute([$animal]);
|
||||
if (trim((string) $current->fetchColumn()) !== $address) {
|
||||
$summary['locations_fixed']++;
|
||||
}
|
||||
$db->prepare(
|
||||
"UPDATE animals SET status='adopte',is_archived=1,archived_at=?,refuge_room=NULL,care_box_key=NULL,quarantine_until=NULL,current_address=?,current_lat=NULL,current_lng=NULL,updated_at=datetime('now') WHERE id=?",
|
||||
)->execute([$date . ' 12:00:00', $address, $animal]);
|
||||
$movement = $db->prepare(
|
||||
"SELECT id FROM animal_movements WHERE animal_id=? AND kind='exit' AND lower(COALESCE(lieu,'')) LIKE 'adopt%' ORDER BY created_at DESC,id DESC LIMIT 1",
|
||||
);
|
||||
$movement->execute([$animal]);
|
||||
$movementId = (int) $movement->fetchColumn();
|
||||
if ($movementId) {
|
||||
$db->prepare(
|
||||
"UPDATE animal_movements SET place=?,lieu='Adoption',contact_name=?,note=CASE WHEN note IS NULL OR note='' THEN 'Sortie synchronisée avec le parcours d’adoption.' ELSE note END,created_at=? WHERE id=?",
|
||||
)->execute([$address, $contact, $date . ' 12:00:00', $movementId]);
|
||||
$summary['movements_updated']++;
|
||||
} else {
|
||||
$db->prepare(
|
||||
"INSERT INTO animal_movements(animal_id,kind,place,lieu,contact_name,note,created_at) VALUES(?,'exit',?,'Adoption',?,'Sortie synchronisée avec le parcours d’adoption.',?)",
|
||||
)->execute([$animal, $address, $contact, $date . ' 12:00:00']);
|
||||
$summary['movements_created']++;
|
||||
}
|
||||
$history = $db->prepare(
|
||||
"SELECT 1 FROM animal_history WHERE animal_id=? AND date(created_at)=date(?) AND (lower(label) LIKE '%adopt%' OR lower(type)='adoption') LIMIT 1",
|
||||
);
|
||||
$history->execute([$animal, $date]);
|
||||
if (!$history->fetchColumn()) {
|
||||
$db->prepare(
|
||||
"INSERT INTO animal_history(animal_id,type,label,details,user_id,created_at) VALUES(?,'status','Adoption de l’animal',?,?,?)",
|
||||
)->execute([$animal, 'Adopté par ' . $contact . '.', $user, $date . ' 12:00:00']);
|
||||
$summary['history_created']++;
|
||||
}
|
||||
}
|
||||
$fk = $db->query('PRAGMA foreign_key_check')->fetchAll();
|
||||
if ($fk) {
|
||||
throw new RuntimeException('Violation de clé étrangère après synchronisation.');
|
||||
}
|
||||
if ($apply) {
|
||||
$db->commit();
|
||||
} else {
|
||||
$db->rollBack();
|
||||
}
|
||||
echo json_encode(
|
||||
['mode' => $apply ? 'APPLIQUE' : 'SIMULATION', 'backup' => $backup['name'] ?? null, 'summary' => $summary],
|
||||
JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES,
|
||||
),
|
||||
"\n";
|
||||
} catch (Throwable $error) {
|
||||
if ($db->inTransaction()) {
|
||||
$db->rollBack();
|
||||
}
|
||||
fwrite(STDERR, 'Synchronisation interrompue : ' . $error->getMessage() . "\n");
|
||||
exit(1);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue