feat: Version 3.5.2 - Configuration Stripe et gestion des immeubles
- Configuration complète Stripe pour les 3 environnements (DEV/REC/PROD) * DEV: Clés TEST Pierre (mode test) * REC: Clés TEST Client (mode test) * PROD: Clés LIVE Client (mode live) - Ajout de la gestion des bases de données immeubles/bâtiments * Configuration buildings_database pour DEV/REC/PROD * Service BuildingService pour enrichissement des adresses - Optimisations pages et améliorations ergonomie - Mises à jour des dépendances Composer - Nettoyage des fichiers obsolètes 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
256
api/scripts/migration2/php/lib/PassageMigrator.php
Normal file
256
api/scripts/migration2/php/lib/PassageMigrator.php
Normal file
@@ -0,0 +1,256 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Migration des passages (ope_pass) et historiques (ope_pass_histo)
|
||||
*
|
||||
* Gère la migration des passages avec vérification du trio
|
||||
* (operation, user, sector) et migration des historiques associés
|
||||
*/
|
||||
class PassageMigrator
|
||||
{
|
||||
private PDO $sourceDb;
|
||||
private PDO $targetDb;
|
||||
private MigrationLogger $logger;
|
||||
|
||||
/**
|
||||
* Constructeur
|
||||
*
|
||||
* @param PDO $sourceDb Connexion source
|
||||
* @param PDO $targetDb Connexion cible
|
||||
* @param MigrationLogger $logger Logger
|
||||
*/
|
||||
public function __construct(PDO $sourceDb, PDO $targetDb, MigrationLogger $logger)
|
||||
{
|
||||
$this->sourceDb = $sourceDb;
|
||||
$this->targetDb = $targetDb;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Migre les passages d'un secteur dans une opération
|
||||
*
|
||||
* @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 de passages migrés
|
||||
*/
|
||||
public function migratePassages(
|
||||
int $oldOperationId,
|
||||
int $newOperationId,
|
||||
int $oldSectorId,
|
||||
int $newOpeSectorId,
|
||||
array $userMapping
|
||||
): int {
|
||||
$stmt = $this->sourceDb->prepare("
|
||||
SELECT * FROM ope_pass
|
||||
WHERE fk_operation = :operation_id
|
||||
AND fk_sector = :sector_id
|
||||
");
|
||||
$stmt->execute([
|
||||
':operation_id' => $oldOperationId,
|
||||
':sector_id' => $oldSectorId
|
||||
]);
|
||||
$passages = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if (empty($passages)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$count = 0;
|
||||
foreach ($passages as $passage) {
|
||||
// Vérifier que l'utilisateur a été migré
|
||||
if (!isset($userMapping[$passage['fk_user']])) {
|
||||
$this->logger->warning(" ⚠ Passage {$passage['rowid']}: User {$passage['fk_user']} non trouvé dans mapping");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Récupérer l'ID de ope_users depuis le mapping
|
||||
$newOpeUserId = $userMapping[$passage['fk_user']];
|
||||
|
||||
// Vérifier que le trio (operation, user, sector) existe dans ope_users_sectors
|
||||
if (!$this->verifyUserSectorAssociation($newOperationId, $newOpeUserId, $newOpeSectorId)) {
|
||||
$this->logger->warning(" ⚠ Passage {$passage['rowid']}: Trio (op={$newOperationId}, user={$newOpeUserId}, sector={$newOpeSectorId}) inexistant");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Insérer le passage avec l'ID de ope_users
|
||||
$newPassId = $this->insertPassage($passage, $newOperationId, $newOpeSectorId, $newOpeUserId);
|
||||
|
||||
if ($newPassId) {
|
||||
// Migrer l'historique du passage
|
||||
$this->migratePassageHisto($passage['rowid'], $newPassId, $userMapping);
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($count > 0) {
|
||||
$this->logger->success(" ✓ {$count} passage(s) migré(s)");
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie qu'une association user-sector existe dans ope_users_sectors
|
||||
*
|
||||
* @param int $operationId ID opération
|
||||
* @param int $userId ID ope_users (mapping)
|
||||
* @param int $sectorId ID ope_sectors
|
||||
* @return bool True si l'association existe
|
||||
*/
|
||||
private function verifyUserSectorAssociation(int $operationId, int $userId, int $sectorId): bool
|
||||
{
|
||||
$stmt = $this->targetDb->prepare("
|
||||
SELECT COUNT(*) FROM ope_users_sectors
|
||||
WHERE fk_operation = :operation_id
|
||||
AND fk_user = :user_id
|
||||
AND fk_sector = :sector_id
|
||||
");
|
||||
$stmt->execute([
|
||||
':operation_id' => $operationId,
|
||||
':user_id' => $userId,
|
||||
':sector_id' => $sectorId
|
||||
]);
|
||||
|
||||
return $stmt->fetchColumn() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insère un passage dans la nouvelle base
|
||||
*
|
||||
* @param array $passage Données du passage
|
||||
* @param int $newOperationId ID nouvelle opération
|
||||
* @param int $newOpeSectorId ID nouveau secteur
|
||||
* @param int $userId ID de ope_users (mapping)
|
||||
* @return int|null ID du nouveau passage ou null en cas d'erreur
|
||||
*/
|
||||
private function insertPassage(
|
||||
array $passage,
|
||||
int $newOperationId,
|
||||
int $newOpeSectorId,
|
||||
int $userId
|
||||
): ?int {
|
||||
try {
|
||||
$stmt = $this->targetDb->prepare("
|
||||
INSERT INTO ope_pass (
|
||||
fk_operation, fk_sector, fk_user, fk_adresse,
|
||||
passed_at, fk_type, numero, rue, rue_bis, ville,
|
||||
fk_habitat, appt, niveau, residence,
|
||||
gps_lat, gps_lng, encrypted_name, montant, fk_type_reglement,
|
||||
remarque, nom_recu, encrypted_email, email_erreur, chk_email_sent,
|
||||
encrypted_phone, docremis, date_repasser, nb_passages,
|
||||
chk_gps_maj, chk_map_create, chk_mobile, chk_synchro,
|
||||
chk_api_adresse, chk_maj_adresse, anomalie,
|
||||
created_at, fk_user_creat, updated_at, fk_user_modif, chk_active
|
||||
) VALUES (
|
||||
:fk_operation, :fk_sector, :fk_user, :fk_adresse,
|
||||
:passed_at, :fk_type, :numero, :rue, :rue_bis, :ville,
|
||||
:fk_habitat, :appt, :niveau, :residence,
|
||||
:gps_lat, :gps_lng, :encrypted_name, :montant, :fk_type_reglement,
|
||||
:remarque, :nom_recu, :encrypted_email, :email_erreur, :chk_email_sent,
|
||||
:encrypted_phone, :docremis, :date_repasser, :nb_passages,
|
||||
:chk_gps_maj, :chk_map_create, :chk_mobile, :chk_synchro,
|
||||
:chk_api_adresse, :chk_maj_adresse, :anomalie,
|
||||
:created_at, :fk_user_creat, :updated_at, :fk_user_modif, :chk_active
|
||||
)
|
||||
");
|
||||
|
||||
// Chiffrer les données sensibles
|
||||
require_once dirname(__DIR__, 4) . '/src/Services/ApiService.php';
|
||||
|
||||
$stmt->execute([
|
||||
':fk_operation' => $newOperationId,
|
||||
':fk_sector' => $newOpeSectorId,
|
||||
':fk_user' => $userId, // ID de ope_users (mapping)
|
||||
':fk_adresse' => $passage['fk_adresse'],
|
||||
':passed_at' => $passage['date_eve'],
|
||||
':fk_type' => $passage['fk_type'],
|
||||
':numero' => $passage['numero'],
|
||||
':rue' => $passage['rue'],
|
||||
':rue_bis' => $passage['rue_bis'],
|
||||
':ville' => $passage['ville'],
|
||||
':fk_habitat' => $passage['fk_habitat'],
|
||||
':appt' => $passage['appt'],
|
||||
':niveau' => $passage['niveau'],
|
||||
':residence' => $passage['lieudit'] ?? null,
|
||||
':gps_lat' => $passage['gps_lat'],
|
||||
':gps_lng' => $passage['gps_lng'],
|
||||
':encrypted_name' => $passage['libelle'] ? ApiService::encryptData($passage['libelle']) : '', // Chiffrer avec IV aléatoire
|
||||
':montant' => $passage['montant'],
|
||||
':fk_type_reglement' => (!empty($passage['fk_type_reglement']) && $passage['fk_type_reglement'] > 0) ? $passage['fk_type_reglement'] : 4,
|
||||
':remarque' => $passage['remarque'],
|
||||
':nom_recu' => $passage['recu'] ?? null,
|
||||
':encrypted_email' => $passage['email'] ? ApiService::encryptSearchableData($passage['email']) : null,
|
||||
':email_erreur' => $passage['email_erreur'],
|
||||
':chk_email_sent' => $passage['chk_email_sent'],
|
||||
':encrypted_phone' => $passage['phone'] ? ApiService::encryptData($passage['phone']) : '',
|
||||
':docremis' => $passage['docremis'],
|
||||
':date_repasser' => $passage['date_repasser'],
|
||||
':nb_passages' => ($passage['fk_type'] == 2) ? 0 : $passage['nb_passages'],
|
||||
':chk_gps_maj' => $passage['chk_gps_maj'],
|
||||
':chk_map_create' => $passage['chk_map_create'],
|
||||
':chk_mobile' => $passage['chk_mobile'],
|
||||
':chk_synchro' => $passage['chk_synchro'],
|
||||
':chk_api_adresse' => $passage['chk_api_adresse'],
|
||||
':chk_maj_adresse' => $passage['chk_maj_adresse'],
|
||||
':anomalie' => $passage['anomalie'],
|
||||
':created_at' => $passage['date_creat'],
|
||||
':fk_user_creat' => $passage['fk_user_creat'] ?? 0,
|
||||
':updated_at' => $passage['date_modif'],
|
||||
':fk_user_modif' => $passage['fk_user_modif'] ?? 0,
|
||||
':chk_active' => $passage['active']
|
||||
]);
|
||||
|
||||
return (int)$this->targetDb->lastInsertId();
|
||||
|
||||
} catch (Exception $e) {
|
||||
$this->logger->error(" ❌ Erreur insertion passage {$passage['rowid']}: " . $e->getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migre l'historique d'un passage
|
||||
*
|
||||
* @param int $oldPassId ID ancien passage
|
||||
* @param int $newPassId ID nouveau passage
|
||||
* @param array $userMapping Non utilisé (conservé pour compatibilité)
|
||||
* @return int Nombre d'entrées d'historique migrées
|
||||
*/
|
||||
public function migratePassageHisto(int $oldPassId, int $newPassId, array $userMapping): int
|
||||
{
|
||||
$stmt = $this->sourceDb->prepare("
|
||||
SELECT * FROM ope_pass_histo WHERE fk_pass = :pass_id
|
||||
");
|
||||
$stmt->execute([':pass_id' => $oldPassId]);
|
||||
$histos = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if (empty($histos)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$count = 0;
|
||||
foreach ($histos as $histo) {
|
||||
$stmt = $this->targetDb->prepare("
|
||||
INSERT INTO ope_pass_histo (
|
||||
fk_pass, date_histo, sujet, remarque
|
||||
) VALUES (
|
||||
:fk_pass, :date_histo, :sujet, :remarque
|
||||
)
|
||||
");
|
||||
|
||||
$stmt->execute([
|
||||
':fk_pass' => $newPassId,
|
||||
':date_histo' => $histo['date_histo'],
|
||||
':sujet' => $histo['sujet'],
|
||||
':remarque' => $histo['remarque']
|
||||
]);
|
||||
|
||||
$count++;
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user