V2.0: Refonte système bancaire - DB SQLite, RIB FR, TVA auto, multi-banques
- Remplace JSON par SQLite (aiosqlite) pour atomicité et intégrité - Nouveau format RIB français avec checksum modulo 97 - Chaque banque a son propre rôle Discord (isolation par serveur) - TVA automatique Particulier -> Entreprise, redirection au Fisc - Institutions gouvernementales avec droit d'audit optionnel - Commandes: /gouv, /banque, /audit, /mes-ribs - Supprime: 16 anciens fichiers (entreprises, FBM, URSAFF, etc.) - Reset complet des données, repart de zéro
This commit is contained in:
parent
2e38d05152
commit
c9ad155bf6
38 changed files with 3689 additions and 5106 deletions
55
utils/rib.py
Normal file
55
utils/rib.py
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import random
|
||||
import string
|
||||
|
||||
|
||||
def _checksum(digits: str) -> int:
|
||||
return (97 - (int(digits) % 97)) % 97
|
||||
|
||||
|
||||
def generer_rib(establishment_code: int, guichet_code: int) -> str:
|
||||
etab = str(establishment_code).zfill(5)
|
||||
guichet = str(guichet_code).zfill(5)
|
||||
numero = "".join(random.choices(string.digits, k=11))
|
||||
checksum_digits = f"76{etab}{guichet}{numero}"
|
||||
cle = str(_checksum(checksum_digits)).zfill(2)
|
||||
return f"FR76 {etab} {guichet} {numero} {cle}"
|
||||
|
||||
|
||||
def valider_rib(rib: str) -> bool:
|
||||
parts = rib.replace("FR76 ", "").split()
|
||||
if len(parts) != 3:
|
||||
return False
|
||||
etab, guichet, rest = parts
|
||||
if len(etab) != 5 or len(guichet) != 5:
|
||||
return False
|
||||
if len(rest) != 13:
|
||||
return False
|
||||
numero = rest[:11]
|
||||
cle = rest[11:]
|
||||
if not etab.isdigit() or not guichet.isdigit() or not numero.isdigit() or not cle.isdigit():
|
||||
return False
|
||||
checksum_digits = f"76{etab}{guichet}{numero}"
|
||||
return _checksum(checksum_digits) == int(cle)
|
||||
|
||||
|
||||
def decoder_rib(rib: str) -> dict:
|
||||
parts = rib.replace("FR76 ", "").split()
|
||||
if len(parts) != 3:
|
||||
return None
|
||||
etab, guichet, rest = parts
|
||||
numero = rest[:11]
|
||||
cle = rest[11:]
|
||||
etab_int = int(etab)
|
||||
guichet_int = int(guichet)
|
||||
|
||||
TYPE_MAP = {4: "particulier", 3: "entreprise", 2: "banque", 1: "institution"}
|
||||
|
||||
return {
|
||||
"etablissement": etab_int,
|
||||
"guichet": guichet_int,
|
||||
"numero": numero,
|
||||
"cle": int(cle),
|
||||
"type_compte": TYPE_MAP.get(guichet_int, "inconnu"),
|
||||
"est_gouvernement": etab_int < 100,
|
||||
"valide": valider_rib(rib),
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue