diff --git a/compta/__pycache__/indy.cpython-310.pyc b/compta/__pycache__/indy.cpython-310.pyc deleted file mode 100644 index d403d9c..0000000 Binary files a/compta/__pycache__/indy.cpython-310.pyc and /dev/null differ diff --git a/compta/__pycache__/views_import.cpython-310.pyc b/compta/__pycache__/views_import.cpython-310.pyc deleted file mode 100644 index c93eb67..0000000 Binary files a/compta/__pycache__/views_import.cpython-310.pyc and /dev/null differ diff --git a/compta/templates/compta/bookmarklet.html b/compta/templates/compta/bookmarklet.html new file mode 100644 index 0000000..d6cf190 --- /dev/null +++ b/compta/templates/compta/bookmarklet.html @@ -0,0 +1,60 @@ + + + + + +JB Compta — Favori Indy → CSV + + + +
← Retour à l'import
+

Favori « Indy → CSV »

+

Un clic sur la page Indy → tes transactions sont copiées au format CSV, + prêtes à coller dans JB Compta. Aucun token à chercher, la 2FA est déjà passée, et tout + se fait dans ton navigateur (donc indépendant de l'accès réseau du serveur).

+ +

Installation (30 s)

+
    +
  1. Affiche ta barre de favoris (Ctrl+Maj+B dans Chrome).
  2. +
  3. Glisse-dépose ce bouton dans la barre de favoris : +   Indy → CSV
  4. +
  5. Va sur app.indy.fr (connecté), puis clique le favori.
  6. +
  7. Choisis la période (sélecteur de date, format JJ/MM/AAAA) → le CSV est copié → + colle-le dans la page d'import.
  8. +
+ +
Si le glisser-déposer ne marche pas : crée un favori manuellement, + puis colle le code ci-dessous comme URL du favori.
+ +

Code (installation manuelle)

+ + +

Notes

+ + +{% verbatim %} + +{% endverbatim %} + + diff --git a/compta/templates/compta/import_csv.html b/compta/templates/compta/import_csv.html index 8bf24fe..1ca5e80 100644 --- a/compta/templates/compta/import_csv.html +++ b/compta/templates/compta/import_csv.html @@ -59,7 +59,8 @@
{% csrf_token %}

① Synchroniser depuis Indy (recommandé)

-
Récupère tes transactions directement depuis l'API Indy. Anti-doublon automatique.
+
Récupère tes transactions directement depuis l'API Indy. Anti-doublon automatique. + · 📌 Installer le favori « Indy → CSV » (le plus simple, depuis ton navigateur)
diff --git a/compta/urls.py b/compta/urls.py index cc0d9ff..152c844 100644 --- a/compta/urls.py +++ b/compta/urls.py @@ -2,6 +2,7 @@ from django.urls import path from . import views from . import views_saisie from . import views_import +from . import views_bookmarklet urlpatterns = [ path("dashboard/", views.dashboard, name="dashboard"), @@ -10,6 +11,7 @@ urlpatterns = [ path("declaration/tva/", views.declaration_tva, name="declaration_tva"), path("saisie/", views_saisie.saisie_paiement, name="saisie_paiement"), path("import/", views_import.import_csv, name="import_csv"), + path("import/bookmarklet/", views_bookmarklet.bookmarklet, name="bookmarklet"), path("export/ventes/", views.export_ventes, name="export_ventes"), path("export/tva/", views.export_tva, name="export_tva"), path("export/urssaf/", views.export_urssaf, name="export_urssaf"), diff --git a/indy-mcp/bookmarklet.html b/indy-mcp/bookmarklet.html index f2ebd13..e3f724c 100644 --- a/indy-mcp/bookmarklet.html +++ b/indy-mcp/bookmarklet.html @@ -20,35 +20,22 @@

Favori « Indy → CSV »

-

Un clic sur la page Indy → tes transactions sont copiées au format CSV, - prêtes à coller dans JB Compta. Pas de token à chercher, la 2FA est déjà passée, - et tout se fait dans ton navigateur (donc pas de souci d'accès serveur).

+

Identique à la page servie par l'app (/import/bookmarklet/). Un clic sur Indy → + CSV copié, prêt à coller dans JB Compta. Pas de token, 2FA déjà passée, tout dans le navigateur.

-

Installation (30 s)

+

Installation

    -
  1. Affiche ta barre de favoris (Ctrl+Maj+B dans Chrome).
  2. -
  3. Glisse-dépose ce bouton dans la barre de favoris : -   Indy → CSV
  4. -
  5. Va sur app.indy.fr (connecté), puis clique le favori.
  6. -
  7. Saisis la période → le CSV est copié → colle-le dans /import/ de JB Compta.
  8. +
  9. Affiche la barre de favoris (Ctrl+Maj+B).
  10. +
  11. Glisse ce bouton dans la barre :   Indy → CSV
  12. +
  13. Sur app.indy.fr (connecté), clique le favori, choisis la période (JJ/MM/AAAA).
  14. +
  15. Colle le CSV dans /import/.
-
Si le glisser-déposer ne marche pas : crée un favori manuellement, - puis colle le code ci-dessous comme URL du favori.
- -

Code (installation manuelle)

+
Si le glisser-déposer échoue, crée un favori manuel et colle ce code comme URL :
-

Notes

-
    -
  • À utiliser uniquement quand l'onglet actif est app.indy.fr.
  • -
  • Aucun secret n'est stocké : le favori lit ta session en cours.
  • -
  • Si une alerte « Erreur Indy » apparaît, reconnecte-toi à Indy et réessaie.
  • -
  • Le mapping des catégories (compte comptable → catégorie) est le même que dans l'app.
  • -
- diff --git a/indy-mcp/bookmarklet.js b/indy-mcp/bookmarklet.js index b229020..f88efb9 100644 --- a/indy-mcp/bookmarklet.js +++ b/indy-mcp/bookmarklet.js @@ -1,13 +1,15 @@ /* * Bookmarklet « Indy → CSV » — version lisible (documentation). - * Le bouton prêt à installer est dans bookmarklet.html. + * Le bouton prêt à installer est dans bookmarklet.html, et la même page est servie + * par l'application à /import/bookmarklet/. * - * Usage : être connecté sur app.indy.fr, cliquer le favori. Il demande une - * période, récupère les transactions (dans TON navigateur = autorisé, 2FA déjà - * passée, pas de problème Cloudflare ni d'accès serveur), construit le CSV au - * format JB Compta et le copie dans le presse-papier. Tu le colles dans /import/. + * Usage : être connecté sur app.indy.fr, cliquer le favori. Une petite fenêtre + * s'ouvre avec deux SÉLECTEURS DE DATE (format JJ/MM/AAAA). Il récupère ensuite les + * transactions (dans TON navigateur = autorisé, 2FA déjà passée, pas de souci serveur + * ni Cloudflare), construit le CSV au format JB Compta et le copie dans le presse-papier. */ (async () => { + // --- mapping compte PCG -> catégorie (identique à compta/indy.py) --- const CC = [ ["701", "Vente de produits finis"], ["707", "Vente de produits finis"], ["706", "Prestation de services"], @@ -30,12 +32,38 @@ if (!ss.length) return null; let m = ss[0]; for (const s of ss) if (Math.abs(s.amount_in_cents || 0) > Math.abs(m.amount_in_cents || 0)) m = s; const num = String((m.accounting_account || {}).number || ""); - let rg = "", tx2 = 0; - if (m.tva_intracom && m.tva_intracom.type === "eu") { rg = "intracom"; tx2 = (m.tva_intracom.rate || 0) / 100; } - else { tx2 = (m.tva_rate || 0) / 100; } + let rg = "", t2 = 0; + if (m.tva_intracom && m.tva_intracom.type === "eu") { rg = "intracom"; t2 = (m.tva_intracom.rate || 0) / 100; } + else { t2 = (m.tva_rate || 0) / 100; } const lib = (tx.description || tx.raw_description || "").replace(/;/g, " "); - return [tx.date || "", lib, cat(num), act(num), String(tx2), rg, mt].join(";"); + return [tx.date || "", lib, cat(num), act(num), String(t2), rg, mt].join(";"); }; + + // --- fenêtre avec deux sélecteurs de date (input type=date -> JJ/MM/AAAA) --- + const mk = (t, css) => { const e = document.createElement(t); if (css) e.style.cssText = css; return e; }; + const askDates = () => new Promise(res => { + const t = new Date(), y = t.getFullYear(), + mo = String(t.getMonth() + 1).padStart(2, "0"), + ld = String(new Date(y, t.getMonth() + 1, 0).getDate()).padStart(2, "0"); + const ov = mk("div", "position:fixed;inset:0;background:rgba(0,0,0,.6);z-index:2147483647;display:flex;align-items:center;justify-content:center"); + const bx = mk("div", "background:#fff;color:#111;padding:20px;border-radius:12px;font-family:sans-serif;min-width:280px"); + const h = mk("div", "font-weight:700;margin-bottom:12px"); h.textContent = "Indy vers CSV : choisis la periode"; + const l1 = mk("div", "font-size:12px;color:#555"); l1.textContent = "Du"; + const i1 = mk("input", "width:100%;margin:4px 0 10px;padding:6px"); i1.type = "date"; i1.value = y + "-" + mo + "-01"; + const l2 = mk("div", "font-size:12px;color:#555"); l2.textContent = "Au"; + const i2 = mk("input", "width:100%;margin:4px 0 14px;padding:6px"); i2.type = "date"; i2.value = y + "-" + mo + "-" + ld; + const row = mk("div", "text-align:right"); + const an = mk("button", "margin-right:8px;padding:6px 12px"); an.textContent = "Annuler"; + const ok = mk("button", "background:#38bdf8;border:none;padding:6px 14px;border-radius:6px;cursor:pointer"); ok.textContent = "Recuperer"; + row.appendChild(an); row.appendChild(ok); + [h, l1, i1, l2, i2, row].forEach(x => bx.appendChild(x)); + ov.appendChild(bx); document.body.appendChild(ov); + ok.onclick = () => { const a = i1.value, b = i2.value; document.body.removeChild(ov); res([a, b]); }; + an.onclick = () => { document.body.removeChild(ov); res([null, null]); }; + }); + const [d1, d2] = await askDates(); if (!d1 || !d2) return; + + // --- token Firebase (depuis IndexedDB) --- const getTok = () => new Promise(r => { const o = indexedDB.open("firebaseLocalStorageDb"); o.onsuccess = () => { try { @@ -45,11 +73,11 @@ } catch (e) { r(null); } }; o.onerror = () => r(null); }); - const d1 = prompt("Date début (AAAA-MM-JJ)"); if (!d1) return; - const d2 = prompt("Date fin (AAAA-MM-JJ)"); if (!d2) return; const tk = await getTok(); const H = { "Accept": "application/json", "x-client-app-type": "web" }; if (tk) H["Authorization"] = "Bearer " + tk; + + // --- fetch paginé --- let all = [], pg = 1, tot = 1e9; try { while (all.length < tot) { @@ -61,9 +89,11 @@ const t = j.transactions || []; if (!t.length) break; all = all.concat(t); pg++; if (pg > 60) break; } - } catch (e) { alert("Erreur Indy : " + e.message + "\nEs-tu bien connecté sur app.indy.fr ?"); return; } + } catch (e) { alert("Erreur Indy : " + e.message); return; } + const rows = all.map(norm).filter(Boolean); - const csv = "date;libelle;categorie;activite;taux_tva;regime;montant\n" + rows.join("\n"); - try { await navigator.clipboard.writeText(csv); alert(rows.length + " opérations -> CSV copié ! Colle-le dans JB Compta (/import/)."); } + const NL = String.fromCharCode(10); + const csv = "date;libelle;categorie;activite;taux_tva;regime;montant" + NL + rows.join(NL); + try { await navigator.clipboard.writeText(csv); alert(rows.length + " operations -> CSV copie ! Colle-le dans JB Compta (/import/)."); } catch (e) { window.prompt("Copie ce CSV (Ctrl+C) :", csv); } })();