TorbatYar/backend/services/accounting/app/repositories/foundation.py
Mortezakoohjani 12c8615615 Ship enterprise Accounting FE/API with CRUD parity and production wiring.
Adds accounting-service PATCH/archive, fiscal helpers, COA templates and setup status, plus SuperApp Accounting UI (DS, scoreboard, masters, vouchers, ledger, ops modules) with session refresh and HTTPS public API URLs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-24 15:26:43 +03:30

108 lines
3.4 KiB
Python

"""Foundation repositories."""
from __future__ import annotations
from uuid import UUID
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.foundation import (
Account,
ChartOfAccounts,
CostCenter,
Currency,
FiscalPeriod,
FiscalYear,
Project,
TenantAccountingConfiguration,
)
from app.repositories.base import TenantBaseRepository
class ChartOfAccountsRepository(TenantBaseRepository[ChartOfAccounts]):
model = ChartOfAccounts
async def get_by_code(self, tenant_id: UUID, code: str) -> ChartOfAccounts | None:
stmt = select(ChartOfAccounts).where(
ChartOfAccounts.tenant_id == tenant_id,
ChartOfAccounts.code == code,
)
result = await self.session.execute(stmt)
return result.scalar_one_or_none()
class AccountRepository(TenantBaseRepository[Account]):
model = Account
async def get_by_code(self, tenant_id: UUID, code: str) -> Account | None:
stmt = select(Account).where(
Account.tenant_id == tenant_id, Account.code == code
)
result = await self.session.execute(stmt)
return result.scalar_one_or_none()
async def list_by_chart(
self, tenant_id: UUID, chart_id: UUID, *, offset: int = 0, limit: int = 100
):
stmt = (
select(Account)
.where(Account.tenant_id == tenant_id, Account.chart_id == chart_id)
.offset(offset)
.limit(limit)
)
result = await self.session.execute(stmt)
return result.scalars().all()
class CurrencyRepository(TenantBaseRepository[Currency]):
model = Currency
class FiscalYearRepository(TenantBaseRepository[FiscalYear]):
model = FiscalYear
async def get_current(self, tenant_id: UUID) -> FiscalYear | None:
stmt = select(FiscalYear).where(
FiscalYear.tenant_id == tenant_id, FiscalYear.is_current.is_(True)
)
result = await self.session.execute(stmt)
return result.scalar_one_or_none()
class FiscalPeriodRepository(TenantBaseRepository[FiscalPeriod]):
model = FiscalPeriod
async def get_current(self, tenant_id: UUID) -> FiscalPeriod | None:
stmt = select(FiscalPeriod).where(
FiscalPeriod.tenant_id == tenant_id, FiscalPeriod.is_current.is_(True)
)
result = await self.session.execute(stmt)
return result.scalar_one_or_none()
async def list_by_year(self, tenant_id: UUID, fiscal_year_id: UUID):
stmt = select(FiscalPeriod).where(
FiscalPeriod.tenant_id == tenant_id,
FiscalPeriod.fiscal_year_id == fiscal_year_id,
)
result = await self.session.execute(stmt)
return result.scalars().all()
class CostCenterRepository(TenantBaseRepository[CostCenter]):
model = CostCenter
class ProjectRepository(TenantBaseRepository[Project]):
model = Project
class TenantAccountingConfigRepository(TenantBaseRepository[TenantAccountingConfiguration]):
model = TenantAccountingConfiguration
async def get_for_tenant(self, tenant_id: UUID) -> TenantAccountingConfiguration | None:
stmt = select(TenantAccountingConfiguration).where(
TenantAccountingConfiguration.tenant_id == tenant_id
)
result = await self.session.execute(stmt)
return result.scalar_one_or_none()