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:
utilisateurqu 2026-08-18 17:42:03 +02:00
parent 2e38d05152
commit c9ad155bf6
38 changed files with 3689 additions and 5106 deletions

View file

@ -1,148 +0,0 @@
import discord
from discord import app_commands
from discord.ext import commands, tasks
import json
import datetime
ABONNEMENTS_FILE = "abonnements.json"
BANQUES_DISPONIBLES = [
"Victoria's Credit Bank",
"NGC Bank"
]
JOURS_SEMAINE = [
"lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche"
]
class Abonnement(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.abonnements = self.load_abonnements()
self.executer_abonnements.start()
def load_abonnements(self):
try:
with open(ABONNEMENTS_FILE, 'r', encoding='utf-8') as f:
return json.load(f)
except (FileNotFoundError, json.JSONDecodeError):
return []
def save_abonnements(self):
with open(ABONNEMENTS_FILE, 'w', encoding='utf-8') as f:
json.dump(self.abonnements, f, ensure_ascii=False, indent=4)
# 🎯 Auto-complétion pour les banques
async def autocomplete_banque(self, interaction: discord.Interaction, current: str):
return [
app_commands.Choice(name=b, value=b)
for b in BANQUES_DISPONIBLES if current.lower() in b.lower()
]
# 🎯 Auto-complétion pour les jours
async def autocomplete_jour(self, interaction: discord.Interaction, current: str):
return [
app_commands.Choice(name=day.capitalize(), value=day)
for day in JOURS_SEMAINE if current.lower() in day
]
@app_commands.command(name="abonnement", description="Crée un abonnement bancaire hebdomadaire.")
@app_commands.describe(
nom="Nom de l'abonnement",
rib_emetteur="RIB de l'expéditeur",
montant="Montant à envoyer",
rib_receveur="RIB du bénéficiaire",
banque="Nom de la banque",
jour="Jour de la semaine du virement"
)
@app_commands.autocomplete(banque=autocomplete_banque, jour=autocomplete_jour)
async def abonnement(
self,
interaction: discord.Interaction,
nom: str,
rib_emetteur: str,
montant: float,
rib_receveur: str,
banque: str,
jour: str
):
if jour.lower() not in JOURS_SEMAINE:
await interaction.response.send_message("❌ Jour invalide. Choisissez un jour valide de la semaine.", ephemeral=True)
return
abonnement = {
"nom": nom,
"rib_emetteur": rib_emetteur,
"rib_receveur": rib_receveur,
"montant": montant,
"banque": banque,
"jour": jour.lower()
}
self.abonnements.append(abonnement)
self.save_abonnements()
await interaction.response.send_message(f"✅ Abonnement **{nom}** enregistré. Virement automatique tous les **{jour}**.", ephemeral=True)
@tasks.loop(minutes=60)
async def executer_abonnements(self):
today = datetime.datetime.now().strftime("%A").lower()
try:
with open("comptes_bancaires.json", "r", encoding="utf-8") as f:
comptes = json.load(f)
except:
comptes = {}
updated = False
for abonnement in self.abonnements:
if abonnement["jour"] != today:
continue
banque = abonnement["banque"]
rib_emetteur = abonnement["rib_emetteur"]
rib_receveur = abonnement["rib_receveur"]
montant = abonnement["montant"]
destinataire_id = None
emetteur_id = None
for user_id, data in comptes.get(banque, {}).items():
if data.get("rib") == rib_emetteur:
emetteur_id = user_id
if data.get("rib") == rib_receveur:
destinataire_id = user_id
if not emetteur_id or not destinataire_id:
continue
if comptes[banque][emetteur_id]["solde"] < montant:
continue
comptes[banque][emetteur_id]["solde"] -= montant
comptes[banque][emetteur_id]["transactions"].append({
"date": datetime.datetime.now().strftime("%d/%m/%Y %H:%M:%S"),
"type": "Virement automatique (abonnement)",
"source": f"Vers RIB {rib_receveur}",
"montant": -montant
})
comptes[banque][destinataire_id]["solde"] += montant
comptes[banque][destinataire_id]["transactions"].append({
"date": datetime.datetime.now().strftime("%d/%m/%Y %H:%M:%S"),
"type": "Virement reçu (abonnement)",
"source": f"{rib_emetteur}",
"montant": montant
})
updated = True
if updated:
with open("comptes_bancaires.json", 'w', encoding='utf-8') as f:
json.dump(comptes, f, ensure_ascii=False, indent=4)
@executer_abonnements.before_loop
async def before_abonnement_loop(self):
await self.bot.wait_until_ready()
async def setup(bot):
await bot.add_cog(Abonnement(bot))

View file

@ -1,145 +0,0 @@
import discord
from discord import app_commands
from discord.ext import commands
import json
from datetime import datetime
from utils.guild_config import has_role
class AjouterArgent(commands.Cog):
def __init__(self, bot):
self.bot = bot
# Choix de banques automatiques
banque_choices = [
app_commands.Choice(name="Victoria's Credit Bank", value="Victoria's Credit Bank"),
app_commands.Choice(name="NGC Bank", value="NGC Bank"),
]
@app_commands.command(
name="ajouter_argent",
description="Ajoute de l'argent à un compte (réservé aux banquiers)."
)
@app_commands.choices(banque=banque_choices)
@app_commands.describe(
rib="Le RIB du compte",
montant="Montant à ajouter",
banque="Banque cible (facultatif)"
)
async def ajouter_argent(
self,
interaction: discord.Interaction,
rib: str,
montant: float,
banque: app_commands.Choice[str] = None
):
# Vérification du rôle
if not has_role(interaction.user, "banquier"):
await interaction.response.send_message(
"❌ Vous n'avez pas la permission d'utiliser cette commande.",
ephemeral=True
)
return
if montant <= 0:
await interaction.response.send_message(
"❌ Le montant doit être supérieur à zéro.",
ephemeral=True
)
return
banque_nom = banque.value if banque else None
# Chargement des fichiers
with open("comptes_bancaires.json", "r", encoding="utf-8") as f:
comptes = json.load(f)
with open("comptes_entreprises.json", "r", encoding="utf-8") as f:
entreprises = json.load(f)
cible_data = None
user_id = None
is_entreprise = False
# Recherche dans la banque spécifiée (si précisée)
if banque_nom and banque_nom in comptes:
for uid, info in comptes[banque_nom].items():
if info.get("rib") == rib:
cible_data = comptes
user_id = uid
break
if not user_id and banque_nom and banque_nom in entreprises:
for nom_entreprise, info in entreprises[banque_nom].items():
if info.get("rib") == rib:
cible_data = entreprises
user_id = nom_entreprise
is_entreprise = True
break
# Si banque non précisée ou compte non trouvé, recherche dans toutes les banques
if not user_id and not banque_nom:
# Recherche dans toutes les banques utilisateurs
for banque_courante, comptes_banque in comptes.items():
for uid, info in comptes_banque.items():
if info.get("rib") == rib:
cible_data = comptes
user_id = uid
banque_nom = banque_courante
break
if user_id:
break
if not user_id and not is_entreprise:
# Recherche dans toutes les banques entreprises
for banque_courante, entreprises_banque in entreprises.items():
for nom_entreprise, info in entreprises_banque.items():
if info.get("rib") == rib:
cible_data = entreprises
user_id = nom_entreprise
banque_nom = banque_courante
is_entreprise = True
break
if user_id:
break
if not user_id:
await interaction.response.send_message(
"❌ Aucun compte trouvé avec ce RIB.",
ephemeral=True
)
return
# Ajout du montant
cible_data[banque_nom][user_id]["solde"] += montant
transaction = {
"date": datetime.now().strftime("%d/%m/%Y %H:%M:%S"),
"type": "Dépôt",
"source": "Banque",
"montant": montant,
"emetteur": interaction.user.id,
"destinataire": user_id
}
cible_data[banque_nom][user_id]["transactions"].append(transaction)
# Sauvegarde
if is_entreprise:
with open("comptes_entreprises.json", "w", encoding="utf-8") as f:
json.dump(entreprises, f, ensure_ascii=False, indent=4)
else:
with open("comptes_bancaires.json", "w", encoding="utf-8") as f:
json.dump(comptes, f, ensure_ascii=False, indent=4)
# Envoyer un MP à l'utilisateur (sauf entreprise)
try:
user = await self.bot.fetch_user(int(user_id))
await user.send(
f"💰 Un dépôt de **{montant:.2f}€** a été effectué sur votre compte dans **{banque_nom}**."
)
except Exception:
pass # Si l'utilisateur a désactivé les MP
await interaction.response.send_message(
f"✅ **{montant:.2f}€** ajoutés avec succès au compte `{rib}` dans la banque **{banque_nom}**.",
ephemeral=True
)
async def setup(bot):
await bot.add_cog(AjouterArgent(bot))

75
commandes/audit.py Normal file
View file

@ -0,0 +1,75 @@
import discord
from discord import app_commands
from discord.ext import commands
from utils.guild_config import has_role, get_guild_role
from utils.bank_manager import BankManager
bank_manager = BankManager()
class Audit(commands.Cog):
def __init__(self, bot):
self.bot = bot
audit_group = app_commands.Group(name="audit", description="Audit bancaire (institutions)")
@audit_group.command(name="consulter-banque", description="Consulter les comptes d'une banque (institutions avec audit)")
@app_commands.describe(nom_banque="Nom de la banque à auditer")
async def consulter_banque(self, interaction: discord.Interaction, nom_banque: str):
user_roles = [r.id for r in interaction.user.roles]
institutions = await bank_manager.lister_institutions(interaction.guild.id)
authorized = None
for inst in institutions:
if inst["role_id"] and inst["role_id"] in user_roles and inst["can_audit_all"]:
authorized = inst
break
if not authorized:
await interaction.response.send_message(
"❌ Vous n'avez pas le droit d'audit. Réservé aux institutions avec le droit d'audit activé.",
ephemeral=True,
)
return
banque = await bank_manager.get_banque_by_name(interaction.guild.id, nom_banque)
if not banque:
banques = await bank_manager.lister_banques(interaction.guild.id)
noms = ", ".join(b["name"] for b in banques) or "aucune"
await interaction.response.send_message(
f"❌ Banque **{nom_banque}** introuvable. Banques disponibles : {noms}",
ephemeral=True,
)
return
comptes = await bank_manager.get_comptes_banque(interaction.guild.id, banque["id"])
if not comptes:
await interaction.response.send_message("Aucun compte dans cette banque.", ephemeral=True)
return
embed = discord.Embed(
title=f"🔍 Audit : {banque['name']}",
description=f"Effectué par l'institution **{authorized['name']}**",
color=discord.Color.orange(),
)
for c in comptes:
member = interaction.guild.get_member(c["user_id"])
name = member.display_name if member else f"User#{c['user_id']}"
tva_text = f" | TVA: {c['tva_rate']}%" if c["account_type"] == "entreprise" else ""
embed.add_field(
name=f"{name} ({c['account_type']})",
value=(
f"**RIB :** `{c['rib']}`\n"
f"**Solde :** `{c['solde']:.2f}€`{tva_text}"
),
inline=False,
)
embed.set_footer(text=f"Total : {len(comptes)} compte(s) | Réserve banque : {banque['vault_balance']:.2f}€")
await interaction.response.send_message(embed=embed, ephemeral=True)
async def setup(bot):
await bot.add_cog(Audit(bot))

245
commandes/banque.py Normal file
View file

@ -0,0 +1,245 @@
import discord
from discord import app_commands
from discord.ext import commands
from utils.guild_config import has_role, get_guild_role
from utils.bank_manager import BankManager
from utils.rib import decoder_rib
bank_manager = BankManager()
class Banque(commands.Cog):
def __init__(self, bot):
self.bot = bot
banque_group = app_commands.Group(name="banque", description="Opérations bancaires")
async def _get_user_bank(self, interaction: discord.Interaction) -> dict:
banques = await bank_manager.lister_banques(interaction.guild.id)
for b in banques:
role = interaction.guild.get_role(b["role_id"])
if role and role in interaction.user.roles:
return b
return None
@banque_group.command(name="ouvrir-compte", description="Ouvrir un compte pour un membre")
@app_commands.describe(
membre="Le membre qui recevra le compte",
type_compte="Type de compte",
taux_tva="Taux TVA (entreprises uniquement, défaut 0%)"
)
@app_commands.choices(
type_compte=[
app_commands.Choice(name="Particulier", value="particulier"),
app_commands.Choice(name="Entreprise", value="entreprise"),
]
)
async def ouvrir_compte(
self,
interaction: discord.Interaction,
membre: discord.Member,
type_compte: app_commands.Choice[str],
taux_tva: float = 0.0,
):
bank = await self._get_user_bank(interaction)
if not bank:
await interaction.response.send_message(
"❌ Vous n'avez pas de rôle de banquier sur ce serveur.", ephemeral=True
)
return
if type_compte.value == "entreprise" and taux_tva < 0:
await interaction.response.send_message("❌ Le taux TVA ne peut pas être négatif.", ephemeral=True)
return
try:
result = await bank_manager.ouvrir_compte(
guild_id=interaction.guild.id,
bank_id=bank["id"],
user_id=membre.id,
account_type=type_compte.value,
tva_rate=taux_tva if type_compte.value == "entreprise" else 0.0,
)
embed = discord.Embed(
title="💳 Compte ouvert",
description=(
f"**Banque :** {bank['name']}\n"
f"**Membre :** {membre.mention}\n"
f"**Type :** {type_compte.value.title()}\n"
f"**RIB :** `{result['rib']}`\n"
),
color=discord.Color.green(),
)
if type_compte.value == "entreprise":
embed.add_field(name="Taux TVA", value=f"{taux_tva}%")
await interaction.response.send_message(embed=embed, ephemeral=True)
try:
await membre.send(
f"💳 Votre compte **{type_compte.value}** chez **{bank['name']}** a été ouvert.\n"
f"**RIB :** `{result['rib']}`"
)
except discord.Forbidden:
pass
except ValueError as e:
await interaction.response.send_message(f"❌ {e}", ephemeral=True)
@banque_group.command(name="modifier-tva", description="Modifier le taux TVA d'une entreprise")
@app_commands.describe(
rib="RIB de l'entreprise",
nouveau_taux="Nouveau taux TVA (ex: 5.5, 20)"
)
async def modifier_tva(self, interaction: discord.Interaction, rib: str, nouveau_taux: float):
bank = await self._get_user_bank(interaction)
if not bank:
await interaction.response.send_message(
"❌ Vous n'avez pas de rôle de banquier sur ce serveur.", ephemeral=True
)
return
if nouveau_taux < 0 or nouveau_taux > 100:
await interaction.response.send_message("❌ Le taux doit être entre 0 et 100%.", ephemeral=True)
return
compte = await bank_manager.get_compte_by_rib(interaction.guild.id, rib)
if not compte:
await interaction.response.send_message("❌ Compte introuvable.", ephemeral=True)
return
if compte["bank_id"] != bank["id"]:
await interaction.response.send_message("❌ Ce RIB n'appartient pas à votre banque.", ephemeral=True)
return
if compte["account_type"] != "entreprise":
await interaction.response.send_message("❌ La TVA ne s'applique qu'aux comptes entreprise.", ephemeral=True)
return
ok = await bank_manager.modifier_tva(interaction.guild.id, rib, nouveau_taux)
if ok:
await interaction.response.send_message(
f"✅ Taux TVA mis à jour : **{nouveau_taux}%** pour `{rib}`.", ephemeral=True
)
else:
await interaction.response.send_message("❌ Erreur lors de la mise à jour.", ephemeral=True)
@banque_group.command(name="consulter-clients", description="Voir tous les comptes de votre banque")
async def consulter_clients(self, interaction: discord.Interaction):
bank = await self._get_user_bank(interaction)
if not bank:
await interaction.response.send_message(
"❌ Vous n'avez pas de rôle de banquier sur ce serveur.", ephemeral=True
)
return
comptes = await bank_manager.get_comptes_banque(interaction.guild.id, bank["id"])
if not comptes:
await interaction.response.send_message("Aucun compte dans cette banque.", ephemeral=True)
return
embed = discord.Embed(
title=f"🏦 Clients de {bank['name']}",
color=discord.Color.blue(),
)
for c in comptes:
member = interaction.guild.get_member(c["user_id"])
name = member.display_name if member else f"<@{c['user_id']}>"
tva_text = f" | TVA: {c['tva_rate']}%" if c["account_type"] == "entreprise" else ""
embed.add_field(
name=f"{name} ({c['account_type']})",
value=(
f"**RIB :** `{c['rib']}`\n"
f"**Solde :** `{c['solde']:.2f}€`{tva_text}"
),
inline=False,
)
embed.set_footer(text=f"{len(comptes)} compte(s)")
await interaction.response.send_message(embed=embed, ephemeral=True)
@banque_group.command(name="info", description="Informations sur votre banque")
async def info_banque(self, interaction: discord.Interaction):
bank = await self._get_user_bank(interaction)
if not bank:
await interaction.response.send_message(
"❌ Vous n'avez pas de rôle de banquier sur ce serveur.", ephemeral=True
)
return
role = interaction.guild.get_role(bank["role_id"])
comptes = await bank_manager.get_comptes_banque(interaction.guild.id, bank["id"])
nb_particuliers = sum(1 for c in comptes if c["account_type"] == "particulier")
nb_entreprises = sum(1 for c in comptes if c["account_type"] == "entreprise")
embed = discord.Embed(
title=f"🏦 {bank['name']}",
color=discord.Color.blue(),
)
embed.add_field(name="Rôle", value=role.mention if role else "Inconnu", inline=True)
embed.add_field(name="Code établissement", value=f"`{bank['establishment_code']}`", inline=True)
embed.add_field(name="Solde propre (réserve)", value=f"`{bank['vault_balance']:.2f}€`", inline=True)
embed.add_field(name="Encours clients", value=f"`{bank['clients_total_balance']:.2f}€`", inline=True)
embed.add_field(name="Comptes particuliers", value=str(nb_particuliers), inline=True)
embed.add_field(name="Comptes entreprises", value=str(nb_entreprises), inline=True)
await interaction.response.send_message(embed=embed, ephemeral=True)
@banque_group.command(name="depot", description="Déposer de l'argent sur un compte")
@app_commands.describe(rib="RIB du compte", montant="Montant à déposer")
async def depot(self, interaction: discord.Interaction, rib: str, montant: float):
bank = await self._get_user_bank(interaction)
if not bank:
await interaction.response.send_message(
"❌ Vous n'avez pas de rôle de banquier sur ce serveur.", ephemeral=True
)
return
compte = await bank_manager.get_compte_by_rib(interaction.guild.id, rib)
if not compte:
await interaction.response.send_message("❌ Compte introuvable.", ephemeral=True)
return
if compte["bank_id"] != bank["id"]:
await interaction.response.send_message("❌ Ce RIB n'appartient pas à votre banque.", ephemeral=True)
return
try:
result = await bank_manager.depot_banquier(interaction.guild.id, rib, montant, interaction.user.id)
await interaction.response.send_message(
f"✅ Dépôt de **{montant:.2f}€** sur `{rib}`. Nouveau solde : **{result['nouveau_solde']:.2f}€**",
ephemeral=True,
)
except ValueError as e:
await interaction.response.send_message(f"❌ {e}", ephemeral=True)
@banque_group.command(name="retrait", description="Retirer de l'argent d'un compte")
@app_commands.describe(rib="RIB du compte", montant="Montant à retirer")
async def retrait(self, interaction: discord.Interaction, rib: str, montant: float):
bank = await self._get_user_bank(interaction)
if not bank:
await interaction.response.send_message(
"❌ Vous n'avez pas de rôle de banquier sur ce serveur.", ephemeral=True
)
return
compte = await bank_manager.get_compte_by_rib(interaction.guild.id, rib)
if not compte:
await interaction.response.send_message("❌ Compte introuvable.", ephemeral=True)
return
if compte["bank_id"] != bank["id"]:
await interaction.response.send_message("❌ Ce RIB n'appartient pas à votre banque.", ephemeral=True)
return
try:
result = await bank_manager.retrait_banquier(interaction.guild.id, rib, montant, interaction.user.id)
await interaction.response.send_message(
f"✅ Retrait de **{montant:.2f}€** sur `{rib}`. Nouveau solde : **{result['nouveau_solde']:.2f}€**",
ephemeral=True,
)
except ValueError as e:
await interaction.response.send_message(f"❌ {e}", ephemeral=True)
async def setup(bot):
await bot.add_cog(Banque(bot))

View file

@ -1,93 +1,62 @@
import discord
from discord import app_commands
from discord.ext import commands
from utils.banque_manager import BanqueManager
banque_manager = BanqueManager()
from utils.bank_manager import BankManager
bank_manager = BankManager()
class Compte(commands.Cog):
def __init__(self, bot):
self.bot = bot
@app_commands.command(
name="compte",
description="Afficher vos comptes bancaires et vos 3 dernières transactions"
)
@app_commands.describe(
membre="Afficher le compte d'un autre membre (réservé au gouvernement)"
)
async def compte(self, interaction: discord.Interaction, membre: discord.Member = None):
"""Affiche les soldes et dernières transactions de l'utilisateur ou d'un autre membre (si gouvernement)"""
@app_commands.command(name="compte", description="Afficher vos comptes bancaires et vos dernières transactions")
async def compte(self, interaction: discord.Interaction):
comptes = await bank_manager.get_comptes_user(interaction.guild.id, interaction.user.id)
banque_manager.load_data()
# Par défaut, on cible l'utilisateur qui exécute la commande
cible = interaction.user
user_id = str(cible.id)
# Si un autre membre est précisé, on vérifie le rôle
if membre and membre != interaction.user:
role_gouv = discord.utils.get(interaction.guild.roles, name="🌍│Gouvernement")
if role_gouv not in interaction.user.roles:
await interaction.response.send_message(
"❌ Vous devez avoir le rôle **gouvernement** pour consulter le compte d'un autre membre.",
ephemeral=True
)
return
cible = membre
user_id = str(membre.id)
comptes = banque_manager.comptes
if not comptes:
await interaction.response.send_message(
"❌ Vous n'avez aucun compte bancaire. Utilisez `/mes-ribs` pour voir vos RIBs.",
ephemeral=True,
)
return
embed = discord.Embed(
title=f"💳 Comptes bancaires de {cible.display_name}",
color=discord.Color.blue()
title=f"💳 Comptes de {interaction.user.display_name}",
color=discord.Color.blue(),
)
banques_trouvees = False
for c in comptes:
transactions = await bank_manager.get_transactions(interaction.guild.id, c["rib"], limit=5)
tva_text = f" | TVA: {c['tva_rate']}%" if c["account_type"] == "entreprise" else ""
for banque, data in comptes.items():
if not isinstance(data, dict) or user_id not in data:
continue # Ce n'est pas une banque valide pour cet utilisateur
compte = data[user_id]
rib = compte.get("rib", "Non défini")
solde = compte.get("solde", 0)
transactions = compte.get("transactions", [])
# Récupérer les 3 dernières transactions avec date
last_transactions = transactions[-3:] if transactions else []
tx_str = ""
for tx in last_transactions:
date = tx.get("date", "Date inconnue")
tx_type = tx.get("type", "Inconnu")
montant = tx.get("montant", 0)
source = tx.get("emetteur", tx.get("source", "Inconnu"))
dest = tx.get("destinataire", "Inconnu")
if tx_type.lower() == "virement" or tx_type.lower().startswith("virement"):
tx_str += f"- 🕒 {date} : **{tx_type}** de **{montant}€** à <@{dest}>\n"
elif tx_type.lower() == "virement reçu":
tx_str += f"- 🕒 {date} : **{tx_type}** de **{montant}€** de <@{source}>\n"
tx_lines = []
for tx in transactions:
is_outgoing = tx["emetteur_rib"] == c["rib"]
direction = "→" if is_outgoing else "←"
other_rib = tx["destinataire_rib"] if is_outgoing else tx["emetteur_rib"]
signe = "-" if is_outgoing else "+"
tx_type = tx["type"]
if tx_type == "tva_prelevee":
tx_lines.append(f"- {direction} **TVA** : `{signe}{tx['montant']:.2f}€`")
else:
tx_str += f"- 🕒 {date} : **{tx_type}** de **{montant}€**\n"
tx_lines.append(f"- {direction} **{tx_type}** : `{signe}{tx['montant']:.2f}€` vers `{other_rib or '?'}`")
if not tx_str:
tx_str = "*Aucune transaction.*"
tx_text = "\n".join(tx_lines) if tx_lines else "*Aucune transaction récente.*"
embed.add_field(
name=f"🏦 {banque}",
value=f"💳 **RIB** : `{rib}`\n💰 **Solde** : `{solde}€`\n📜 **Transactions récentes :**\n{tx_str}",
inline=False
name=f"🏦 {c['bank_name']} ({c['account_type']}){tva_text}",
value=(
f"**RIB :** `{c['rib']}`\n"
f"**Solde :** `{c['solde']:.2f}€`\n\n"
f"**Transactions récentes :**\n{tx_text}"
),
inline=False,
)
banques_trouvees = True
if not banques_trouvees:
embed.description = "❌ Aucun compte bancaire trouvé dans les banques enregistrées pour cet utilisateur."
await interaction.response.send_message(embed=embed, ephemeral=True)
async def setup(bot):
await bot.add_cog(Compte(bot))

View file

@ -1,101 +0,0 @@
import discord
from discord import app_commands
from discord.ext import commands
import json
import math
from utils.guild_config import has_role
class CompteBanqueNationale(commands.Cog):
def __init__(self, bot):
self.bot = bot
def get_banque_nationale_data(self):
try:
with open("comptes_entreprises.json", "r+", encoding="utf-8") as f:
data = json.load(f)
# Crée la section si elle n'existe pas
if "banque_nationale" not in data:
data["banque_nationale"] = {
"BANQUE": {
"rib": "11111 22222 33333333333 44",
"solde": 0.0,
"transactions": [{
"date": "Création automatique",
"type": "Création de compte",
"source": "Système",
"montant": 0.0
}]
}
}
f.seek(0)
json.dump(data, f, indent=4, ensure_ascii=False)
f.truncate()
banque_data = data["banque_nationale"].get("BANQUE", {})
return banque_data.get("solde", 0.0), banque_data.get("transactions", [])
except Exception as e:
print(f"Erreur lecture ou création banque_nationale : {e}")
return 0.0, []
@app_commands.command(name="voir_banque_nationale", description="Voir solde et transactions du compte banque nationale")
async def voir_banque_nationale(self, interaction: discord.Interaction):
if not has_role(interaction.user, "banque_nationale"):
await interaction.response.send_message("❌ Vous n'avez pas la permission d'accéder à ce compte.", ephemeral=True)
return
solde, transactions = self.get_banque_nationale_data()
if not transactions:
await interaction.response.send_message("📄 Aucune transaction trouvée sur le compte banque nationale.", ephemeral=True)
return
# Pagination
pages = []
per_page = 5
total_pages = math.ceil(len(transactions) / per_page)
for i in range(total_pages):
start = i * per_page
end = start + per_page
chunk = transactions[start:end]
embed = discord.Embed(
title="🏦 Banque Nationale - Historique",
description=f"Page {i+1}/{total_pages}",
color=discord.Color.blue()
)
embed.add_field(name="💰 Solde", value=f"{solde:.2f}€", inline=False)
for tx in chunk:
description = (
f"**Date**: {tx.get('date', 'N/A')}\n"
f"**Type**: {tx.get('type', 'N/A')}\n"
f"**Montant**: {tx.get('montant', 0)}€\n"
f"**Source**: {tx.get('source', 'N/A')}"
)
embed.add_field(name="📄 Transaction", value=description, inline=False)
pages.append(embed)
class Pagination(discord.ui.View):
def __init__(self):
super().__init__(timeout=None)
self.current = 0
@discord.ui.button(label="⬅️", style=discord.ButtonStyle.grey)
async def previous(self, interaction_btn: discord.Interaction, button: discord.ui.Button):
if self.current > 0:
self.current -= 1
await interaction_btn.response.edit_message(embed=pages[self.current], view=self)
@discord.ui.button(label="➡️", style=discord.ButtonStyle.grey)
async def next(self, interaction_btn: discord.Interaction, button: discord.ui.Button):
if self.current < len(pages) - 1:
self.current += 1
await interaction_btn.response.edit_message(embed=pages[self.current], view=self)
await interaction.response.send_message(embed=pages[0], view=Pagination(), ephemeral=True)
async def setup(bot):
await bot.add_cog(CompteBanqueNationale(bot))

View file

@ -1,91 +0,0 @@
import discord
from discord import app_commands
from discord.ext import commands
import json
import math
from utils.guild_config import has_role
class CompteFBM(commands.Cog):
def __init__(self, bot):
self.bot = bot
def get_all_transactions(self):
try:
with open("comptes_entreprises.json", "r", encoding="utf-8") as f:
data = json.load(f)
fbm_data = data.setdefault("fbm", {}).setdefault("FBM", {
"solde": 0.0,
"transactions": []
})
return fbm_data["solde"], fbm_data["transactions"]
except Exception as e:
print(f"Erreur lecture comptes_entreprises.json : {e}")
return 0.0, []
@app_commands.command(name="compte_fbm", description="Affiche le solde et l'historique du compte FBM (réservé au personnel FBM).")
async def compte_fbm(self, interaction: discord.Interaction):
if not has_role(interaction.user, "fbm"):
await interaction.response.send_message("❌ Vous n'avez pas la permission d'accéder à ce compte.", ephemeral=True)
return
solde, transactions = self.get_all_transactions()
if not transactions:
embed = discord.Embed(
title="📄 Compte FBM",
description="Aucune transaction enregistrée.",
color=discord.Color.orange()
)
embed.add_field(name="💰 Solde actuel", value=f"{solde:.2f}€", inline=False)
await interaction.response.send_message(embed=embed, ephemeral=True)
return
# Pagination
pages = []
per_page = 5
total_pages = math.ceil(len(transactions) / per_page)
for i in range(total_pages):
start = i * per_page
end = start + per_page
chunk = transactions[start:end]
embed = discord.Embed(
title="📄 Historique FBM",
description=f"Page {i+1}/{total_pages}",
color=discord.Color.orange()
)
embed.add_field(name="💰 Solde actuel", value=f"{solde:.2f}€", inline=False)
for tx in chunk:
desc = (
f"**Date**: {tx.get('date', 'N/A')}\n"
f"**Type**: {tx.get('type', 'N/A')}\n"
f"**Montant**: {tx.get('montant', 0)}€\n"
f"**Source**: {tx.get('source', 'N/A')}"
)
embed.add_field(name="🔸 Transaction", value=desc, inline=False)
pages.append(embed)
class Pagination(discord.ui.View):
def __init__(self):
super().__init__(timeout=None)
self.current = 0
@discord.ui.button(label="⬅️", style=discord.ButtonStyle.grey)
async def previous(self, interaction_btn: discord.Interaction, button: discord.ui.Button):
if self.current > 0:
self.current -= 1
await interaction_btn.response.edit_message(embed=pages[self.current], view=self)
@discord.ui.button(label="➡️", style=discord.ButtonStyle.grey)
async def next(self, interaction_btn: discord.Interaction, button: discord.ui.Button):
if self.current < len(pages) - 1:
self.current += 1
await interaction_btn.response.edit_message(embed=pages[self.current], view=self)
await interaction.response.send_message(embed=pages[0], view=Pagination(), ephemeral=True)
async def setup(bot):
await bot.add_cog(CompteFBM(bot))

View file

@ -1,84 +0,0 @@
import discord
from discord import app_commands
from discord.ext import commands
import json
import math
from utils.guild_config import has_role
class CompteGouvernement(commands.Cog):
def __init__(self, bot):
self.bot = bot
def get_gouv_data(self):
try:
with open("comptes_entreprises.json", "r", encoding="utf-8") as f:
data = json.load(f)
gouv_data = data.get("Gouvernement", {}).get("GOUV", {})
return gouv_data.get("solde", 0.0), gouv_data.get("transactions", [])
except Exception as e:
print(f"Erreur lecture comptes_entreprises.json : {e}")
return 0.0, []
@app_commands.command(name="compte_gouvernement", description="Affiche le solde et les transactions du compte Gouvernement.")
async def compte_gouvernement(self, interaction: discord.Interaction):
if not has_role(interaction.user, "gouvernement"):
await interaction.response.send_message("❌ Vous n'avez pas la permission d'accéder à ce compte.", ephemeral=True)
return
solde, transactions = self.get_gouv_data()
if not transactions:
await interaction.response.send_message("📄 Aucune transaction trouvée pour le gouvernement.", ephemeral=True)
return
# Pagination setup
pages = []
per_page = 5
total_pages = math.ceil(len(transactions) / per_page)
for i in range(total_pages):
start = i * per_page
end = start + per_page
chunk = transactions[start:end]
embed = discord.Embed(
title="🏛️ Compte Gouvernement",
description=f"Page {i+1}/{total_pages}",
color=discord.Color.dark_gold()
)
embed.add_field(name="💰 Solde", value=f"{solde:.2f}€", inline=False)
for tx in chunk:
desc = (
f"**Date**: {tx.get('date', 'N/A')}\n"
f"**Type**: {tx.get('type', 'N/A')}\n"
f"**Montant**: {tx.get('montant', 0)}€\n"
f"**Source**: {tx.get('source', 'N/A')}"
)
embed.add_field(name="📄 Transaction", value=desc, inline=False)
pages.append(embed)
# Vue de pagination
class Pagination(discord.ui.View):
def __init__(self):
super().__init__(timeout=None)
self.current = 0
@discord.ui.button(label="⬅️", style=discord.ButtonStyle.grey)
async def previous(self, interaction_btn: discord.Interaction, button: discord.ui.Button):
if self.current > 0:
self.current -= 1
await interaction_btn.response.edit_message(embed=pages[self.current], view=self)
@discord.ui.button(label="➡️", style=discord.ButtonStyle.grey)
async def next(self, interaction_btn: discord.Interaction, button: discord.ui.Button):
if self.current < len(pages) - 1:
self.current += 1
await interaction_btn.response.edit_message(embed=pages[self.current], view=self)
await interaction.response.send_message(embed=pages[0], view=Pagination(), ephemeral=True)
async def setup(bot):
await bot.add_cog(CompteGouvernement(bot))

View file

@ -1,95 +0,0 @@
import discord
from discord import app_commands
from discord.ext import commands
import json
import math
from utils.guild_config import has_role
class CompteUrssaf(commands.Cog):
def __init__(self, bot):
self.bot = bot
def get_all_transactions(self):
try:
with open("comptes_entreprises.json", "r", encoding="utf-8") as f:
data = json.load(f)
except Exception as e:
print(f"Erreur lecture comptes_entreprises.json : {e}")
return 0.0, []
# Si URSAFF n'existe pas, on le crée
if "ursaff" not in data:
data["ursaff"] = {
"URSSAFF": {
"rib": "00000 00000 00000000000 01",
"solde": 0.0,
"transactions": []
}
}
with open("comptes_entreprises.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=4)
ursaff_data = data.get("ursaff", {}).get("URSAFF", {})
return ursaff_data.get("solde", 0.0), ursaff_data.get("transactions", [])
@app_commands.command(name="compte_ursaff", description="Affiche le solde et l'historique complet du compte URSAFF (réservé aux membres URSAFF).")
async def compte_ursaff(self, interaction: discord.Interaction):
# Vérifie que l'utilisateur a le rôle URSAFF
if not has_role(interaction.user, "ursaff"):
await interaction.response.send_message("❌ Vous n'avez pas la permission d'accéder à ce compte.", ephemeral=True)
return
solde, transactions = self.get_all_transactions()
# Pagination setup
pages = []
per_page = 5
total_pages = max(1, math.ceil(len(transactions) / per_page))
for i in range(total_pages):
start = i * per_page
end = start + per_page
chunk = transactions[start:end]
embed = discord.Embed(
title="📄 Historique URSSAF",
description=f"Page {i+1}/{total_pages}",
color=discord.Color.dark_purple()
)
embed.add_field(name="💼 Solde actuel", value=f"{solde:.2f}€", inline=False)
if chunk:
for tx in chunk:
description = (
f"**Date**: {tx.get('date', 'N/A')}\n"
f"**Type**: {tx.get('type', 'N/A')}\n"
f"**Montant**: {tx.get('montant', 0)}€\n"
f"**Source**: {tx.get('source', 'N/A')}"
)
embed.add_field(name="🔹 Transaction", value=description, inline=False)
else:
embed.add_field(name="📄 Transactions", value="Aucune transaction récente.", inline=False)
pages.append(embed)
class Pagination(discord.ui.View):
def __init__(self):
super().__init__(timeout=None)
self.current = 0
@discord.ui.button(label="⬅️", style=discord.ButtonStyle.grey)
async def previous(self, interaction_btn: discord.Interaction, button: discord.ui.Button):
if self.current > 0:
self.current -= 1
await interaction_btn.response.edit_message(embed=pages[self.current], view=self)
@discord.ui.button(label="➡️", style=discord.ButtonStyle.grey)
async def next(self, interaction_btn: discord.Interaction, button: discord.ui.Button):
if self.current < len(pages) - 1:
self.current += 1
await interaction_btn.response.edit_message(embed=pages[self.current], view=self)
await interaction.response.send_message(embed=pages[0], view=Pagination(), ephemeral=True)
async def setup(bot):
await bot.add_cog(CompteUrssaf(bot))

View file

@ -1,73 +0,0 @@
import discord
from discord import app_commands
from discord.ext import commands
import json
class CompteEntreprise(commands.Cog):
def __init__(self, bot):
self.bot = bot
banque_choices = [
app_commands.Choice(name="Victoria's Credit Bank", value="Victoria's Credit Bank"),
app_commands.Choice(name="NGC Bank", value="NGC Bank"),
]
@app_commands.command(name="compte_entreprise", description="Consulte le solde et les transactions d'une entreprise.")
@app_commands.choices(banque=banque_choices)
async def compte_entreprise(
self,
interaction: discord.Interaction,
banque: app_commands.Choice[str],
nom_entreprise: str,
mot_de_passe: str
):
banque_nom = banque.value
try:
with open("comptes_entreprises.json", "r", encoding="utf-8") as f:
comptes = json.load(f)
except Exception:
await interaction.response.send_message("❌ Erreur de lecture des données bancaires.", ephemeral=True)
return
if banque_nom not in comptes or nom_entreprise not in comptes[banque_nom]:
await interaction.response.send_message("❌ Ce compte entreprise n'existe pas.", ephemeral=True)
return
compte = comptes[banque_nom][nom_entreprise]
# 🔐 Vérification du mot de passe avec la bonne clé
mdp_stocke = compte.get("mdp", "").strip()
mdp_fournit = mot_de_passe.strip()
if mdp_stocke != mdp_fournit:
await interaction.response.send_message("❌ Mot de passe incorrect.", ephemeral=True)
return
solde = compte.get("solde", 0)
transactions = compte.get("transactions", [])
embed = discord.Embed(
title=f"🏢 Compte Entreprise : {nom_entreprise}",
color=discord.Color.teal()
)
embed.add_field(name="🏦 Banque", value=banque_nom, inline=True)
embed.add_field(name="💰 Solde", value=f"{solde:.2f}€", inline=False)
if transactions:
last_transactions = transactions[-3:]
for tx in reversed(last_transactions):
desc = (
f"**Date**: {tx.get('date', 'N/A')}\n"
f"**Type**: {tx.get('type', 'N/A')}\n"
f"**Montant**: {tx.get('montant', 0)}€\n"
f"**Source**: {tx.get('source', 'N/A')}"
)
embed.add_field(name="📄 Transaction", value=desc, inline=False)
else:
embed.add_field(name="📄 Transactions", value="Aucune transaction récente.", inline=False)
await interaction.response.send_message(embed=embed, ephemeral=True)
async def setup(bot):
await bot.add_cog(CompteEntreprise(bot))

194
commandes/gouv.py Normal file
View file

@ -0,0 +1,194 @@
import discord
from discord import app_commands
from discord.ext import commands
from utils.guild_config import has_role
from utils.bank_manager import BankManager
bank_manager = BankManager()
class Gouv(commands.Cog):
def __init__(self, bot):
self.bot = bot
gouv_group = app_commands.Group(name="gouv", description="Commandes gouvernementales")
def _check_gouv(self, interaction: discord.Interaction) -> bool:
return has_role(interaction.user, "gouvernement")
@gouv_group.command(name="creer-banque", description="Créer une nouvelle banque commerciale")
@app_commands.describe(
nom="Nom de la banque (ex: NGC Bank)",
role="Le rôle Discord des banquiers de cette banque"
)
async def creer_banque(self, interaction: discord.Interaction, nom: str, role: discord.Role):
if not self._check_gouv(interaction):
await interaction.response.send_message("❌ Réservé au rôle **Gouvernement**.", ephemeral=True)
return
try:
result = await bank_manager.creer_banque(interaction.guild.id, nom, role.id)
embed = discord.Embed(
title="🏦 Banque créée",
description=(
f"**{nom}** a été créée avec succès.\n\n"
f"**Rôle banquiers :** {role.mention}\n"
f"**Code établissement :** `{result['establishment_code']}`\n"
f"**ID banque :** `{result['id']}`"
),
color=discord.Color.green(),
)
await interaction.response.send_message(embed=embed, ephemeral=True)
except Exception as e:
await interaction.response.send_message(f"❌ Erreur : {e}", ephemeral=True)
@gouv_group.command(name="creer-institution", description="Créer une institution (Fisc, URSAFF, etc.)")
@app_commands.describe(
nom="Nom de l'institution",
role="Le rôle Discord qui gère cette institution",
audit="Peut-elle consulter les comptes de toutes les banques ?"
)
async def creer_institution(
self,
interaction: discord.Interaction,
nom: str,
role: discord.Role,
audit: bool = False,
):
if not self._check_gouv(interaction):
await interaction.response.send_message("❌ Réservé au rôle **Gouvernement**.", ephemeral=True)
return
try:
result = await bank_manager.creer_institution(
interaction.guild.id, nom, role.id, audit
)
embed = discord.Embed(
title="🏛️ Institution créée",
description=(
f"**{nom}** a été créée.\n\n"
f"**Rôle :** {role.mention}\n"
f"**Droit d'audit :** {'✅ Oui' if audit else '❌ Non'}\n"
f"**ID :** `{result['id']}`"
),
color=discord.Color.blue(),
)
await interaction.response.send_message(embed=embed, ephemeral=True)
except Exception as e:
await interaction.response.send_message(f"❌ Erreur : {e}", ephemeral=True)
@gouv_group.command(name="config-fisc", description="Définir quelle institution reçoit la TVA")
@app_commands.describe(
institution="L'institution qui servira de Fisc"
)
async def config_fisc(self, interaction: discord.Interaction, institution: str):
if not self._check_gouv(interaction):
await interaction.response.send_message("❌ Réservé au rôle **Gouvernement**.", ephemeral=True)
return
institutions = await bank_manager.lister_institutions(interaction.guild.id)
target = None
for inst in institutions:
if inst["name"].lower() == institution.lower():
target = inst
break
if not target:
await interaction.response.send_message(
f"❌ Institution **{institution}** introuvable. Institutions disponibles : {', '.join(i['name'] for i in institutions) or 'aucune'}",
ephemeral=True,
)
return
ok = await bank_manager.configurer_fisc(interaction.guild.id, target["id"])
if ok:
embed = discord.Embed(
title="🏛️ Fisc configuré",
description=f"**{target['name']}** reçoit désormais la TVA de tous les virements Particulier → Entreprise.",
color=discord.Color.green(),
)
await interaction.response.send_message(embed=embed, ephemeral=True)
else:
await interaction.response.send_message("❌ Erreur lors de la configuration.", ephemeral=True)
@gouv_group.command(name="lister-banques", description="Lister toutes les banques du serveur")
async def lister_banques(self, interaction: discord.Interaction):
if not self._check_gouv(interaction):
await interaction.response.send_message("❌ Réservé au rôle **Gouvernement**.", ephemeral=True)
return
banques = await bank_manager.lister_banques(interaction.guild.id)
if not banques:
await interaction.response.send_message("Aucune banque configurée.", ephemeral=True)
return
embed = discord.Embed(title="🏦 Banques du serveur", color=discord.Color.blue())
for b in banques:
role = interaction.guild.get_role(b["role_id"])
role_text = role.mention if role else f"`{b['role_id']}` introuvable"
embed.add_field(
name=b["name"],
value=(
f"**Rôle :** {role_text}\n"
f"**Code établissement :** `{b['establishment_code']}`\n"
f"**Réserve :** `{b['vault_balance']:.2f}€`\n"
f"**Encours clients :** `{b['clients_total_balance']:.2f}€`"
),
inline=False,
)
await interaction.response.send_message(embed=embed, ephemeral=True)
@gouv_group.command(name="lister-institutions", description="Lister toutes les institutions du serveur")
async def lister_institutions(self, interaction: discord.Interaction):
if not self._check_gouv(interaction):
await interaction.response.send_message("❌ Réservé au rôle **Gouvernement**.", ephemeral=True)
return
institutions = await bank_manager.lister_institutions(interaction.guild.id)
if not institutions:
await interaction.response.send_message("Aucune institution configurée.", ephemeral=True)
return
fisc_config = await bank_manager.get_fisc_config(interaction.guild.id)
fisc_id = fisc_config["institution_id"] if fisc_config else None
embed = discord.Embed(title="🏛️ Institutions du serveur", color=discord.Color.blue())
for inst in institutions:
role = interaction.guild.get_role(inst["role_id"]) if inst["role_id"] else None
role_text = role.mention if role else "Non assigné"
is_fisc = " 💰 **(Fisc)**" if inst["id"] == fisc_id else ""
embed.add_field(
name=f"{inst['name']}{is_fisc}",
value=(
f"**Rôle :** {role_text}\n"
f"**Audit :** {'✅ Toutes les banques' if inst['can_audit_all'] else '❌ Non'}\n"
f"**ID :** `{inst['id']}`"
),
inline=False,
)
await interaction.response.send_message(embed=embed, ephemeral=True)
@gouv_group.command(name="supprimer-banque", description="Supprimer une banque")
@app_commands.describe(nom="Nom de la banque à supprimer")
async def supprimer_banque(self, interaction: discord.Interaction, nom: str):
if not self._check_gouv(interaction):
await interaction.response.send_message("❌ Réservé au rôle **Gouvernement**.", ephemeral=True)
return
banque = await bank_manager.get_banque_by_name(interaction.guild.id, nom)
if not banque:
await interaction.response.send_message(f"❌ Banque **{nom}** introuvable.", ephemeral=True)
return
ok = await bank_manager.supprimer_banque(interaction.guild.id, banque["id"])
if ok:
await interaction.response.send_message(
f"✅ Banque **{nom}** supprimée avec tous ses comptes.", ephemeral=True
)
else:
await interaction.response.send_message("❌ Erreur lors de la suppression.", ephemeral=True)
async def setup(bot):
await bot.add_cog(Gouv(bot))

44
commandes/mes_ribs.py Normal file
View file

@ -0,0 +1,44 @@
import discord
from discord import app_commands
from discord.ext import commands
from utils.bank_manager import BankManager
bank_manager = BankManager()
class MesRibs(commands.Cog):
def __init__(self, bot):
self.bot = bot
@app_commands.command(name="mes-ribs", description="Afficher tous vos RIBs")
async def mes_ribs(self, interaction: discord.Interaction):
comptes = await bank_manager.get_comptes_user(interaction.guild.id, interaction.user.id)
if not comptes:
await interaction.response.send_message(
"❌ Vous n'avez aucun compte bancaire.", ephemeral=True
)
return
embed = discord.Embed(
title=f"💳 RIBs de {interaction.user.display_name}",
color=discord.Color.blue(),
)
for c in comptes:
tva_text = f" | TVA: {c['tva_rate']}%" if c["account_type"] == "entreprise" else ""
embed.add_field(
name=f"{c['bank_name']} ({c['account_type']})",
value=(
f"**RIB :** `{c['rib']}`\n"
f"**Solde :** `{c['solde']:.2f}€`{tva_text}"
),
inline=False,
)
await interaction.response.send_message(embed=embed, ephemeral=True)
async def setup(bot):
await bot.add_cog(MesRibs(bot))

View file

@ -1,74 +0,0 @@
import discord
from discord import app_commands
from discord.ext import commands
from utils.banque_manager import BanqueManager
import random
from utils.guild_config import has_role
# Liste des banques disponibles (id interne : nom affiché)
BANQUES = {
"Victoria's Credit Bank": "Victoria's Credit Bank",
"NGC Bank": "Nexus Global Corporation Bank"
}
banque_manager = BanqueManager()
class OuvrirCompte(commands.Cog):
def __init__(self, bot):
self.bot = bot
@app_commands.command(name="ouvrir_compte", description="Ouvre un compte bancaire pour un utilisateur (banquier uniquement).")
@app_commands.choices(
banque=[app_commands.Choice(name=nom, value=id_banque) for id_banque, nom in BANQUES.items()]
)
async def ouvrir_compte(self, interaction: discord.Interaction, utilisateur: discord.Member, banque: app_commands.Choice[str]):
banque_id = banque.value
banque_nom = BANQUES[banque_id]
# Vérification du rôle de banquier
if not has_role(interaction.user, "banquier"):
await interaction.response.send_message("❌ Vous n'avez pas la permission d'ouvrir un compte.", ephemeral=True)
return
user_id = str(utilisateur.id)
banque_manager.load_data()
# Conversion automatique si l'ancien format est utilisé
if all(isinstance(v, dict) and 'rib' in v for v in banque_manager.comptes.values()):
banque_manager.comptes = {"vicynationale": banque_manager.comptes}
# Vérification si la banque existe dans les données
if banque_id not in banque_manager.comptes:
banque_manager.comptes[banque_id] = {}
# Vérification si l'utilisateur a déjà un compte dans cette banque
if user_id in banque_manager.comptes[banque_id]:
await interaction.response.send_message(
f"❌ {utilisateur.mention} possède déjà un compte à la {banque_nom} !",
ephemeral=True
)
return
# Génération du RIB aléatoire
rib = f"{random.randint(10000, 99999)} {random.randint(10000, 99999)} {random.randint(10000000000, 99999999999)} {random.randint(10, 99)}"
# Création du compte
banque_manager.comptes[banque_id][user_id] = {
"rib": rib,
"solde": 0.0,
"transactions": []
}
banque_manager.save_data()
# Envoi du RIB en MP à l'utilisateur cible
try:
await utilisateur.send(f"🏦 Un compte a été créé pour vous à la **{banque_nom}**.\nVoici votre RIB : `{rib}`")
except discord.Forbidden:
await interaction.response.send_message("❌ Impossible d'envoyer le RIB en message privé (l'utilisateur a les MP fermés).", ephemeral=True)
return
await interaction.response.send_message(f"✅ Compte créé avec succès pour {utilisateur.mention} à la **{banque_nom}**.", ephemeral=True)
async def setup(bot):
await bot.add_cog(OuvrirCompte(bot))

View file

@ -1,93 +0,0 @@
import json
import os
import random
import string
import discord
from discord import app_commands
from discord.ext import commands
from utils.guild_config import has_role
COMPTES_ENTREPRISES_PATH = "comptes_entreprises.json"
def generer_rib():
return " ".join(["".join(random.choices(string.digits, k=5)) for _ in range(4)])
def generer_mdp():
return "".join(random.choices(string.ascii_letters + string.digits, k=8))
class OuvrirCompteEntreprise(commands.Cog):
def __init__(self, bot):
self.bot = bot
banque_choix = [
app_commands.Choice(name="Victoria's Credit Bank", value="Victoria's Credit Bank"),
app_commands.Choice(name="NGC Bank", value="NGC Bank"),
]
tva_choix = [
app_commands.Choice(name="2%", value=2),
app_commands.Choice(name="5%", value=5),
app_commands.Choice(name="10%", value=10),
app_commands.Choice(name="20%", value=20),
]
@app_commands.command(name="ouvrir_compte_entreprise", description="Ouvre un compte bancaire pour une entreprise")
@app_commands.choices(banque=banque_choix, tva=tva_choix)
async def ouvrir_compte_entreprise(self, interaction: discord.Interaction, entreprise: str, banque: app_commands.Choice[str], tva: app_commands.Choice[int]):
# ✅ Vérifie que l'utilisateur est banquier
if not has_role(interaction.user, "banquier"):
await interaction.response.send_message("❌ Vous n'avez pas la permission d'exécuter cette commande.", ephemeral=True)
return
banque_name = banque.value
entreprise = entreprise.strip()
# ✅ Chargement sécurisé du fichier
if os.path.exists(COMPTES_ENTREPRISES_PATH):
try:
with open(COMPTES_ENTREPRISES_PATH, "r", encoding="utf-8") as f:
comptes = json.load(f)
except json.JSONDecodeError:
comptes = {}
else:
comptes = {}
if banque_name not in comptes:
comptes[banque_name] = {}
if entreprise in comptes[banque_name]:
await interaction.response.send_message(f"❌ Un compte existe déjà pour l'entreprise **{entreprise}** dans la banque **{banque_name}**.", ephemeral=True)
return
rib = generer_rib()
mdp = generer_mdp()
comptes[banque_name][entreprise] = {
"rib": rib,
"solde": 0,
"mdp": mdp,
"tva": tva.value,
"transactions": []
}
with open(COMPTES_ENTREPRISES_PATH, "w", encoding="utf-8") as f:
json.dump(comptes, f, ensure_ascii=False, indent=4)
# ✅ MP à l'utilisateur avec le RIB et le mot de passe
try:
await interaction.user.send(
f"🏦 Compte de l'entreprise **{entreprise}** ouvert avec succès dans la banque **{banque_name}** !\n"
f"💳 RIB : `{rib}`\n"
f"🔐 Mot de passe : `{mdp}`\n"
f"💼 Taux de TVA : `{tva.value}%`\n\n"
f"Conservez bien ces informations."
)
except discord.Forbidden:
await interaction.response.send_message("⚠️ Impossible de vous envoyer un message privé avec les informations du compte.", ephemeral=True)
return
await interaction.response.send_message(f"✅ Le compte de l'entreprise **{entreprise}** a été créé avec succès.", ephemeral=True)
async def setup(bot):
await bot.add_cog(OuvrirCompteEntreprise(bot))

2389
commandes/panel.py Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,74 +0,0 @@
import discord
from discord import app_commands
from discord.ext import commands
from utils.banque_manager import BanqueManager
from utils.guild_config import has_role
banque_manager = BanqueManager()
class Pret(commands.Cog):
def __init__(self, bot):
self.bot = bot
@app_commands.command(name="calculer_pret", description="Accorde un prêt bancaire à un utilisateur (Réservé aux banquiers).")
async def calculer_pret(
self,
interaction: discord.Interaction,
utilisateur: discord.Member,
banque: str,
montant: float,
duree_annees: int
):
"""Les banquiers peuvent accorder un prêt à un utilisateur si son solde le permet."""
# Vérification de si le joueur executant la commande est un banquier
if not has_role(interaction.user, "banquier"):
await interaction.response.send_message(
"❌ Vous n'avez pas la permission d'accorder un prêt.",
ephemeral=True
)
return
user_id = str(utilisateur.id)
success, result = banque_manager.ajouter_pret(user_id, banque, montant, duree_annees)
if not success:
await interaction.response.send_message(result, ephemeral=True)
return
total_a_rembourser = result
taux_interet = banque_manager.comptes[user_id]['prets'][-1]['taux_interet'] * 100
# Vérifier si l'utilisateur a assez d'argent pour rembourser
solde_utilisateur = banque_manager.comptes[user_id].get("solde", 0)
if solde_utilisateur < total_a_rembourser:
await interaction.response.send_message(
f"❌ {utilisateur.mention} n'a pas assez d'argent pour rembourser ce prêt.\n"
f"💰 **Solde actuel** : {solde_utilisateur}€\n"
f"💳 **Montant à rembourser** : {total_a_rembourser}€",
ephemeral=True
)
return
# Débiter le solde de l'utilisateur
banque_manager.comptes[user_id]["solde"] -= total_a_rembourser
banque_manager.save_data()
# Création de l'embed
embed = discord.Embed(
title="🏦 Prêt bancaire accordé",
description=f"Le prêt a été accordé par {interaction.user.mention} pour {utilisateur.mention}.",
color=discord.Color.green()
)
embed.set_thumbnail(url="https://cdn-icons-png.flaticon.com/512/2910/2910827.png") # Icône banque
embed.add_field(name="💰 Montant emprunté", value=f"{montant}€", inline=True)
embed.add_field(name="📅 Durée", value=f"{duree_annees} ans", inline=True)
embed.add_field(name="📈 Taux d'intérêt", value=f"{taux_interet}%", inline=True)
embed.add_field(name="💳 Montant total à rembourser", value=f"{total_a_rembourser}€", inline=False)
embed.add_field(name="💰 Solde après prêt", value=f"{banque_manager.comptes[user_id]['solde']}€", inline=True)
embed.set_footer(text="Prêt enregistré dans le compte bancaire ✅")
await interaction.response.send_message(embed=embed)
async def setup(bot):
await bot.add_cog(Pret(bot))

View file

@ -1,146 +0,0 @@
import discord
from discord import app_commands
from discord.ext import commands
import json
from datetime import datetime
from utils.guild_config import has_role
class RetirerArgent(commands.Cog):
def __init__(self, bot):
self.bot = bot
banque_choices = [
app_commands.Choice(name="Victoria's Credit Bank", value="Victoria's Credit Bank"),
app_commands.Choice(name="NGC Bank", value="NGC Bank"),
]
@app_commands.command(
name="retirer_argent",
description="Retire de l'argent d'un compte via son RIB (utilisateur ou entreprise)."
)
@app_commands.choices(banque=banque_choices)
@app_commands.describe(
rib="Le RIB du compte",
montant="Montant à retirer",
banque="Banque cible (facultatif)"
)
async def retirer_argent(
self,
interaction: discord.Interaction,
rib: str,
montant: float,
banque: app_commands.Choice[str] = None
):
if not has_role(interaction.user, "banquier"):
await interaction.response.send_message("❌ Vous n'avez pas la permission de faire cela.", ephemeral=True)
return
if montant <= 0:
await interaction.response.send_message("❌ Le montant doit être supérieur à zéro.", ephemeral=True)
return
banque_nom = banque.value if banque else None
# Charger les fichiers
try:
with open("comptes_bancaires.json", "r", encoding="utf-8") as f:
comptes_bancaires = json.load(f)
with open("comptes_entreprises.json", "r", encoding="utf-8") as f:
comptes_entreprises = json.load(f)
except Exception:
await interaction.response.send_message("❌ Erreur lors de la lecture des fichiers JSON.", ephemeral=True)
return
compte = None
source = None # "utilisateur" ou "entreprise"
user_id = None
# Recherche dans la banque spécifiée (si précisée)
if banque_nom and banque_nom in comptes_bancaires:
for uid, data in comptes_bancaires[banque_nom].items():
if data.get("rib") == rib:
compte = data
source = "utilisateur"
user_id = uid
break
if not compte and banque_nom and banque_nom in comptes_entreprises:
for entreprise, data in comptes_entreprises[banque_nom].items():
if data.get("rib") == rib:
compte = data
source = "entreprise"
user_id = entreprise
break
# Si banque non précisée ou compte non trouvé, recherche dans toutes les banques
if not compte and not banque_nom:
# Recherche dans toutes les banques utilisateurs
for banque_courante, comptes_banque in comptes_bancaires.items():
for uid, data in comptes_banque.items():
if data.get("rib") == rib:
compte = data
source = "utilisateur"
user_id = uid
banque_nom = banque_courante
break
if compte:
break
if not compte:
# Recherche dans toutes les banques entreprises
for banque_courante, entreprises_banque in comptes_entreprises.items():
for entreprise, data in entreprises_banque.items():
if data.get("rib") == rib:
compte = data
source = "entreprise"
user_id = entreprise
banque_nom = banque_courante
break
if compte:
break
if not compte:
await interaction.response.send_message("❌ Aucun compte trouvé avec ce RIB.", ephemeral=True)
return
if compte["solde"] < montant:
await interaction.response.send_message("❌ Solde insuffisant pour retirer cette somme.", ephemeral=True)
return
# Appliquer le retrait
compte["solde"] -= montant
transaction = {
"date": datetime.now().strftime("%d/%m/%Y %H:%M:%S"),
"type": "Retrait",
"source": "Banque",
"montant": -montant,
"emetteur": interaction.user.id,
"destinataire": user_id
}
compte.setdefault("transactions", []).append(transaction)
# Sauvegarde dans le bon fichier
if source == "utilisateur":
comptes_bancaires[banque_nom][user_id] = compte
with open("comptes_bancaires.json", "w", encoding="utf-8") as f:
json.dump(comptes_bancaires, f, indent=4, ensure_ascii=False)
else:
comptes_entreprises[banque_nom][user_id] = compte
with open("comptes_entreprises.json", "w", encoding="utf-8") as f:
json.dump(comptes_entreprises, f, indent=4, ensure_ascii=False)
# Message de confirmation
embed = discord.Embed(
title="💸 Retrait effectué",
description=f"💼 Banque : **{banque_nom}**\n📌 Type : **{source.capitalize()}**",
color=discord.Color.red()
)
embed.add_field(name="RIB", value=rib, inline=False)
embed.add_field(name="Montant retiré", value=f"{montant:.2f}€", inline=True)
embed.add_field(name="Effectué par", value=interaction.user.mention, inline=True)
embed.set_footer(text="Transaction enregistrée ✅")
await interaction.response.send_message(embed=embed, ephemeral=False)
async def setup(bot):
await bot.add_cog(RetirerArgent(bot))

View file

@ -1,184 +0,0 @@
import discord
from discord import app_commands
from discord.ext import commands
import json
from datetime import datetime
from utils.guild_config import has_role
GOUV_BANQUE = "Gouvernement"
GOUV_COMPTE = "GOUV"
GOUV_RIB = "00000 00000 00000000000 00"
class GouvVirement(commands.Cog):
def __init__(self, bot):
self.bot = bot
# Liste des banques à jour (ajoute ici toutes les banques possibles de ton système)
banque_choices = [
app_commands.Choice(name="Victoria's Credit Bank", value="Victoria's Credit Bank"),
app_commands.Choice(name="NGC Bank", value="NGC Bank"),
]
@app_commands.command(
name="gouv_virer",
description="Le Gouvernement vire de l'argent de son compte vers un autre RIB (entreprise ou particulier)."
)
@app_commands.choices(banque=banque_choices)
@app_commands.describe(
rib="Le RIB destinataire",
montant="Montant à virer",
banque="Banque cible (facultatif)"
)
async def gouv_virer(
self,
interaction: discord.Interaction,
rib: str,
montant: float,
banque: app_commands.Choice[str] = None
):
# Vérification du rôle Gouvernement
if not has_role(interaction.user, "gouvernement"):
await interaction.response.send_message("❌ Seul le Gouvernement peut utiliser cette commande.", ephemeral=True)
return
if montant <= 0:
await interaction.response.send_message("❌ Le montant doit être supérieur à zéro.", ephemeral=True)
return
banque_nom = banque.value if banque else None
# Charger les fichiers
try:
with open("comptes_bancaires.json", "r", encoding="utf-8") as f:
comptes_bancaires = json.load(f)
except Exception:
comptes_bancaires = {}
try:
with open("comptes_entreprises.json", "r", encoding="utf-8") as f:
comptes_entreprises = json.load(f)
except Exception:
await interaction.response.send_message("❌ Erreur lors de la lecture des fichiers JSON.", ephemeral=True)
return
# Récupérer le compte du Gouvernement
try:
gouv_compte = comptes_entreprises[GOUV_BANQUE][GOUV_COMPTE]
except KeyError:
await interaction.response.send_message("❌ Compte Gouvernement introuvable.", ephemeral=True)
return
if gouv_compte["solde"] < montant:
await interaction.response.send_message("❌ Le Gouvernement n'a pas assez de fonds.", ephemeral=True)
return
# Chercher le destinataire
destinataire_compte = None
destinataire_banque = None
destinataire_nom = None
destinataire_type = None
# Si banque précisée, chercher d'abord dans cette banque (entreprises puis particuliers)
if banque_nom:
# Entreprises
if banque_nom in comptes_entreprises:
for nom, data in comptes_entreprises[banque_nom].items():
if data.get("rib") == rib:
destinataire_compte = data
destinataire_banque = banque_nom
destinataire_nom = nom
destinataire_type = "entreprise"
break
# Particuliers
if not destinataire_compte and banque_nom in comptes_bancaires:
for uid, data in comptes_bancaires[banque_nom].items():
if data.get("rib") == rib:
destinataire_compte = data
destinataire_banque = banque_nom
destinataire_nom = uid
destinataire_type = "particulier"
break
# Si banque non précisée, chercher dans toutes les banques
else:
# Entreprises
for banque_courante, entreprises in comptes_entreprises.items():
for nom, data in entreprises.items():
if data.get("rib") == rib:
destinataire_compte = data
destinataire_banque = banque_courante
destinataire_nom = nom
destinataire_type = "entreprise"
break
if destinataire_compte:
break
# Particuliers
if not destinataire_compte:
for banque_courante, comptes in comptes_bancaires.items():
for uid, data in comptes.items():
if data.get("rib") == rib:
destinataire_compte = data
destinataire_banque = banque_courante
destinataire_nom = uid
destinataire_type = "particulier"
break
if destinataire_compte:
break
if not destinataire_compte:
await interaction.response.send_message("❌ Aucun compte trouvé avec ce RIB dans la banque spécifiée." if banque_nom else "❌ Aucun compte trouvé avec ce RIB.", ephemeral=True)
return
# Effectuer le virement
gouv_compte["solde"] -= montant
destinataire_compte["solde"] += montant
now = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
# Transaction côté Gouvernement (sortant)
gouv_compte.setdefault("transactions", []).append({
"date": now,
"type": "Virement",
"source": "Gouvernement",
"montant": -montant,
"emetteur": "Gouvernement",
"destinataire": destinataire_nom
})
# Transaction côté destinataire (entrant)
destinataire_compte.setdefault("transactions", []).append({
"date": now,
"type": "Virement",
"source": "Gouvernement",
"montant": montant,
"emetteur": "Gouvernement",
"destinataire": destinataire_nom
})
# Sauvegarde
comptes_entreprises[GOUV_BANQUE][GOUV_COMPTE] = gouv_compte
if destinataire_type == "entreprise":
comptes_entreprises[destinataire_banque][destinataire_nom] = destinataire_compte
with open("comptes_entreprises.json", "w", encoding="utf-8") as f:
json.dump(comptes_entreprises, f, indent=4, ensure_ascii=False)
else:
comptes_bancaires[destinataire_banque][destinataire_nom] = destinataire_compte
with open("comptes_entreprises.json", "w", encoding="utf-8") as f:
json.dump(comptes_entreprises, f, indent=4, ensure_ascii=False)
with open("comptes_bancaires.json", "w", encoding="utf-8") as f:
json.dump(comptes_bancaires, f, indent=4, ensure_ascii=False)
# Message de confirmation
embed = discord.Embed(
title="🏛️ Virement Gouvernemental effectué",
description=f"💼 Banque destinataire : **{destinataire_banque}**\n📌 Type : **{destinataire_type.capitalize()}**",
color=discord.Color.gold()
)
embed.add_field(name="RIB destinataire", value=rib, inline=False)
embed.add_field(name="Montant viré", value=f"{montant:.2f}€", inline=True)
embed.add_field(name="Effectué par", value=interaction.user.mention, inline=True)
embed.set_footer(text="Transaction enregistrée ✅")
await interaction.response.send_message(embed=embed, ephemeral=False)
async def setup(bot):
await bot.add_cog(GouvVirement(bot))

View file

@ -1,66 +0,0 @@
import discord
from discord import app_commands
from discord.ext import commands
from utils.banque_manager import BanqueManager
from utils.guild_config import has_role
banque_manager = BanqueManager()
class Transactions(commands.Cog):
def __init__(self, bot):
self.bot = bot
@app_commands.command(name="transactions", description="Affiche les transactions d'un utilisateur (réservé aux banquiers).")
async def transactions(self, interaction: discord.Interaction, utilisateur: discord.Member):
"""Affiche l'historique des transactions d'un utilisateur (banquiers uniquement)."""
# ✅ Récupération du vrai membre pour avoir les rôles
member = interaction.guild.get_member(interaction.user.id)
if not member:
await interaction.response.send_message("❌ Impossible de vérifier vos permissions.", ephemeral=True)
return
# ✅ Vérification du rôle banquier
if not has_role(member, "banquier"):
await interaction.response.send_message("❌ Vous n'avez pas la permission de voir les transactions.", ephemeral=True)
return
banque_manager.load_data()
user_id = str(utilisateur.id)
# ✅ Vérification si l'utilisateur a des transactions
if user_id not in banque_manager.comptes or "transactions" not in banque_manager.comptes[user_id]:
await interaction.response.send_message(f"❌ {utilisateur.mention} n'a pas d'historique de transactions.", ephemeral=True)
return
transactions = banque_manager.comptes[user_id].get("transactions", [])
if not transactions:
await interaction.response.send_message(f"📜 {utilisateur.mention} n'a encore effectué aucune transaction.", ephemeral=True)
return
# ✅ Création de l'embed
embed = discord.Embed(
title=f"📜 Historique des transactions de {utilisateur.name}",
color=discord.Color.gold()
)
for t in transactions[-10:]:
embed.add_field(
name=f"📅 {t['date']}",
value=(
f"**Type**: {t['type']}\n"
f"💰 **Montant**: {t['montant']}€\n"
f"📤 **Émetteur**: <@{t['emetteur']}>\n"
f"📥 **Destinataire**: <@{t['destinataire']}>"
),
inline=False
)
embed.set_footer(text="Seules les 10 dernières transactions sont affichées.")
await interaction.response.send_message(embed=embed)
async def setup(bot):
await bot.add_cog(Transactions(bot))

View file

@ -1,138 +1,71 @@
import json
import discord
from discord import app_commands
from discord.ext import commands
from datetime import datetime
from utils.bank_manager import BankManager
from utils.rib import decoder_rib
bank_manager = BankManager()
class Virement(commands.Cog):
def __init__(self, bot):
self.bot = bot
banque_choices = [
app_commands.Choice(name="Victoria's Credit Bank", value="Victoria's Credit Bank"),
app_commands.Choice(name="NGC Bank", value="NGC Bank"),
]
@app_commands.command(name="virement", description="Fait un virement bancaire à un autre membre via son RIB")
@app_commands.choices(banque=banque_choices)
@app_commands.describe(rib="Le RIB du destinataire", montant="Le montant à envoyer", banque="Banque d'où retirer l'argent")
async def virement(self, interaction: discord.Interaction, rib: str, montant: float, banque: app_commands.Choice[str]):
auteur_id = str(interaction.user.id)
banque_source = banque.value
# Charger les comptes utilisateurs
with open('comptes_bancaires.json', 'r', encoding='utf-8') as f:
comptes = json.load(f)
# Charger les comptes entreprises
with open('comptes_entreprises.json', 'r', encoding='utf-8') as f:
entreprises = json.load(f)
# Vérifier que l'utilisateur a un compte dans cette banque
if banque_source not in comptes or auteur_id not in comptes[banque_source]:
await interaction.response.send_message(f"❌ Tu n'as pas de compte dans la banque **{banque_source}**.", ephemeral=True)
@app_commands.command(name="virement", description="Faire un virement à un autre compte via RIB")
@app_commands.describe(
rib_source="Votre RIB (compte source)",
rib_dest="RIB du destinataire",
montant="Montant à envoyer",
)
async def virement(
self,
interaction: discord.Interaction,
rib_source: str,
rib_dest: str,
montant: float,
):
if montant <= 0:
await interaction.response.send_message("❌ Le montant doit être supérieur à 0.", ephemeral=True)
return
compte_emetteur = comptes[banque_source][auteur_id]
if compte_emetteur["solde"] < montant:
await interaction.response.send_message("❌ Ton solde est insuffisant pour effectuer ce virement.", ephemeral=True)
compte_source = await bank_manager.get_compte_by_rib(interaction.guild.id, rib_source)
if not compte_source:
await interaction.response.send_message("❌ RIB source introuvable.", ephemeral=True)
return
if compte_source["user_id"] != interaction.user.id:
await interaction.response.send_message("❌ Ce RIB ne vous appartient pas.", ephemeral=True)
return
# Rechercher le destinataire (utilisateur ou entreprise)
destinataire_id = None
banque_destinataire = None
is_entreprise = False
try:
result = await bank_manager.virement(
guild_id=interaction.guild.id,
rib_source=rib_source,
rib_dest=rib_dest,
montant=montant,
emetteur_id=interaction.user.id,
)
# Recherche dans comptes utilisateurs
for bq_name, bq_data in comptes.items():
if isinstance(bq_data, dict):
for user_id, info in bq_data.items():
if isinstance(info, dict) and info.get("rib") == rib:
destinataire_id = user_id
banque_destinataire = bq_name
break
if destinataire_id:
break
msg = f"✅ Virement de **{result['montant_envoye']:.2f}€** effectué."
if result["tva_prelevee"] > 0:
msg += f"\n💰 TVA prélevée : **{result['tva_prelevee']:.2f}€** → Fisc."
msg += f"\n**Reçu par le destinataire :** {result['montant_recu']:.2f}€"
# Sinon, recherche dans les entreprises
if not destinataire_id:
for bq_name, bq_data in entreprises.items():
if isinstance(bq_data, dict):
for ent_id, info in bq_data.items():
if isinstance(info, dict) and info.get("rib") == rib:
destinataire_id = ent_id
banque_destinataire = bq_name
is_entreprise = True
break
if destinataire_id:
break
await interaction.response.send_message(msg, ephemeral=True)
if not destinataire_id:
await interaction.response.send_message("❌ Aucun compte trouvé avec ce RIB.", ephemeral=True)
return
# Appliquer la TVA si entreprise
montant_net = montant
tva_envoyee = 0
if is_entreprise:
taux = entreprises[banque_destinataire][destinataire_id].get("tva", 0)
tva_envoyee = round(montant * taux / 100, 2)
montant_net = montant - tva_envoyee
# Ajouter la TVA au Gouvernement
if "Gouvernement" not in entreprises:
entreprises["Gouvernement"] = {}
if "GOUV" not in entreprises["Gouvernement"]:
entreprises["Gouvernement"]["GOUV"] = {
"rib": "00000 00000 00000000000 00",
"solde": 0.0,
"transactions": []
}
entreprises["Gouvernement"]["GOUV"]["solde"] += tva_envoyee
entreprises["Gouvernement"]["GOUV"]["transactions"].append({
"date": datetime.now().strftime("%d/%m/%Y %H:%M:%S"),
"type": "TVA reçue",
"source": auteur_id,
"montant": tva_envoyee
})
# Déduire du compte émetteur
comptes[banque_source][auteur_id]["solde"] -= montant
comptes[banque_source][auteur_id]["transactions"].append({
"date": datetime.now().strftime("%d/%m/%Y %H:%M:%S"),
"type": "Virement",
"source": f"Vers RIB {rib}",
"montant": -montant
})
# Ajouter au compte destinataire
cible_data = entreprises if is_entreprise else comptes
cible_data[banque_destinataire][destinataire_id]["solde"] += montant_net
cible_data[banque_destinataire][destinataire_id]["transactions"].append({
"date": datetime.now().strftime("%d/%m/%Y %H:%M:%S"),
"type": "Virement reçu",
"source": interaction.user.name,
"montant": montant_net
})
# Sauvegarde
with open('comptes_bancaires.json', 'w', encoding='utf-8') as f:
json.dump(comptes, f, ensure_ascii=False, indent=4)
with open('comptes_entreprises.json', 'w', encoding='utf-8') as f:
json.dump(entreprises, f, ensure_ascii=False, indent=4)
# Envoi MP au destinataire si c'est un utilisateur
if not is_entreprise:
try:
user_dest = await self.bot.fetch_user(int(destinataire_id))
await user_dest.send(f"📥 Vous avez reçu un virement de **{montant:.2f}€** de la part de **{interaction.user.display_name}**.")
except:
pass # Si l'utilisateur a les MP désactivés
dest_compte = await bank_manager.get_compte_by_rib(interaction.guild.id, rib_dest)
if dest_compte and dest_compte["account_type"] == "particulier":
dest_user = await self.bot.fetch_user(dest_compte["user_id"])
await dest_user.send(
f"📥 Vous avez reçu **{result['montant_recu']:.2f}€** de la part de **{interaction.user.display_name}**."
)
except (discord.Forbidden, Exception):
pass
except ValueError as e:
await interaction.response.send_message(f"❌ {e}", ephemeral=True)
await interaction.response.send_message(
f"✅ Virement de **{montant:.2f}€** effectué.{' TVA de ' + str(tva_envoyee) + '€ envoyée au Gouvernement.' if is_entreprise else ''}",
ephemeral=True
)
async def setup(bot):
await bot.add_cog(Virement(bot))
await bot.add_cog(Virement(bot))

View file

@ -1,85 +0,0 @@
import json
import discord
from discord import app_commands
from discord.ext import commands
from datetime import datetime
from utils.guild_config import has_role
class VirementBanquier(commands.Cog):
def __init__(self, bot):
self.bot = bot
banque_choices = [
app_commands.Choice(name="Victoria's Credit Bank", value="Victoria's Credit Bank"),
app_commands.Choice(name="NGC Bank", value="NGC Bank"),
]
@app_commands.command(name="virement_banquier", description="Effectue un virement au nom d'un client (réservé aux banquiers).")
@app_commands.choices(banque=banque_choices)
async def virement_banquier(
self,
interaction: discord.Interaction,
rib_emetteur: str,
montant: float,
rib_destinataire: str,
banque: app_commands.Choice[str]
):
if not has_role(interaction.user, "banquier"):
await interaction.response.send_message("❌ Vous n'avez pas la permission d'utiliser cette commande.", ephemeral=True)
return
banque_nom = banque.value
try:
with open("comptes_bancaires.json", "r", encoding="utf-8") as f:
comptes = json.load(f)
except:
await interaction.response.send_message("❌ Erreur de lecture des comptes bancaires.", ephemeral=True)
return
# Trouver les ID à partir des RIB
emetteur_id = None
destinataire_id = None
for user_id, data in comptes.get(banque_nom, {}).items():
if data.get("rib") == rib_emetteur:
emetteur_id = user_id
if data.get("rib") == rib_destinataire:
destinataire_id = user_id
if not emetteur_id:
await interaction.response.send_message("❌ Le RIB émetteur est introuvable dans cette banque.", ephemeral=True)
return
if not destinataire_id:
await interaction.response.send_message("❌ Le RIB destinataire est introuvable dans cette banque.", ephemeral=True)
return
# Vérifier le solde
if comptes[banque_nom][emetteur_id]["solde"] < montant:
await interaction.response.send_message("❌ Le solde du compte émetteur est insuffisant.", ephemeral=True)
return
# Exécuter le virement
comptes[banque_nom][emetteur_id]["solde"] -= montant
comptes[banque_nom][emetteur_id]["transactions"].append({
"date": datetime.now().strftime("%d/%m/%Y %H:%M:%S"),
"type": "Virement manuel (par banquier)",
"source": f"Vers RIB {rib_destinataire}",
"montant": -montant
})
comptes[banque_nom][destinataire_id]["solde"] += montant
comptes[banque_nom][destinataire_id]["transactions"].append({
"date": datetime.now().strftime("%d/%m/%Y %H:%M:%S"),
"type": "Virement reçu (par banquier)",
"source": f"RIB {rib_emetteur}",
"montant": montant
})
with open("comptes_bancaires.json", "w", encoding="utf-8") as f:
json.dump(comptes, f, ensure_ascii=False, indent=4)
await interaction.response.send_message(f"✅ Virement de **{montant:.2f}€** effectué de **{rib_emetteur}** vers **{rib_destinataire}** dans **{banque_nom}**.", ephemeral=True)
async def setup(bot):
await bot.add_cog(VirementBanquier(bot))

View file

@ -1,121 +0,0 @@
import discord
from discord import app_commands
from discord.ext import commands
import json
from datetime import datetime
from utils.guild_config import has_role
class VirementBanquierEntreprise(commands.Cog):
def __init__(self, bot):
self.bot = bot
banques = [
app_commands.Choice(name="Victoria's Credit Bank", value="Victoria's Credit Bank"),
app_commands.Choice(name="NGC Bank", value="NGC Bank")
]
@app_commands.command(name="virement_banquier_entreprise", description="Fait un virement depuis une entreprise avec mot de passe (réservé aux banquiers).")
@app_commands.choices(banque=banques)
async def virement_banquier_entreprise(
self,
interaction: discord.Interaction,
banque: app_commands.Choice[str],
nom_entreprise: str,
mot_de_passe: str,
rib_destinataire: str,
montant: float
):
if not has_role(interaction.user, "banquier"):
await interaction.response.send_message("❌ Vous n'avez pas la permission de faire cette commande.", ephemeral=True)
return
banque_nom = banque.value
# Chargement des fichiers
try:
with open("comptes_entreprises.json", "r", encoding="utf-8") as f:
entreprises = json.load(f)
with open("comptes_bancaires.json", "r", encoding="utf-8") as f:
particuliers = json.load(f)
except Exception:
await interaction.response.send_message("❌ Erreur de lecture des fichiers JSON.", ephemeral=True)
return
# Vérification de l'entreprise
if banque_nom not in entreprises or nom_entreprise not in entreprises[banque_nom]:
await interaction.response.send_message("❌ Compte entreprise introuvable.", ephemeral=True)
return
compte_entreprise = entreprises[banque_nom][nom_entreprise]
if compte_entreprise.get("mdp") != mot_de_passe:
await interaction.response.send_message("❌ Mot de passe incorrect.", ephemeral=True)
return
if compte_entreprise["solde"] < montant:
await interaction.response.send_message("❌ Solde insuffisant pour ce virement.", ephemeral=True)
return
# Recherche du compte destinataire (entreprise ou particulier)
destinataire_id = None
banque_destinataire = None
is_entreprise = False
# Recherche dans entreprises
for bq, entreprises_data in entreprises.items():
for nom, infos in entreprises_data.items():
if infos.get("rib") == rib_destinataire:
destinataire_id = nom
banque_destinataire = bq
is_entreprise = True
break
if destinataire_id:
break
# Sinon, recherche dans particuliers
if not destinataire_id:
for bq, clients in particuliers.items():
for user_id, infos in clients.items():
if infos.get("rib") == rib_destinataire:
destinataire_id = user_id
banque_destinataire = bq
is_entreprise = False
break
if destinataire_id:
break
if not destinataire_id:
await interaction.response.send_message("❌ RIB destinataire introuvable.", ephemeral=True)
return
# Retrait du montant
compte_entreprise["solde"] -= montant
compte_entreprise["transactions"].append({
"date": datetime.now().strftime("%d/%m/%Y %H:%M:%S"),
"type": "Virement",
"source": f"Entreprise {nom_entreprise}",
"montant": -montant,
"destinataire": rib_destinataire
})
# Créditer le destinataire
compte_cible = entreprises if is_entreprise else particuliers
compte_data = compte_cible[banque_destinataire][destinataire_id]
compte_data["solde"] += montant
compte_data["transactions"].append({
"date": datetime.now().strftime("%d/%m/%Y %H:%M:%S"),
"type": "Virement reçu",
"source": nom_entreprise,
"montant": montant
})
# Sauvegarde
with open("comptes_entreprises.json", "w", encoding="utf-8") as f:
json.dump(entreprises, f, ensure_ascii=False, indent=4)
with open("comptes_bancaires.json", "w", encoding="utf-8") as f:
json.dump(particuliers, f, ensure_ascii=False, indent=4)
await interaction.response.send_message(f"✅ Virement de **{montant:.2f}€** effectué depuis **{nom_entreprise}** vers **{rib_destinataire}**.")
async def setup(bot):
await bot.add_cog(VirementBanquierEntreprise(bot))

View file

@ -1,149 +0,0 @@
import discord
from discord import app_commands
from discord.ext import commands
import json
from datetime import datetime
class VirementEntreprise(commands.Cog):
def __init__(self, bot):
self.bot = bot
banque_choices = [
app_commands.Choice(name="Victoria's Credit Bank", value="Victoria's Credit Bank"),
app_commands.Choice(name="NGC Bank", value="NGC Bank"),
]
@app_commands.command(name="virement_entreprise", description="Effectuer un virement depuis une entreprise vers un RIB.")
@app_commands.choices(banque=banque_choices)
async def virement_entreprise(
self,
interaction: discord.Interaction,
rib_entreprise: str,
montant: float,
mot_de_passe: str,
rib_destinataire: str,
banque: app_commands.Choice[str]
):
banque_nom = banque.value
# Chargement des données
try:
with open("comptes_entreprises.json", "r", encoding="utf-8") as f:
comptes_entreprises = json.load(f)
with open("comptes_bancaires.json", "r", encoding="utf-8") as f:
comptes_bancaires = json.load(f)
except Exception:
await interaction.response.send_message("❌ Erreur de lecture des données bancaires.", ephemeral=True)
return
# 🔐 Vérification de l'émetteur
entreprise_id = None
for nom_entreprise, infos in comptes_entreprises.get(banque_nom, {}).items():
if infos.get("rib") == rib_entreprise:
if infos.get("mdp") != mot_de_passe:
await interaction.response.send_message("❌ Mot de passe incorrect.", ephemeral=True)
return
entreprise_id = nom_entreprise
break
if not entreprise_id:
await interaction.response.send_message("❌ Aucun compte entreprise trouvé avec ce RIB.", ephemeral=True)
return
compte_emetteur = comptes_entreprises[banque_nom][entreprise_id]
if compte_emetteur["solde"] < montant:
await interaction.response.send_message("❌ Solde insuffisant.", ephemeral=True)
return
# 🔎 Recherche du destinataire
destinataire_data = None
destinataire_type = None
destinataire_nom = None
banque_dest = None
for banque_cible, comptes in comptes_entreprises.items():
for nom, infos in comptes.items():
if infos.get("rib") == rib_destinataire:
destinataire_data = infos
destinataire_type = "entreprise"
destinataire_nom = nom
banque_dest = banque_cible
break
if destinataire_data:
break
if not destinataire_data:
for banque_cible, comptes in comptes_bancaires.items():
for uid, infos in comptes.items():
if infos.get("rib") == rib_destinataire:
destinataire_data = infos
destinataire_type = "particulier"
destinataire_nom = uid
banque_dest = banque_cible
break
if destinataire_data:
break
if not destinataire_data:
await interaction.response.send_message("❌ RIB destinataire introuvable.", ephemeral=True)
return
# 📉 Débit du compte entreprise
compte_emetteur["solde"] -= montant
now = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
compte_emetteur.setdefault("transactions", []).append({
"date": now,
"type": "Virement",
"source": f"Vers RIB {rib_destinataire}",
"montant": -montant
})
# 📈 Crédit du destinataire (avec TVA si entreprise)
montant_net = montant
tva_envoyee = 0
if destinataire_type == "entreprise":
tva = destinataire_data.get("tva", 0)
tva_envoyee = round(montant * tva / 100, 2)
montant_net = montant - tva_envoyee
# Crédit TVA à l'État
if "Gouvernement" not in comptes_entreprises:
comptes_entreprises["Gouvernement"] = {}
if "GOUV" not in comptes_entreprises["Gouvernement"]:
comptes_entreprises["Gouvernement"]["GOUV"] = {
"rib": "00000 00000 00000000000 00",
"solde": 0.0,
"transactions": []
}
comptes_entreprises["Gouvernement"]["GOUV"]["solde"] += tva_envoyee
comptes_entreprises["Gouvernement"]["GOUV"]["transactions"].append({
"date": now,
"type": "TVA reçue",
"source": entreprise_id,
"montant": tva_envoyee
})
destinataire_data["solde"] += montant_net
destinataire_data.setdefault("transactions", []).append({
"date": now,
"type": "Virement reçu",
"source": entreprise_id,
"montant": montant_net
})
# Sauvegardes
with open("comptes_entreprises.json", "w", encoding="utf-8") as f:
json.dump(comptes_entreprises, f, ensure_ascii=False, indent=4)
with open("comptes_bancaires.json", "w", encoding="utf-8") as f:
json.dump(comptes_bancaires, f, ensure_ascii=False, indent=4)
await interaction.response.send_message(
f"✅ Virement effectué avec succès.{' TVA de ' + str(tva_envoyee) + '€ envoyée au Gouvernement.' if tva_envoyee else ''}",
ephemeral=True
)
async def setup(bot):
await bot.add_cog(VirementEntreprise(bot))

View file

@ -1,97 +0,0 @@
import discord
from discord import app_commands
from discord.ext import commands
import json
from datetime import datetime
class VirementFBM(commands.Cog):
def __init__(self, bot):
self.bot = bot
banque_choices = [
app_commands.Choice(name="Victoria's Credit Bank", value="Victoria's Credit Bank"),
app_commands.Choice(name="NGC Bank", value="NGC Bank"),
]
@app_commands.command(name="virement_fbm", description="Fait un virement au compte indépendant FBM.")
@app_commands.choices(banque=banque_choices)
@app_commands.describe(montant="Montant à transférer", banque="Banque à utiliser")
async def virement_fbm(self, interaction: discord.Interaction, montant: float, banque: app_commands.Choice[str]):
auteur_id = str(interaction.user.id)
banque_nom = banque.value
if montant <= 0:
await interaction.response.send_message("❌ Le montant doit être supérieur à 0.", ephemeral=True)
return
# Charger les fichiers
try:
with open("comptes_bancaires.json", "r", encoding="utf-8") as f:
comptes = json.load(f)
except Exception:
await interaction.response.send_message("❌ Erreur lors de la lecture des comptes bancaires.", ephemeral=True)
return
try:
with open("comptes_entreprises.json", "r", encoding="utf-8") as f:
entreprises = json.load(f)
except:
entreprises = {}
# Vérification du compte de l'utilisateur
if banque_nom not in comptes or auteur_id not in comptes[banque_nom]:
await interaction.response.send_message("❌ Tu n'as pas de compte dans cette banque.", ephemeral=True)
return
compte = comptes[banque_nom][auteur_id]
if compte["solde"] < montant:
await interaction.response.send_message("❌ Solde insuffisant pour effectuer le virement.", ephemeral=True)
return
# Initialiser FBM si nécessaire
if "fbm" not in entreprises:
entreprises["fbm"] = {}
if "FBM" not in entreprises["fbm"]:
entreprises["fbm"]["FBM"] = {
"rib": "00000 00000 00000000000 03",
"solde": 0.0,
"transactions": []
}
now = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
# Mise à jour des soldes
compte["solde"] -= montant
entreprises["fbm"]["FBM"]["solde"] += montant
# Historique utilisateur
compte["transactions"].append({
"date": now,
"type": "Virement",
"source": f"Vers FBM",
"montant": -montant
})
# Historique FBM
entreprises["fbm"]["FBM"]["transactions"].append({
"date": now,
"type": "Virement reçu",
"source": interaction.user.name,
"montant": montant
})
# Sauvegarde
with open("comptes_bancaires.json", "w", encoding="utf-8") as f:
json.dump(comptes, f, indent=4, ensure_ascii=False)
with open("comptes_entreprises.json", "w", encoding="utf-8") as f:
json.dump(entreprises, f, indent=4, ensure_ascii=False)
# Confirmation
await interaction.response.send_message(
f"✅ Virement de **{montant:.2f}€** envoyé au compte **FBM** depuis **{banque_nom}**.",
ephemeral=True
)
async def setup(bot):
await bot.add_cog(VirementFBM(bot))

View file

@ -1,86 +0,0 @@
import discord
from discord import app_commands
from discord.ext import commands
import json
from datetime import datetime
class VirementGouvernement(commands.Cog):
def __init__(self, bot):
self.bot = bot
banque_choices = [
app_commands.Choice(name="Victoria's Credit Bank", value="Victoria's Credit Bank"),
app_commands.Choice(name="NGC Bank", value="NGC Bank"),
]
@app_commands.command(name="virement_gouvernement", description="Effectue un virement au Gouvernement.")
@app_commands.choices(banque=banque_choices)
@app_commands.describe(montant="Le montant à envoyer", banque="Banque à utiliser pour le virement")
async def virement_gouvernement(self, interaction: discord.Interaction, montant: float, banque: app_commands.Choice[str]):
auteur_id = str(interaction.user.id)
banque_source = banque.value
if montant <= 0:
await interaction.response.send_message("❌ Le montant doit être supérieur à zéro.", ephemeral=True)
return
# Charger les fichiers
try:
with open('comptes_bancaires.json', 'r', encoding='utf-8') as f:
comptes = json.load(f)
with open('comptes_entreprises.json', 'r', encoding='utf-8') as f:
entreprises = json.load(f)
except Exception as e:
await interaction.response.send_message(f"❌ Erreur de lecture des fichiers : {e}", ephemeral=True)
return
if banque_source not in comptes or auteur_id not in comptes[banque_source]:
await interaction.response.send_message(f"❌ Tu n'as pas de compte dans la banque **{banque_source}**.", ephemeral=True)
return
compte_user = comptes[banque_source][auteur_id]
if compte_user["solde"] < montant:
await interaction.response.send_message("❌ Solde insuffisant pour effectuer ce virement.", ephemeral=True)
return
# Vérifier ou créer le compte Gouvernement
if "Gouvernement" not in entreprises:
entreprises["Gouvernement"] = {}
if "GOUV" not in entreprises["Gouvernement"]:
entreprises["Gouvernement"]["GOUV"] = {
"rib": "00000 00000 00000000000 00",
"solde": 0.0,
"transactions": []
}
# Effectuer le virement
now = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
compte_user["solde"] -= montant
entreprises["Gouvernement"]["GOUV"]["solde"] += montant
compte_user["transactions"].append({
"date": now,
"type": "Virement",
"source": f"Vers Gouvernement",
"montant": -montant
})
entreprises["Gouvernement"]["GOUV"]["transactions"].append({
"date": now,
"type": "Virement reçu",
"source": interaction.user.name,
"montant": montant
})
# Sauvegarde
with open('comptes_bancaires.json', 'w', encoding='utf-8') as f:
json.dump(comptes, f, indent=4, ensure_ascii=False)
with open('comptes_entreprises.json', 'w', encoding='utf-8') as f:
json.dump(entreprises, f, indent=4, ensure_ascii=False)
await interaction.response.send_message(
f"✅ Virement de **{montant:.2f}€** envoyé au Gouvernement avec succès.",
ephemeral=True
)
async def setup(bot):
await bot.add_cog(VirementGouvernement(bot))

View file

@ -1,93 +0,0 @@
import discord
from discord import app_commands
from discord.ext import commands
import json
from datetime import datetime
class VirementUrssaf(commands.Cog):
def __init__(self, bot):
self.bot = bot
banque_choices = [
app_commands.Choice(name="Victoria's Credit Bank", value="Victoria's Credit Bank"),
app_commands.Choice(name="NGC Bank", value="NGC Bank"),
]
@app_commands.command(name="virement_ursaff", description="Fait un virement vers le compte indépendant URSAFF.")
@app_commands.choices(banque=banque_choices)
@app_commands.describe(montant="Montant à transférer", banque="Banque à utiliser")
async def virement_ursaff(self, interaction: discord.Interaction, montant: float, banque: app_commands.Choice[str]):
auteur_id = str(interaction.user.id)
banque_nom = banque.value
if montant <= 0:
await interaction.response.send_message("❌ Le montant doit être supérieur à 0.", ephemeral=True)
return
try:
with open("comptes_bancaires.json", "r", encoding="utf-8") as f:
comptes = json.load(f)
except Exception:
await interaction.response.send_message("❌ Erreur lors de la lecture des comptes bancaires.", ephemeral=True)
return
try:
with open("comptes_entreprises.json", "r", encoding="utf-8") as f:
entreprises = json.load(f)
except:
entreprises = {}
if banque_nom not in comptes or auteur_id not in comptes[banque_nom]:
await interaction.response.send_message("❌ Tu n'as pas de compte dans cette banque.", ephemeral=True)
return
compte = comptes[banque_nom][auteur_id]
if compte["solde"] < montant:
await interaction.response.send_message("❌ Solde insuffisant pour effectuer le virement.", ephemeral=True)
return
# Initialiser URSAFF si nécessaire
if "ursaff" not in entreprises:
entreprises["ursaff"] = {}
if "URSAFF" not in entreprises["ursaff"]:
entreprises["ursaff"]["URSAFF"] = {
"rib": "00000 00000 00000000000 02",
"solde": 0.0,
"transactions": []
}
now = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
# Mise à jour des soldes
compte["solde"] -= montant
entreprises["ursaff"]["URSAFF"]["solde"] += montant
# Historique utilisateur
compte["transactions"].append({
"date": now,
"type": "Virement",
"source": "Vers URSAFF",
"montant": -montant
})
# Historique URSAFF
entreprises["ursaff"]["URSAFF"]["transactions"].append({
"date": now,
"type": "Virement reçu",
"source": interaction.user.name,
"montant": montant
})
# Sauvegarde
with open("comptes_bancaires.json", "w", encoding="utf-8") as f:
json.dump(comptes, f, indent=4, ensure_ascii=False)
with open("comptes_entreprises.json", "w", encoding="utf-8") as f:
json.dump(entreprises, f, indent=4, ensure_ascii=False)
await interaction.response.send_message(
f"✅ Virement de **{montant:.2f}€** envoyé au compte **URSAFF** depuis **{banque_nom}**.",
ephemeral=True
)
async def setup(bot):
await bot.add_cog(VirementUrssaf(bot))