diff --git a/migrate_categories_order.php b/migrate_categories_order.php
new file mode 100644
index 0000000..b7ae432
--- /dev/null
+++ b/migrate_categories_order.php
@@ -0,0 +1,64 @@
+🚀 Migration : Ajout de l'ordre des catégories";
+
+try {
+ // Connexion au serveur MySQL (sans spécifier de base de données particulière)
+ $pdo = new PDO("mysql:host=$host;charset=utf8mb4", $user, $pass);
+ $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+
+ // 1. Trouver toutes les bases de données de la famille HouseHub
+ $stmt = $pdo->query("SHOW DATABASES LIKE 'househub_f%'");
+ $databases = $stmt->fetchAll(PDO::FETCH_COLUMN);
+
+ if (empty($databases)) {
+ echo "
❌ Aucune base de données correspondant à 'househub_f*' n'a été trouvée.
";
+ exit;
+ }
+
+ echo "
🔍 " . count($databases) . " base(s) de données trouvée(s).
";
+
+ // 2. Boucler sur chaque base de données
+ foreach ($databases as $db) {
+ echo "
";
+ echo "
📂 Traitement de la base : $db
";
+
+ // Sélectionner la base de données active
+ $pdo->exec("USE `$db`");
+
+ // Vérifier si la table pf_budget_categories existe dans cette DB
+ $tableExists = $pdo->query("SHOW TABLES LIKE 'pf_budget_categories'")->rowCount() > 0;
+
+ if ($tableExists) {
+ // Vérifier si la colonne sort_order existe déjà (sécurité)
+ $columnExists = $pdo->query("SHOW COLUMNS FROM pf_budget_categories LIKE 'sort_order'")->rowCount() > 0;
+
+ if (!$columnExists) {
+ // La colonne n'existe pas, on l'ajoute !
+ $pdo->exec("ALTER TABLE pf_budget_categories ADD sort_order INT DEFAULT 0");
+ echo "✅ Colonne 'sort_order' ajoutée avec succès !";
+ } else {
+ // La colonne est déjà là
+ echo "ℹ️ La colonne 'sort_order' existe déjà (Ignoré).";
+ }
+ } else {
+ echo "⚠️ La table 'pf_budget_categories' n'existe pas ici.";
+ }
+ echo "
";
+ }
+
+ echo "
🎉 Migration terminée avec succès !
";
+ echo "
Tu peux maintenant supprimer ce fichier par mesure de sécurité.
";
+
+} catch (PDOException $e) {
+ echo "
❌ Erreur fatale MySQL :
";
+ echo "
" . $e->getMessage() . "
";
+}
+?>
\ No newline at end of file
diff --git a/modules/budget/includes/api/settings.php b/modules/budget/includes/api/settings.php
index 11535ce..cd75844 100644
--- a/modules/budget/includes/api/settings.php
+++ b/modules/budget/includes/api/settings.php
@@ -168,6 +168,19 @@ try {
exit;
}
+ // SAUVEGARDE DU NOUVEL ORDRE DES CATÉGORIES
+ if (isset($_POST['action']) && $_POST['action'] === 'save_categories_order') {
+ $ids = json_decode($_POST['order'], true);
+ if (is_array($ids)) {
+ $stmt = $pdo->prepare("UPDATE pf_budget_categories SET sort_order = ? WHERE id = ?");
+ foreach ($ids as $index => $id) {
+ $stmt->execute([$index, (int)$id]);
+ }
+ }
+ echo json_encode(['success' => true]);
+ exit;
+ }
+
throw new Exception("Action API inconnue.");
} catch (Exception $e) {
diff --git a/modules/budget/views/settings_modal.php b/modules/budget/views/settings_modal.php
index aa75322..d3c4ac4 100644
--- a/modules/budget/views/settings_modal.php
+++ b/modules/budget/views/settings_modal.php
@@ -305,16 +305,25 @@ function renderCategories(categories) {
container.innerHTML = `${tr('bs_empty_categories')}`;
return;
}
+
+ // Tri JS pour respecter l'ordre au chargement de la modale
+ categories.sort((a, b) => {
+ if (a.type !== b.type) return a.type === 'Income' ? -1 : 1;
+ return (a.sort_order || 0) - (b.sort_order || 0);
+ });
+
let html = '';
categories.forEach(cat => {
let typeLabel = cat.type === 'Income' ? tr('bs_type_income') : cat.type === 'Expense' ? tr('bs_type_expense') : tr('bs_type_savings_cat');
html += `
-