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:
pierre
2025-11-09 18:26:27 +01:00
parent 21657a3820
commit 2f5946a184
812 changed files with 142105 additions and 25992 deletions

View File

@@ -0,0 +1,240 @@
#!/usr/bin/env php
<?php
/**
* Script : Créer les Stripe Terminal Locations manquantes
*
* Raison : Certains comptes Stripe Connect ont été créés avant l'implémentation
* de la création automatique de Location. Ce script crée les Locations
* manquantes pour tous les comptes existants.
*
* Date : 2025-11-03
* Auteur : Migration automatique
*/
// Simuler l'environnement web pour AppConfig en CLI
if (php_sapi_name() === 'cli') {
$hostname = gethostname();
if (strpos($hostname, 'pra') !== false) {
$_SERVER['SERVER_NAME'] = 'app3.geosector.fr';
} elseif (strpos($hostname, 'rca') !== false) {
$_SERVER['SERVER_NAME'] = 'rapp.geosector.fr';
} else {
$_SERVER['SERVER_NAME'] = 'dapp.geosector.fr';
}
$_SERVER['HTTP_HOST'] = $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'];
$_SERVER['REMOTE_ADDR'] = $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1';
if (!function_exists('getallheaders')) {
function getallheaders() {
return [];
}
}
}
// Charger l'autoloader Composer (pour Stripe SDK)
require_once dirname(dirname(__DIR__)) . '/vendor/autoload.php';
// Charger les classes nécessaires explicitement
require_once dirname(dirname(__DIR__)) . '/src/Config/AppConfig.php';
require_once dirname(dirname(__DIR__)) . '/src/Core/Database.php';
require_once dirname(dirname(__DIR__)) . '/src/Services/ApiService.php';
require_once dirname(dirname(__DIR__)) . '/src/Services/LogService.php';
require_once dirname(dirname(__DIR__)) . '/src/Services/StripeService.php';
use App\Services\StripeService;
// Initialiser la configuration
$config = AppConfig::getInstance();
$env = $config->getEnvironment();
$dbConfig = $config->getDatabaseConfig();
echo "\n";
echo "=============================================================================\n";
echo " Création des Stripe Terminal Locations manquantes\n";
echo "=============================================================================\n";
echo "Environnement : " . strtoupper($env) . "\n";
echo "Base de données : " . $dbConfig['name'] . "\n";
echo "\n";
try {
// Initialiser la base de données avec la configuration
Database::init($dbConfig);
$db = Database::getInstance();
// StripeService est un singleton
$stripeService = StripeService::getInstance();
// 1. Identifier les comptes sans Location
echo "📋 Recherche des comptes Stripe sans Location...\n\n";
$stmt = $db->query("
SELECT
sa.id,
sa.fk_entite,
sa.stripe_account_id,
sa.stripe_location_id,
e.encrypted_name,
e.adresse1,
e.adresse2,
e.code_postal,
e.ville
FROM stripe_accounts sa
INNER JOIN entites e ON sa.fk_entite = e.id
WHERE sa.stripe_account_id IS NOT NULL
AND (sa.stripe_location_id IS NULL OR sa.stripe_location_id = '')
AND e.chk_active = 1
");
$accountsWithoutLocation = $stmt->fetchAll(PDO::FETCH_ASSOC);
$total = count($accountsWithoutLocation);
if ($total === 0) {
echo "✅ Aucun compte sans Location trouvé. Tous les comptes sont à jour !\n\n";
exit(0);
}
echo " Trouvé $total compte(s) sans Location :\n\n";
foreach ($accountsWithoutLocation as $account) {
$name = !empty($account['encrypted_name'])
? ApiService::decryptData($account['encrypted_name'])
: 'Amicale #' . $account['fk_entite'];
echo " - Entité #{$account['fk_entite']} : $name\n";
echo " Stripe Account : {$account['stripe_account_id']}\n";
echo " Adresse : {$account['adresse1']}, {$account['code_postal']} {$account['ville']}\n\n";
}
// Demander confirmation
echo "⚠️ Voulez-vous créer les Locations manquantes ? (yes/no) : ";
$handle = fopen("php://stdin", "r");
$line = trim(fgets($handle));
fclose($handle);
if ($line !== 'yes') {
echo "❌ Opération annulée.\n\n";
exit(0);
}
echo "\n🚀 Création des Locations...\n\n";
// Initialiser Stripe avec la bonne clé selon le mode
$stripeConfig = $config->getStripeConfig();
$stripeMode = $stripeConfig['mode'] ?? 'test';
$stripeSecretKey = ($stripeMode === 'live')
? $stripeConfig['secret_key_live']
: $stripeConfig['secret_key_test'];
\Stripe\Stripe::setApiKey($stripeSecretKey);
echo " Mode Stripe : " . strtoupper($stripeMode) . "\n\n";
$success = 0;
$errors = 0;
// 2. Créer les Locations manquantes
foreach ($accountsWithoutLocation as $account) {
$entiteId = $account['fk_entite'];
$stripeAccountId = $account['stripe_account_id'];
$name = !empty($account['encrypted_name'])
? ApiService::decryptData($account['encrypted_name'])
: 'Amicale #' . $entiteId;
echo "🔧 Entité #{$entiteId} : $name\n";
try {
// Construire l'adresse
$adresse1 = !empty($account['adresse1']) ? $account['adresse1'] : 'Adresse non renseignée';
$ville = !empty($account['ville']) ? $account['ville'] : 'Ville';
$codePostal = !empty($account['code_postal']) ? $account['code_postal'] : '00000';
// Construire l'adresse pour Stripe (ne pas envoyer line2 si vide)
$addressData = [
'line1' => $adresse1,
'city' => $ville,
'postal_code' => $codePostal,
'country' => 'FR',
];
// Ajouter line2 seulement s'il n'est pas vide
if (!empty($account['adresse2'])) {
$addressData['line2'] = $account['adresse2'];
}
// Créer la Location via Stripe API
$location = \Stripe\Terminal\Location::create([
'display_name' => $name,
'address' => $addressData,
'metadata' => [
'entite_id' => $entiteId,
'type' => 'tap_to_pay',
'created_by' => 'migration_script'
]
], [
'stripe_account' => $stripeAccountId
]);
$locationId = $location->id;
// Mettre à jour la base de données
$updateStmt = $db->prepare("
UPDATE stripe_accounts
SET stripe_location_id = :location_id,
updated_at = NOW()
WHERE id = :id
");
$updateStmt->execute([
'location_id' => $locationId,
'id' => $account['id']
]);
echo " ✅ Location créée : $locationId\n\n";
$success++;
} catch (\Stripe\Exception\ApiErrorException $e) {
echo " ❌ Erreur Stripe : " . $e->getMessage() . "\n\n";
$errors++;
} catch (Exception $e) {
echo " ❌ Erreur : " . $e->getMessage() . "\n\n";
$errors++;
}
}
// 3. Résumé
echo "\n";
echo "=============================================================================\n";
echo " Résumé de l'opération\n";
echo "=============================================================================\n";
echo "✅ Locations créées avec succès : $success\n";
echo "❌ Erreurs : $errors\n";
echo "📊 Total traité : $total\n";
echo "\n";
// 4. Vérification finale
echo "🔍 Vérification finale...\n";
$stmt = $db->query("
SELECT COUNT(*) as remaining
FROM stripe_accounts sa
WHERE sa.stripe_account_id IS NOT NULL
AND (sa.stripe_location_id IS NULL OR sa.stripe_location_id = '')
");
$remaining = $stmt->fetch(PDO::FETCH_ASSOC);
echo " Comptes restants sans Location : " . $remaining['remaining'] . "\n\n";
if ($remaining['remaining'] == 0) {
echo "🎉 Tous les comptes Stripe ont maintenant une Location !\n\n";
}
} catch (Exception $e) {
echo "\n";
echo "=============================================================================\n";
echo " ❌ ERREUR\n";
echo "=============================================================================\n";
echo "Message : " . $e->getMessage() . "\n";
echo "Fichier : " . $e->getFile() . ":" . $e->getLine() . "\n";
echo "\n";
exit(1);
}