Changes to be committed:

modified:   .env.example
	new file:   compta/__pycache__/__init__.cpython-310.pyc
	new file:   compta/__pycache__/admin.cpython-310.pyc
	new file:   compta/__pycache__/apps.cpython-310.pyc
	new file:   compta/__pycache__/models.cpython-310.pyc
	modified:   compta/admin.py
	new file:   compta/categories_indy.py
	modified:   compta/indy.py
	modified:   compta/management/commands/seed_reference.py
	new file:   compta/migrations/0010_categorie_compte_pcg.py
	modified:   compta/models.py
	modified:   compta/templates/compta/base.html
	new file:   compta/templates/compta/gestion.html
	modified:   compta/urls.py
	new file:   compta/views_gestion.py
	new file:   config/__pycache__/__init__.cpython-310.pyc
	new file:   config/__pycache__/settings.cpython-310.pyc
	modified:   config/settings.py
	modified:   entrypoint.sh
This commit is contained in:
2026-07-11 20:27:51 +02:00
parent 358cf35790
commit 0a4ba2001b
19 changed files with 743 additions and 63 deletions
+10 -34
View File
@@ -1,9 +1,10 @@
"""
Synchronisation Indy : récupère les transactions via l'API privée d'Indy et les
normalise au format attendu par l'import (réutilisé par la page /import/).
normalise au format d'import.
La « catégorie » Indy est un numéro de compte du plan comptable (PCG) ; on le
mappe vers nos catégories. Montants en centimes, signés. `tva_intracom` => UE.
La « catégorie » Indy = un numéro de compte du plan comptable (PCG). On mappe ce
numéro vers nos catégories via le catalogue (categories_indy). Montants en
centimes, signés. `tva_intracom` => UE (autoliquidation).
API non officielle d'Indy : pour les données de l'utilisateur. Le token JWT
expire (~1 h) et doit être renouvelé.
@@ -12,43 +13,18 @@ from decimal import Decimal
import httpx
from .categories_indy import COMPTE_VERS_NOM, COMPTE_ACTIVITE
BASE_URL = "https://app.indy.fr"
TRANSACTIONS_PATH = "/api/transactions/transactions-list"
COMPTE_CATEGORIE = [
("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"),
]
COMPTE_ACTIVITE = [("701", "vente"), ("707", "vente"), ("706", "service_bic")]
def _cat(num):
num = str(num or "")
best = None
for pref, cat in COMPTE_CATEGORIE:
if num.startswith(pref) and (best is None or len(pref) > len(best[0])):
best = (pref, cat)
return best[1] if best else None
return COMPTE_VERS_NOM.get(str(num or ""))
def _act(num):
num = str(num or "")
for pref, act in COMPTE_ACTIVITE:
if num.startswith(pref):
return act
return ""
return COMPTE_ACTIVITE.get(str(num or ""), "")
def normaliser(tx):
@@ -109,12 +85,12 @@ def fetch_transactions(token, date_debut=None, date_fin=None, search="", page=1,
return r.status_code, [], (
"Reponse non-JSON (probablement Cloudflare). Le conteneur n'arrive "
"pas a joindre Indy directement. Recupere le CSV depuis ton poste "
"(MCP/CLI) et colle-le ci-dessous.")
"(favori/MCP) et colle-le ci-dessous.")
data = r.json()
return 200, data.get("transactions", []), None
except httpx.TimeoutException:
return None, [], ("Delai depasse en joignant Indy : le conteneur n'a peut-etre "
"pas d'acces Internet, ou Cloudflare bloque. Utilise le CSV "
"pas d'acces Internet, ou Cloudflare bloque. Utilise le favori "
"depuis ton poste.")
except Exception as ex: # noqa: BLE001
return None, [], f"{type(ex).__name__}: {ex}"