hesabixArc/hesabixAPI/app/services/account_service.py
2025-10-31 18:02:23 +00:00

107 lines
2.5 KiB
Python

from __future__ import annotations
from typing import Any, Dict, Optional
from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm import Session
from adapters.db.models.account import Account
def account_to_dict(obj: Account) -> Dict[str, Any]:
return {
"id": obj.id,
"name": obj.name,
"code": obj.code,
"account_type": obj.account_type,
"parent_id": obj.parent_id,
"business_id": obj.business_id,
"created_at": obj.created_at,
"updated_at": obj.updated_at,
}
def _validate_parent(db: Session, parent_id: Optional[int], business_id: Optional[int]) -> Optional[int]:
if parent_id is None:
return None
parent = db.get(Account, parent_id)
if not parent:
raise ValueError("PARENT_NOT_FOUND")
# والد باید عمومی یا متعلق به همان کسب‌وکار باشد
if parent.business_id is not None and parent.business_id != business_id:
raise ValueError("INVALID_PARENT_BUSINESS")
return parent.id
def create_account(
db: Session,
*,
name: str,
code: str,
account_type: str,
business_id: Optional[int],
parent_id: Optional[int] = None,
) -> Dict[str, Any]:
parent_id = _validate_parent(db, parent_id, business_id)
obj = Account(
name=name,
code=code,
account_type=account_type,
business_id=business_id,
parent_id=parent_id,
)
db.add(obj)
try:
db.commit()
except IntegrityError as e:
db.rollback()
raise ValueError("ACCOUNT_CODE_NOT_UNIQUE") from e
db.refresh(obj)
return account_to_dict(obj)
def update_account(
db: Session,
account_id: int,
*,
name: Optional[str] = None,
code: Optional[str] = None,
account_type: Optional[str] = None,
parent_id: Optional[int] = None,
) -> Optional[Dict[str, Any]]:
obj = db.get(Account, account_id)
if not obj:
return None
if parent_id is not None:
parent_id = _validate_parent(db, parent_id, obj.business_id)
if name is not None:
obj.name = name
if code is not None:
obj.code = code
if account_type is not None:
obj.account_type = account_type
obj.parent_id = parent_id if parent_id is not None else obj.parent_id
try:
db.commit()
except IntegrityError as e:
db.rollback()
raise ValueError("ACCOUNT_CODE_NOT_UNIQUE") from e
db.refresh(obj)
return account_to_dict(obj)
def delete_account(db: Session, account_id: int) -> bool:
obj = db.get(Account, account_id)
if not obj:
return False
db.delete(obj)
db.commit()
return True
def get_account(db: Session, account_id: int) -> Optional[Dict[str, Any]]:
obj = db.get(Account, account_id)
return account_to_dict(obj) if obj else None