feat: additional expenses
This commit is contained in:
		
							
								
								
									
										85
									
								
								services/expenses.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								services/expenses.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,85 @@
 | 
			
		||||
from datetime import datetime
 | 
			
		||||
from typing import Optional
 | 
			
		||||
 | 
			
		||||
import math
 | 
			
		||||
from fastapi import HTTPException
 | 
			
		||||
from sqlalchemy import delete, select, func
 | 
			
		||||
from fastapi import status
 | 
			
		||||
 | 
			
		||||
from models import User
 | 
			
		||||
from models.expense import Expense
 | 
			
		||||
from schemas.base import PaginationSchema, PaginationInfoSchema
 | 
			
		||||
from schemas.expense import UpdateExpenseResponse, UpdateExpenseRequest, DeleteExpenseResponse, GetAllExpensesResponse
 | 
			
		||||
from services.base import BaseService
 | 
			
		||||
from utils.dependecies import is_valid_pagination
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ExpensesService(BaseService):
 | 
			
		||||
    async def get_all(self, pagination: PaginationSchema) -> GetAllExpensesResponse:
 | 
			
		||||
        if not is_valid_pagination(pagination):
 | 
			
		||||
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='Invalid pagination')
 | 
			
		||||
        page = max(0, pagination.page - 1)
 | 
			
		||||
 | 
			
		||||
        stmt = (
 | 
			
		||||
            select(Expense)
 | 
			
		||||
            .order_by(Expense.spent_date.desc())
 | 
			
		||||
            .offset(page * pagination.items_per_page)
 | 
			
		||||
            .limit(pagination.items_per_page)
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        total_records = await self.session.scalar(select(func.count()).select_from(Expense))
 | 
			
		||||
        if not total_records:
 | 
			
		||||
            return GetAllExpensesResponse(
 | 
			
		||||
                expenses=[],
 | 
			
		||||
                pagination_info=PaginationInfoSchema()
 | 
			
		||||
            )
 | 
			
		||||
        total_items = total_records
 | 
			
		||||
        total_pages = math.ceil(total_records / pagination.items_per_page)
 | 
			
		||||
 | 
			
		||||
        expenses = await self.session.execute(stmt)
 | 
			
		||||
        expenses = expenses.scalars().all()
 | 
			
		||||
        response = GetAllExpensesResponse(
 | 
			
		||||
            expenses=expenses,
 | 
			
		||||
            pagination_info=PaginationInfoSchema(
 | 
			
		||||
                total_items=total_items,
 | 
			
		||||
                total_pages=total_pages
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
        return response
 | 
			
		||||
 | 
			
		||||
    async def get_by_id(self, expense_id) -> Optional[Expense]:
 | 
			
		||||
        expense = await self.session.get(Expense, expense_id)
 | 
			
		||||
        return expense
 | 
			
		||||
 | 
			
		||||
    async def update_expense(self, user: User, request: UpdateExpenseRequest) -> UpdateExpenseResponse:
 | 
			
		||||
        expense = await self.get_by_id(request.expense.id)
 | 
			
		||||
 | 
			
		||||
        if not expense:
 | 
			
		||||
            expense = Expense(
 | 
			
		||||
                created_at=datetime.now(),
 | 
			
		||||
                name=request.expense.name,
 | 
			
		||||
                comment=request.expense.comment,
 | 
			
		||||
                amount=request.expense.amount,
 | 
			
		||||
                spent_date=request.expense.spent_date,
 | 
			
		||||
                created_by_user_id=user.id,
 | 
			
		||||
            )
 | 
			
		||||
            self.session.add(expense)
 | 
			
		||||
            await self.session.commit()
 | 
			
		||||
            return UpdateExpenseResponse(ok=True, message='Запись о расходах успешно создана')
 | 
			
		||||
 | 
			
		||||
        expense.name = request.expense.name
 | 
			
		||||
        expense.amount = request.expense.amount
 | 
			
		||||
        expense.comment = request.expense.comment
 | 
			
		||||
        expense.spent_date = request.expense.spent_date
 | 
			
		||||
        self.session.add(expense)
 | 
			
		||||
        await self.session.commit()
 | 
			
		||||
        return UpdateExpenseResponse(ok=True, message='Запись о расходах успешно изменена')
 | 
			
		||||
 | 
			
		||||
    async def delete_expense(self, expense_id) -> DeleteExpenseResponse:
 | 
			
		||||
        stmt = (
 | 
			
		||||
            delete(Expense)
 | 
			
		||||
            .where(Expense.id == expense_id)
 | 
			
		||||
        )
 | 
			
		||||
        await self.session.execute(stmt)
 | 
			
		||||
        await self.session.commit()
 | 
			
		||||
        return DeleteExpenseResponse(ok=True, message='Запись о расходах успешно удалена')
 | 
			
		||||
		Reference in New Issue
	
	Block a user