70 lines
4.2 KiB
JavaScript
70 lines
4.2 KiB
JavaScript
/*
|
|
* Bookmarklet « Indy → CSV » — version lisible (documentation).
|
|
* Le bouton prêt à installer est dans bookmarklet.html.
|
|
*
|
|
* 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/.
|
|
*/
|
|
(async () => {
|
|
const CC = [
|
|
["701", "Vente de produits finis"], ["707", "Vente de produits finis"],
|
|
["706", "Prestation de services"],
|
|
["605", "Matériel et outillage"], ["606", "Matériel et outillage"], ["607", "Matériel et outillage"],
|
|
["6256", "Frais de repas hors domicile"], ["6253", "Frais de repas hors domicile"],
|
|
["626", "Télécom, fournitures, documentation"],
|
|
["6181", "Télécom, fournitures, documentation"], ["6183", "Télécom, fournitures, documentation"],
|
|
["6136", "Abonnement logiciel"], ["6226", "Abonnement logiciel"],
|
|
["646", "Cotisation sociale Urssaf"],
|
|
["44551", "TVA payée"], ["44558", "TVA payée"], ["44583", "Remboursement de TVA"],
|
|
["108", "Prélèvement personnel"],
|
|
];
|
|
const CA = [["701", "vente"], ["707", "vente"], ["706", "service_bic"]];
|
|
const cat = (n) => { n = String(n || ""); let b = null; for (const [p, c] of CC) { if (n.startsWith(p) && (!b || p.length > b[0].length)) b = [p, c]; } return b ? b[1] : ""; };
|
|
const act = (n) => { n = String(n || ""); for (const [p, a] of CA) { if (n.startsWith(p)) return a; } return ""; };
|
|
const norm = (tx) => {
|
|
const c = tx.totalAmountInCents; if (c == null) return null;
|
|
const mt = (c / 100).toFixed(2);
|
|
const ss = (tx.subdivisions || []).filter(s => !String((s.accounting_account || {}).number || "").startsWith("512"));
|
|
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; }
|
|
const lib = (tx.description || tx.raw_description || "").replace(/;/g, " ");
|
|
return [tx.date || "", lib, cat(num), act(num), String(tx2), rg, mt].join(";");
|
|
};
|
|
const getTok = () => new Promise(r => {
|
|
const o = indexedDB.open("firebaseLocalStorageDb");
|
|
o.onsuccess = () => { try {
|
|
const q = o.result.transaction("firebaseLocalStorage", "readonly").objectStore("firebaseLocalStorage").getAll();
|
|
q.onsuccess = () => { const v = (q.result || []).map(x => x.value).find(v => v && v.stsTokenManager && v.stsTokenManager.accessToken); r(v ? v.stsTokenManager.accessToken : null); };
|
|
q.onerror = () => r(null);
|
|
} 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;
|
|
let all = [], pg = 1, tot = 1e9;
|
|
try {
|
|
while (all.length < tot) {
|
|
const u = "/api/transactions/transactions-list?" + new URLSearchParams({ search: "", dateFrom: d1, dateTo: d2, page: pg });
|
|
const r = await fetch(u, { headers: H, credentials: "include" });
|
|
if (!r.ok) throw new Error("HTTP " + r.status);
|
|
const j = await r.json();
|
|
tot = j.nbTransactions != null ? j.nbTransactions : (j.transactions || []).length;
|
|
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; }
|
|
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/)."); }
|
|
catch (e) { window.prompt("Copie ce CSV (Ctrl+C) :", csv); }
|
|
})();
|