finance-watcher / api / endpoints / budget.py
budget.py
Raw
from flask import request
from flask_restx import Namespace, Resource, fields, reqparse
from database.finance_database import FinanceDatabase
from helpers.helper_functions import (
    json_success_response, json_error_response, get_string_from_date
)


namespace = Namespace(
    'budget', 
    description='API endpoints related to Budget resource'
)

budget_parser = reqparse.RequestParser()
budget_parser.add_argument('dashboard_user_id', required=True, type=int, help='id of the user')
budget_parser.add_argument('page', required=False, type=int, help='page number')

post_payload = namespace.model("Payload", {
    "dashboard_user_id": fields.Integer(required=True, description='id of the user'),
    "name": fields.String(required=True, description='name of the budget'),
    "amount": fields.Integer(required=True, description='amount of the budget'),
    "business_type_id": fields.String(required=True, description='id of the business type'),
})


patch_payload = namespace.model("Payload", {
    "budget_id": fields.Integer(required=True, description='id of the budget'),
    "name": fields.String(required=False, description='new name to update to'),
    "amount": fields.Integer(required=False, description='new amount to update to'),
    "business_type_id": fields.String(required=False, description='new business type to update to'),
})


delete_payload = namespace.model("Payload", {
    "dashboard_user_id": fields.Integer(required=True, description='id of the user'),
    "name": fields.String(required=True, description='name of the budget')
})


@namespace.route('')
class BudgetAPI(Resource):
    """
    API for the Budget resource
    """

    @namespace.expect(budget_parser)
    def get(self):
        """
        Gets the Budget resource by User ID.
        """
        args = budget_parser.parse_args()

        user_id= args['dashboard_user_id']
        page = args.get('page')
        if page is None:
            page = 1

        finance_db = FinanceDatabase()

        budgets = finance_db.get_budgets(
            dashboard_user_id=user_id,
            page=page
        )
    
        if budgets is None:
            return json_error_response(
                f'ERROR: Failed to get budgets of User {user_id}.'
            )
        
        return json_success_response([
            {
                'id': budget.id,
                'name': budget.name,
                'business_type_id': budget.business_type_id,
                'created_date': get_string_from_date(budget.created_date),
                'updated_date': get_string_from_date(budget.updated_date) if budget.updated_date else 'null'
            }
            for budget in budgets
        ])
    
    @namespace.expect(post_payload)
    def post(self):
        """
        Creates a Budget resource.
        """
        payload = request.json

        finance_db = FinanceDatabase()
        budget = finance_db.create_budget(
            dashboard_user_id=payload['dashboard_user_id'],
            name=payload['name'],
            amount=payload['amount'],
            business_type_id=payload['business_type_id']
        )

        if budget is None:
            return json_error_response(
                'ERROR: Failed to create budget.'
            )
        
        return json_success_response(
            {
                'id': budget.id,
                'name': budget.name,
                'business_type_id': budget.business_type_id,
                'created_date': get_string_from_date(budget.created_date),
                'updated_date': get_string_from_date(budget.updated_date) if budget.updated_date else 'null'
            }
        )
    
    @namespace.expect(patch_payload)
    def patch(self):
        """
        Updates a Budget resource.
        """
        payload = request.json

        finance_db = FinanceDatabase()
        is_success = finance_db.update_budget(
            budget_id=payload['budget_id'],
            name=payload['name'],
            amount=payload.get('amount'),
            business_type_id=payload.get('business_type_id')
        )

        if not is_success:
            return json_error_response(
                'ERROR: Failed to update budget.'
            )
    
        return json_success_response()

    
    @namespace.expect(delete_payload)
    def delete(self):
        """
        Deletes a Budget resource.
        """
        payload = request.json

        finance_db = FinanceDatabase()
        is_success = finance_db.delete_budget(
            dashboard_user_id=payload['dashboard_user_id'],
            name=payload['name']
        )

        if not is_success:
            return json_error_response(
                'ERROR: Failed to delete budget.'
            )
    
        return json_success_response()