finance_defaults.py 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. from sqlalchemy import select
  2. from sqlalchemy.ext.asyncio import AsyncSession
  3. from backend.app.models.finance import CostCenter, CostCenterMember, UserWallet
  4. from backend.app.models.user import User
  5. async def ensure_user_finance_defaults(db: AsyncSession, user: User) -> bool:
  6. """Ensure wallet and private cost center defaults exist for a user.
  7. Returns True when database objects were created or changed.
  8. """
  9. changed = False
  10. wallet = (await db.execute(select(UserWallet).where(UserWallet.user_id == user.id))).scalar_one_or_none()
  11. if wallet is None:
  12. db.add(UserWallet(user_id=user.id, balance=0.0))
  13. changed = True
  14. private_center = (
  15. (
  16. await db.execute(
  17. select(CostCenter)
  18. .where(
  19. CostCenter.is_private.is_(True),
  20. CostCenter.owner_user_id == user.id,
  21. )
  22. .order_by(CostCenter.id.asc())
  23. )
  24. )
  25. .scalars()
  26. .first()
  27. )
  28. if private_center is None:
  29. private_center = CostCenter(
  30. name=user.username,
  31. is_active=True,
  32. is_private=True,
  33. owner_user_id=user.id,
  34. )
  35. db.add(private_center)
  36. await db.flush()
  37. changed = True
  38. else:
  39. # A private center is the billing fallback for its owner and therefore
  40. # must remain active. A zero budget is the supported way to prevent
  41. # printing from it.
  42. if not private_center.is_active:
  43. private_center.is_active = True
  44. changed = True
  45. if private_center.name != user.username:
  46. private_center.name = user.username
  47. changed = True
  48. membership = (
  49. await db.execute(
  50. select(CostCenterMember).where(
  51. CostCenterMember.cost_center_id == private_center.id,
  52. CostCenterMember.user_id == user.id,
  53. )
  54. )
  55. ).scalar_one_or_none()
  56. if membership is None:
  57. db.add(CostCenterMember(cost_center_id=private_center.id, user_id=user.id, can_print=True))
  58. changed = True
  59. return changed