sourceDb = $sourceDb; $this->targetDb = $targetDb; $this->logger = $logger; $this->passageMigrator = $passageMigrator; } /** * Migre un secteur dans le contexte d'une opération * * @param int $oldOperationId ID ancienne opération * @param int $newOperationId ID nouvelle opération * @param int $oldSectorId ID ancien secteur * @param array $userMapping Mapping oldUserId => newOpeUserId * @return array|null ['id' => int, 'name' => string, 'users' => int, 'passages' => int] ou null en cas d'erreur */ public function migrateSector( int $oldOperationId, int $newOperationId, int $oldSectorId, array $userMapping ): ?array { $this->logger->info(" 📍 Migration secteur ID: {$oldSectorId}"); try { // 1. Récupérer le secteur source $stmt = $this->sourceDb->prepare(" SELECT * FROM sectors WHERE rowid = :id "); $stmt->execute([':id' => $oldSectorId]); $sector = $stmt->fetch(PDO::FETCH_ASSOC); if (!$sector) { $this->logger->warning(" Secteur {$oldSectorId} non trouvé"); return null; } // 2. Créer dans ope_sectors $newOpeSectorId = $this->createOpeSector($sector, $newOperationId); if (!$newOpeSectorId) { return null; } // 3. Mapper "operationId_sectorId" → newOpeSectorId $mappingKey = "{$oldOperationId}_{$oldSectorId}"; $this->sectorMapping[$mappingKey] = $newOpeSectorId; $this->logger->success(" ✓ Secteur créé avec ID: {$newOpeSectorId}"); // 4. Migrer sectors_adresses $this->migrateSectorAddresses($oldSectorId, $newOpeSectorId); // 5. Migrer ope_users_sectors $usersCount = $this->migrateUsersSectors($oldOperationId, $newOperationId, $oldSectorId, $newOpeSectorId, $userMapping); // 6. Migrer ope_pass $passagesCount = $this->passageMigrator->migratePassages( $oldOperationId, $newOperationId, $oldSectorId, $newOpeSectorId, $userMapping ); return [ 'id' => $newOpeSectorId, 'name' => $sector['libelle'], 'users' => $usersCount, 'passages' => $passagesCount ]; } catch (Exception $e) { $this->logger->error(" ❌ Erreur migration secteur {$oldSectorId}: " . $e->getMessage()); return null; } } /** * Crée un secteur dans ope_sectors * * @param array $sector Données du secteur * @param int $newOperationId ID nouvelle opération * @return int|null ID du nouveau secteur ou null en cas d'erreur */ private function createOpeSector(array $sector, int $newOperationId): ?int { try { $stmt = $this->targetDb->prepare(" INSERT INTO ope_sectors ( fk_operation, libelle, sector, color, created_at, fk_user_creat, updated_at, fk_user_modif, chk_active ) VALUES ( :fk_operation, :libelle, :sector, :color, :created_at, :fk_user_creat, :updated_at, :fk_user_modif, :chk_active ) "); $stmt->execute([ ':fk_operation' => $newOperationId, ':libelle' => $sector['libelle'], ':sector' => $sector['sector'], ':color' => $sector['color'], ':created_at' => $sector['date_creat'], ':fk_user_creat' => $sector['fk_user_creat'] ?? 0, ':updated_at' => $sector['date_modif'], ':fk_user_modif' => $sector['fk_user_modif'] ?? 0, ':chk_active' => $sector['active'] ]); return (int)$this->targetDb->lastInsertId(); } catch (Exception $e) { $this->logger->error(" ❌ Erreur création secteur: " . $e->getMessage()); return null; } } /** * Migre les adresses d'un secteur * * @param int $oldSectorId ID ancien secteur * @param int $newOpeSectorId ID nouveau ope_sectors * @return int Nombre d'adresses migrées */ private function migrateSectorAddresses(int $oldSectorId, int $newOpeSectorId): int { $stmt = $this->sourceDb->prepare(" SELECT * FROM sectors_adresses WHERE fk_sector = :sector_id "); $stmt->execute([':sector_id' => $oldSectorId]); $addresses = $stmt->fetchAll(PDO::FETCH_ASSOC); if (empty($addresses)) { return 0; } $count = 0; foreach ($addresses as $address) { $stmt = $this->targetDb->prepare(" INSERT INTO sectors_adresses ( fk_adresse, fk_sector, numero, rue_bis, rue, cp, ville, gps_lat, gps_lng ) VALUES ( :fk_adresse, :fk_sector, :numero, :rue_bis, :rue, :cp, :ville, :gps_lat, :gps_lng ) "); $stmt->execute([ ':fk_adresse' => $address['fk_adresse'], // Garde la valeur telle quelle ':fk_sector' => $newOpeSectorId, ':numero' => $address['numero'], ':rue_bis' => $address['rue_bis'], ':rue' => $address['rue'], ':cp' => $address['cp'], ':ville' => $address['ville'], ':gps_lat' => $address['gps_lat'], ':gps_lng' => $address['gps_lng'] ]); $count++; } $this->logger->success(" ✓ {$count} adresse(s) migrée(s)"); return $count; } /** * Migre les associations utilisateurs-secteurs * * @param int $oldOperationId ID ancienne opération * @param int $newOperationId ID nouvelle opération * @param int $oldSectorId ID ancien secteur * @param int $newOpeSectorId ID nouveau ope_sectors * @param array $userMapping Mapping oldUserId => newOpeUserId * @return int Nombre d'associations migrées */ private function migrateUsersSectors( int $oldOperationId, int $newOperationId, int $oldSectorId, int $newOpeSectorId, array $userMapping ): int { $stmt = $this->sourceDb->prepare(" SELECT * FROM ope_users_sectors WHERE fk_operation = :operation_id AND fk_sector = :sector_id AND active = 1 "); $stmt->execute([ ':operation_id' => $oldOperationId, ':sector_id' => $oldSectorId ]); $usersSectors = $stmt->fetchAll(PDO::FETCH_ASSOC); if (empty($usersSectors)) { return 0; } $count = 0; foreach ($usersSectors as $us) { // Vérifier que l'utilisateur existe dans le mapping // (le mapping sert juste à vérifier que l'user a été migré) if (!isset($userMapping[$us['fk_user']])) { $this->logger->warning(" ⚠ User {$us['fk_user']} non trouvé dans mapping"); continue; } $stmt = $this->targetDb->prepare(" INSERT INTO ope_users_sectors ( fk_operation, fk_user, fk_sector, created_at, fk_user_creat, updated_at, fk_user_modif, chk_active ) VALUES ( :fk_operation, :fk_user, :fk_sector, :created_at, :fk_user_creat, :updated_at, :fk_user_modif, :chk_active ) "); $stmt->execute([ ':fk_operation' => $newOperationId, ':fk_user' => $userMapping[$us['fk_user']], // ID de ope_users (mapping) ':fk_sector' => $newOpeSectorId, ':created_at' => date('Y-m-d H:i:s'), ':fk_user_creat' => 0, ':updated_at' => null, ':fk_user_modif' => null, ':chk_active' => $us['active'] ]); $count++; } $this->logger->success(" ✓ {$count} association(s) user-secteur migrée(s)"); return $count; } /** * Retourne le mapping des secteurs * * @return array "operationId_sectorId" => newOpeSectorId */ public function getSectorMapping(): array { return $this->sectorMapping; } /** * Définit le mapping des secteurs (utile pour réutilisation) * * @param array $mapping "operationId_sectorId" => newOpeSectorId */ public function setSectorMapping(array $mapping): void { $this->sectorMapping = $mapping; } }