beginTransaction(); try { $animalId = (int) $data['animal_id']; $date = $data['adoption_date'] ?? date('Y-m-d'); $beforeStmt = $db->prepare( 'SELECT status,refuge_room,care_box_key,current_address FROM animals WHERE id=:id', ); $beforeStmt->execute([':id' => $animalId]); $beforeLocation = $beforeStmt->fetch(PDO::FETCH_ASSOC) ?: []; // 1. Enregistrement de l’adoption $stmt = $db->prepare(' INSERT INTO adoptions ( animal_id, adopter_name, adopter_phone, adopter_email, adopter_address, adopter_postal_code, adopter_city, adoption_date, notes, adopter_contact_id, created_at ) VALUES ( :animal_id, :name, :phone, :email, :address, :postal, :city, :date, :notes, :contact_id, CURRENT_TIMESTAMP ) '); $stmt->execute([ ':animal_id' => $animalId, ':name' => $data['adopter_name'], ':phone' => $data['adopter_phone'] ?: null, ':email' => $data['adopter_email'] ?: null, ':address' => $data['adopter_address'] ?: null, ':postal' => $data['adopter_postal_code'] ?: null, ':city' => $data['adopter_city'] ?: null, ':date' => $date, ':notes' => $data['notes'] ?: null, ':contact_id' => $data['adopter_contact_id'] ?? null, ]); $adoptionId = (int) $db->lastInsertId(); $db->prepare( "INSERT INTO animal_placements(animal_id,event_type,event_date,contact_id,reason,notes,adoption_id,created_by) VALUES(:animal,'adoption',:date,:contact,'Adoption définitive',:notes,:adoption,:user)", )->execute([ ':animal' => $animalId, ':date' => $date, ':contact' => $data['adopter_contact_id'] ?? null, ':notes' => $data['notes'] ?: null, ':adoption' => $adoptionId, ':user' => Auth::id(), ]); // 2. Mise à jour du statut de l’animal $currentAddress = implode( ' ', array_filter([ $data['adopter_address'] ?? '', $data['adopter_postal_code'] ?? '', $data['adopter_city'] ?? '', ]), ); $lat = null; $lng = null; if (!empty($currentAddress)) { $coords = GeocodeService::geocode($currentAddress); if ($coords) { $lat = $coords['lat'] ?? null; $lng = $coords['lng'] ?? null; } } $db->prepare( " UPDATE animals SET status = 'adopte', refuge_room = NULL, care_box_key = NULL, updated_at = CURRENT_TIMESTAMP, current_address = :currentAddress, current_lat = :lat, current_lng = :lng WHERE id = :id ", )->execute([':id' => $animalId, ':currentAddress' => $currentAddress, ':lat' => $lat, ':lng' => $lng]); LocationHistoryService::record( $db, $animalId, $beforeLocation, [ 'status' => 'adopte', 'refuge_room' => null, 'care_box_key' => null, 'current_address' => $currentAddress, ], 'adoption', 'Adoption finalisée', $date . ' 12:00:00', ); // 3. Ajout dans les mouvements administratifs (sortie) $stmt = $db->prepare(" INSERT INTO animal_movements ( animal_id, kind, place, lieu, contact_name, contact_phone, contact_email, note, created_at ) VALUES ( :animal_id, 'exit', :place, 'Adoption', :contact_name, :contact_phone, :contact_email, :note, CURRENT_TIMESTAMP ) "); $stmt->execute([ ':animal_id' => $animalId, ':place' => $data['adopter_address'] ?: null, ':contact_name' => $data['adopter_name'] ?: null, ':contact_phone' => $data['adopter_phone'] ?: null, ':contact_email' => $data['adopter_email'] ?: null, ':note' => 'Adoption finalisée', ]); // 4. Ajout dans l’historique $stmt = $db->prepare(" INSERT INTO animal_history ( animal_id, type, label, details, user_id, created_at ) VALUES ( :animal_id, 'adoption', 'Adoption finalisée', :details, :user_id, CURRENT_TIMESTAMP ) "); $stmt->execute([ ':animal_id' => $animalId, ':details' => 'Par ' . $data['adopter_name'] . ' - Note(s) : ' . $data['notes'], ':user_id' => Auth::id(), ]); $db->commit(); } catch (Exception $e) { $db->rollBack(); throw $e; } } }