"""Transaction service""" from typing import Optional, List from datetime import datetime, timedelta from sqlalchemy.orm import Session from app.db.repositories import TransactionRepository, AccountRepository, BudgetRepository from app.db.models import Transaction, TransactionType from app.schemas import TransactionCreateSchema class TransactionService: """Service for transaction operations""" def __init__(self, session: Session): self.session = session self.transaction_repo = TransactionRepository(session) self.account_repo = AccountRepository(session) self.budget_repo = BudgetRepository(session) def create_transaction( self, family_id: int, user_id: int, account_id: int, data: TransactionCreateSchema, ) -> Transaction: """Create new transaction and update account balance""" # Create transaction transaction = self.transaction_repo.create( family_id=family_id, user_id=user_id, account_id=account_id, amount=data.amount, transaction_type=data.transaction_type, description=data.description, notes=data.notes, tags=data.tags, category_id=data.category_id, receipt_photo_url=data.receipt_photo_url, transaction_date=data.transaction_date, ) # Update account balance if data.transaction_type == TransactionType.EXPENSE: self.account_repo.update_balance(account_id, -data.amount) elif data.transaction_type == TransactionType.INCOME: self.account_repo.update_balance(account_id, data.amount) # Update budget if expense if ( data.transaction_type == TransactionType.EXPENSE and data.category_id ): budget = self.budget_repo.get_category_budget(family_id, data.category_id) if budget: self.budget_repo.update_spent_amount(budget.id, data.amount) return transaction def get_family_summary(self, family_id: int, days: int = 30) -> dict: """Get financial summary for family""" end_date = datetime.utcnow() start_date = end_date - timedelta(days=days) transactions = self.transaction_repo.get_transactions_by_period( family_id, start_date, end_date ) income = sum(t.amount for t in transactions if t.transaction_type == TransactionType.INCOME) expenses = sum(t.amount for t in transactions if t.transaction_type == TransactionType.EXPENSE) net = income - expenses return { "period_days": days, "income": income, "expenses": expenses, "net": net, "average_daily_expense": expenses / days if days > 0 else 0, "transaction_count": len(transactions), } def delete_transaction(self, transaction_id: int) -> bool: """Delete transaction and rollback balance""" transaction = self.transaction_repo.get_by_id(transaction_id) if transaction: # Rollback balance if transaction.transaction_type == TransactionType.EXPENSE: self.account_repo.update_balance(transaction.account_id, transaction.amount) elif transaction.transaction_type == TransactionType.INCOME: self.account_repo.update_balance(transaction.account_id, -transaction.amount) # Delete transaction return self.transaction_repo.delete(transaction_id) return False