finance-watcher / api / endpoints / business.py
business.py
Raw
from pathlib import Path
import sys

sys.path.append(str(Path(__file__).parent.parent.parent))

from flask import request
from flask_restx import Namespace, Resource, fields
from finance_watcher_dataclasses.enums import BusinessTypeEnum
from database.finance_database import FinanceDatabase

from helpers.helper_functions import json_success_response, json_error_response

namespace = Namespace(
    'business', 
    description='API endpoints related to Business resource'
)


business_payload = namespace.model("Payload", {
    "businesses": fields.List(fields.Nested(namespace.model("data", {
    "name": fields.String(required=True, description="name of the business"),
    "business_type_id": fields.Integer(
        required=True, description="id of the business type"
    )
    })), required=True, description="list of names and corresponding business types")
})
@namespace.route('')
@namespace.expect(business_payload)
class BusinessAPI(Resource):
    """
    API for the Business resource.
    """
    def post(self):
        """
        Inserts multiple businesses into the database.
        Returns the inserted businesses if successful.

        Expected payload:
        {
            "businesses": [
                {
                    "name": str,
                    "business_type_id": int
                }
            ]
        }
        """
        payload = request.json

        businesses_info = payload.get('businesses')

        if businesses_info is None:
            return json_error_response(
                "ERROR: 'businesses' was not included in the payload."
            )

        business_name_type_id = {}

        try: 
            for info in businesses_info:
                name = info['name']
                type_id = info['business_type_id']
                business_name_type_id[name] = type_id
        except:
            return json_error_response(
                "ERROR: Missing 'name' or 'business_type_id'."
            )

        finance_db = FinanceDatabase()
        businesses_inserted = finance_db.insert_businesses(
            business_name_type_id
        )

        if businesses_inserted is None:
            return json_error_response(
                'ERROR: Failed to insert businesses into the database.'
            )

        values_to_return = [
            {
                'id': business.id,
                'name': business.name,
                'business_type_id': business.business_type_id
            }
            for business in businesses_inserted
        ]

        return json_success_response(values_to_return)


@namespace.route('/type')
class BusinessTypeAPI(Resource):
    """
    API for the Business Type Resource
    """
    def post(self):
        """
        Insert default Business Types.
        """
        try:
            finance_db = FinanceDatabase()
            finance_db.insert_default_business_types()

            return json_success_response()
        except:
            return json_error_response(
                "ERROR: Failed to insert the default business types."
            )


@namespace.route('/type/<string:name>')
class BusinessTypeByNameAPI(Resource):
    """
    API for the Business Type resource by name.
    """
    def get(self, name: str):
        """
        Gets the Business Type based on the name given.

        :param name: Name of the Business Type
        """
        try:
            finance_db = FinanceDatabase()

            business_type_enum = BusinessTypeEnum.get_business_type_from_str(
                name
            )

            business_type = finance_db.get_business_type(business_type_enum)

            return json_success_response(
                {
                    'id': business_type.id,
                    'name': business_type.name
                }
            )
        except Exception:
            return json_error_response('Business Type does not exist.')