148 lines
6.4 KiB
Python
148 lines
6.4 KiB
Python
|
|
from database import creer_connexion, enregistrer_audit
|
||
|
|
from auth import obtenir_ip_client
|
||
|
|
from validators import valider_champs_obligatoires, valider_montant
|
||
|
|
from models.transaction import TransactionDAO
|
||
|
|
from models.compte import CompteDAO
|
||
|
|
from models.beneficiaire import BeneficiaireDAO
|
||
|
|
|
||
|
|
class TransactionService:
|
||
|
|
def __init__(self):
|
||
|
|
self.transaction_dao = TransactionDAO()
|
||
|
|
self.compte_dao = CompteDAO()
|
||
|
|
self.beneficiaire_dao = BeneficiaireDAO()
|
||
|
|
|
||
|
|
def virement_interne(self, id_utilisateur_courant, donnees):
|
||
|
|
conn = creer_connexion()
|
||
|
|
try:
|
||
|
|
valider_champs_obligatoires(donnees, ['from_account_id', 'to_account_id', 'amount'])
|
||
|
|
montant = valider_montant(donnees['amount'])
|
||
|
|
|
||
|
|
if donnees['from_account_id'] == donnees['to_account_id']:
|
||
|
|
raise ValueError('Les comptes source et destination doivent etre differents')
|
||
|
|
|
||
|
|
source = self.compte_dao.trouver_actif(conn, donnees['from_account_id'], id_utilisateur_courant)
|
||
|
|
dest = self.compte_dao.trouver_actif(conn, donnees['to_account_id'], id_utilisateur_courant)
|
||
|
|
|
||
|
|
if not source:
|
||
|
|
raise ValueError('Compte source introuvable')
|
||
|
|
if not dest:
|
||
|
|
raise ValueError('Compte destination introuvable')
|
||
|
|
|
||
|
|
libelle = donnees.get('description') or (
|
||
|
|
'Virement ' + source['account_type'] + ' vers ' + dest['account_type']
|
||
|
|
)
|
||
|
|
|
||
|
|
transaction = self.transaction_dao.virement_interne(
|
||
|
|
conn, donnees['from_account_id'], donnees['to_account_id'],
|
||
|
|
montant, libelle, self.compte_dao
|
||
|
|
)
|
||
|
|
enregistrer_audit(conn.cursor(), id_utilisateur_courant, 'TRANSFER_INTERNAL',
|
||
|
|
{'montant': float(montant), 'source': source['account_number'],
|
||
|
|
'dest': dest['account_number']}, obtenir_ip_client())
|
||
|
|
conn.commit()
|
||
|
|
return transaction
|
||
|
|
except Exception:
|
||
|
|
conn.rollback()
|
||
|
|
raise
|
||
|
|
finally:
|
||
|
|
conn.close()
|
||
|
|
|
||
|
|
def virement_beneficiaire(self, id_utilisateur_courant, donnees):
|
||
|
|
conn = creer_connexion()
|
||
|
|
try:
|
||
|
|
valider_champs_obligatoires(donnees, ['from_account_id', 'beneficiary_id', 'amount'])
|
||
|
|
montant = valider_montant(donnees['amount'])
|
||
|
|
|
||
|
|
source = self.compte_dao.trouver_actif(conn, donnees['from_account_id'], id_utilisateur_courant)
|
||
|
|
if not source:
|
||
|
|
raise ValueError('Compte source introuvable')
|
||
|
|
|
||
|
|
beneficiaire = self.beneficiaire_dao.trouver_approuve(
|
||
|
|
conn, donnees['beneficiary_id'], id_utilisateur_courant
|
||
|
|
)
|
||
|
|
if not beneficiaire:
|
||
|
|
raise ValueError('Beneficiaire introuvable ou non approuve')
|
||
|
|
|
||
|
|
dest = self.compte_dao.trouver_par_numero(conn, beneficiaire['account_number'])
|
||
|
|
if not dest:
|
||
|
|
raise ValueError('Le compte du beneficiaire est introuvable dans DragonBank')
|
||
|
|
|
||
|
|
libelle = donnees.get('description') or 'Virement a ' + beneficiaire['beneficiary_name']
|
||
|
|
|
||
|
|
transaction = self.transaction_dao.virement_entre_personnes(
|
||
|
|
conn, donnees['from_account_id'], str(dest['id']),
|
||
|
|
montant, libelle, self.compte_dao
|
||
|
|
)
|
||
|
|
enregistrer_audit(conn.cursor(), id_utilisateur_courant, 'TRANSFER_PERSON',
|
||
|
|
{'montant': float(montant), 'beneficiaire': beneficiaire['beneficiary_name']},
|
||
|
|
obtenir_ip_client())
|
||
|
|
conn.commit()
|
||
|
|
return transaction
|
||
|
|
except Exception:
|
||
|
|
conn.rollback()
|
||
|
|
raise
|
||
|
|
finally:
|
||
|
|
conn.close()
|
||
|
|
|
||
|
|
def virement_externe(self, id_utilisateur_courant, donnees):
|
||
|
|
conn = creer_connexion()
|
||
|
|
try:
|
||
|
|
valider_champs_obligatoires(
|
||
|
|
donnees,
|
||
|
|
['account_id', 'amount', 'external_bank_name', 'external_account_number', 'direction']
|
||
|
|
)
|
||
|
|
direction = donnees['direction']
|
||
|
|
if direction not in ('incoming', 'outgoing'):
|
||
|
|
raise ValueError('La direction doit etre "incoming" ou "outgoing"')
|
||
|
|
|
||
|
|
montant = valider_montant(donnees['amount'])
|
||
|
|
compte = self.compte_dao.trouver_actif(conn, donnees['account_id'], id_utilisateur_courant)
|
||
|
|
if not compte:
|
||
|
|
raise ValueError('Compte introuvable')
|
||
|
|
|
||
|
|
nom_banque = donnees['external_bank_name'].strip()
|
||
|
|
num_ext = donnees['external_account_number'].strip().upper()
|
||
|
|
libelle = donnees.get('description', '').strip() or (
|
||
|
|
'Virement ' + ('sortant vers ' if direction == 'outgoing' else 'entrant depuis ')
|
||
|
|
+ nom_banque + ' (' + num_ext + ')'
|
||
|
|
)
|
||
|
|
|
||
|
|
transaction = self.transaction_dao.virement_externe(
|
||
|
|
conn, donnees['account_id'], montant, direction,
|
||
|
|
nom_banque, num_ext, libelle, self.compte_dao
|
||
|
|
)
|
||
|
|
enregistrer_audit(conn.cursor(), id_utilisateur_courant, 'TRANSFER_EXTERNAL',
|
||
|
|
{'montant': float(montant), 'direction': direction, 'banque': nom_banque},
|
||
|
|
obtenir_ip_client())
|
||
|
|
conn.commit()
|
||
|
|
return transaction, direction
|
||
|
|
except Exception:
|
||
|
|
conn.rollback()
|
||
|
|
raise
|
||
|
|
finally:
|
||
|
|
conn.close()
|
||
|
|
|
||
|
|
def obtenir_transactions(self, id_utilisateur_courant, id_compte_filtre, type_tx_filtre, limite):
|
||
|
|
conn = creer_connexion()
|
||
|
|
try:
|
||
|
|
if id_compte_filtre:
|
||
|
|
if not self.compte_dao.trouver_par_id(conn, id_compte_filtre, id_utilisateur_courant):
|
||
|
|
raise ValueError('Compte introuvable ou acces refuse')
|
||
|
|
|
||
|
|
transactions = self.transaction_dao.lister(
|
||
|
|
conn, id_utilisateur_courant, id_compte_filtre, type_tx_filtre, limite
|
||
|
|
)
|
||
|
|
return transactions
|
||
|
|
finally:
|
||
|
|
conn.close()
|
||
|
|
|
||
|
|
def exporter_csv(self, id_utilisateur_courant, id_compte_filtre):
|
||
|
|
conn = creer_connexion()
|
||
|
|
try:
|
||
|
|
if id_compte_filtre:
|
||
|
|
if not self.compte_dao.trouver_par_id(conn, id_compte_filtre, id_utilisateur_courant):
|
||
|
|
raise ValueError('Compte introuvable ou acces refuse')
|
||
|
|
return self.transaction_dao.exporter_csv(conn, id_utilisateur_courant, id_compte_filtre)
|
||
|
|
finally:
|
||
|
|
conn.close()
|