| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- from sqlalchemy import select
- from sqlalchemy.ext.asyncio import AsyncSession
- from backend.app.models.finance import CostCenter, CostCenterMember, UserWallet
- from backend.app.models.settings import Settings as AppSettingModel
- from backend.app.models.user import User
- from backend.app.schemas.settings import AppSettings as AppSettingsSchema
- async def ensure_user_finance_defaults(db: AsyncSession, user: User) -> bool:
- """Ensure wallet and private cost center defaults exist for a user.
- Returns True when database objects were created or changed.
- """
- changed = False
- wallet = (await db.execute(select(UserWallet).where(UserWallet.user_id == user.id))).scalar_one_or_none()
- if wallet is None:
- # Respect admin-configured currency if present, otherwise fall back to app default
- default_currency = AppSettingsSchema().currency
- result = await db.execute(select(AppSettingModel).where(AppSettingModel.key == "currency"))
- setting = result.scalar_one_or_none()
- currency = setting.value if setting and setting.value else default_currency
- db.add(UserWallet(user_id=user.id, balance=0.0, currency=currency))
- changed = True
- private_center = (
- (
- await db.execute(
- select(CostCenter)
- .where(
- CostCenter.is_private.is_(True),
- CostCenter.owner_user_id == user.id,
- )
- .order_by(CostCenter.id.asc())
- )
- )
- .scalars()
- .first()
- )
- if private_center is None:
- private_center = CostCenter(
- name=user.username,
- is_active=True,
- is_private=True,
- owner_user_id=user.id,
- )
- db.add(private_center)
- await db.flush()
- changed = True
- else:
- # A private center is the billing fallback for its owner and therefore
- # must remain active. A zero budget is the supported way to prevent
- # printing from it.
- if not private_center.is_active:
- private_center.is_active = True
- changed = True
- if private_center.name != user.username:
- private_center.name = user.username
- changed = True
- membership = (
- await db.execute(
- select(CostCenterMember).where(
- CostCenterMember.cost_center_id == private_center.id,
- CostCenterMember.user_id == user.id,
- )
- )
- ).scalar_one_or_none()
- if membership is None:
- db.add(CostCenterMember(cost_center_id=private_center.id, user_id=user.id, can_print=True))
- changed = True
- return changed
|