117 lines
4.3 KiB
Python
117 lines
4.3 KiB
Python
"""Services financiers: registre comptable, soldes et réserves."""
|
|
from sqlalchemy import desc, func, select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.core.financial_position import PositionTresorerie
|
|
from app.models.depense import Depense
|
|
from app.models.envoi_contribution import EnvoiContribution
|
|
from app.models.mouvement_reserve import MouvementReserve
|
|
from app.models.reserve import Reserve
|
|
from app.models.transaction_comptable import TransactionComptable
|
|
|
|
|
|
async def solde_compte(groupe_id, compte: str, db: AsyncSession) -> float:
|
|
debits = float((await db.execute(
|
|
select(func.coalesce(func.sum(TransactionComptable.montant), 0)).where(
|
|
TransactionComptable.groupe_id == groupe_id,
|
|
TransactionComptable.compte == compte,
|
|
TransactionComptable.sens == "debit",
|
|
)
|
|
)).scalar())
|
|
credits = float((await db.execute(
|
|
select(func.coalesce(func.sum(TransactionComptable.montant), 0)).where(
|
|
TransactionComptable.groupe_id == groupe_id,
|
|
TransactionComptable.compte == compte,
|
|
TransactionComptable.sens == "credit",
|
|
)
|
|
)).scalar())
|
|
return debits - credits
|
|
|
|
|
|
async def encaisse(groupe_id, db: AsyncSession) -> float:
|
|
return await solde_compte(groupe_id, "encaisse", db)
|
|
|
|
|
|
async def solde_banque(groupe_id, db: AsyncSession) -> float:
|
|
return await solde_compte(groupe_id, "banque", db)
|
|
|
|
|
|
async def engagements_non_debites(groupe_id, db: AsyncSession) -> float:
|
|
depenses = float((await db.execute(
|
|
select(func.coalesce(func.sum(Depense.montant), 0)).where(
|
|
Depense.groupe_id == groupe_id,
|
|
Depense.paye == False,
|
|
Depense.methode.in_(["VIREMENT", "CHEQUE"]),
|
|
)
|
|
)).scalar())
|
|
contributions = float((await db.execute(
|
|
select(func.coalesce(func.sum(EnvoiContribution.montant), 0)).where(
|
|
EnvoiContribution.groupe_id == groupe_id,
|
|
EnvoiContribution.engagee == True,
|
|
EnvoiContribution.debitee == False,
|
|
)
|
|
)).scalar())
|
|
return depenses + contributions
|
|
|
|
|
|
async def solde_reserve(reserve_id, db: AsyncSession) -> float:
|
|
entrees = float((await db.execute(
|
|
select(func.coalesce(func.sum(MouvementReserve.montant), 0)).where(
|
|
MouvementReserve.destination_id == reserve_id,
|
|
)
|
|
)).scalar())
|
|
sorties = float((await db.execute(
|
|
select(func.coalesce(func.sum(MouvementReserve.montant), 0)).where(
|
|
MouvementReserve.source_id == reserve_id,
|
|
)
|
|
)).scalar())
|
|
return entrees - sorties
|
|
|
|
|
|
async def total_reserves(groupe_id, db: AsyncSession, exclure_id: str | None = None) -> float:
|
|
result = await db.execute(select(Reserve).where(Reserve.groupe_id == groupe_id, Reserve.active == True))
|
|
total = 0.0
|
|
for reserve in result.scalars().all():
|
|
if exclure_id and str(reserve.id) == str(exclure_id):
|
|
continue
|
|
total += await solde_reserve(reserve.id, db)
|
|
return total
|
|
|
|
|
|
async def reserve_disponible(groupe_id, db: AsyncSession) -> float:
|
|
return (await position_tresorerie(groupe_id, db)).disponible_bancaire
|
|
|
|
|
|
async def position_tresorerie(groupe_id, db: AsyncSession) -> PositionTresorerie:
|
|
return PositionTresorerie(
|
|
solde_banque=await solde_banque(groupe_id, db),
|
|
encaisse=await encaisse(groupe_id, db),
|
|
total_reserves=await total_reserves(groupe_id, db),
|
|
engagements_non_debites=await engagements_non_debites(groupe_id, db),
|
|
)
|
|
|
|
|
|
async def dernier_releve(groupe_id, db: AsyncSession):
|
|
from app.models.operation_bancaire import OperationBancaire
|
|
result = await db.execute(
|
|
select(OperationBancaire).where(
|
|
OperationBancaire.groupe_id == groupe_id,
|
|
OperationBancaire.type == "releve",
|
|
).order_by(desc(OperationBancaire.date_operation)).limit(1)
|
|
)
|
|
return result.scalar_one_or_none()
|
|
|
|
|
|
def transaction(groupe_id, membre_id, date_transaction, type_, compte, montant, sens, source_table=None, source_id=None, note=None):
|
|
return TransactionComptable(
|
|
groupe_id=groupe_id,
|
|
date_transaction=date_transaction,
|
|
type=type_,
|
|
compte=compte,
|
|
montant=montant,
|
|
sens=sens,
|
|
source_table=source_table,
|
|
source_id=source_id,
|
|
note=note,
|
|
cree_par=membre_id,
|
|
)
|