"""Expense Handler.""" from ddtrace import tracer from fastapi import APIRouter from moneyhub.constants.constants import GroupBy from moneyhub.constants.constants import ONE_MONTH from moneyhub.logic import ledger_adjustment as logic from moneyhub.schemas.ledger_adjustment import ExpenseSchema from moneyhub.schemas.ledger_adjustment import ExpenseSubaccountSchema from moneyhub.schemas.ledger_adjustment import LedgerAdjustmentExpenseArtistSchema from moneyhub.schemas.ledger_adjustment import LedgerAdjustmentExpenseSchema from moneyhub.schemas.ledger_adjustment import LedgerAdjustmentExpenseUPCsSchema from moneyhub.schemas.ledger_adjustment import PaginatedExpenseSchema from moneyhub.schemas.reference_adjustment_type import ReferenceAdjustmentType from moneyhub.utils.cache import cache expenses_router = APIRouter(prefix='/expenses', tags=['expenses']) @expenses_router.get( '/account/{account_id}', status_code=200 ) def get_expenses_by_account_id( account_id: int, limit: int | None = None, offset: int | None = None, contract_id: int | None = None, statement_period_id_start: int | None = None, statement_period_id_end: int | None = None, upc: str | None = None, expense_type_id: int | None = None, distribution_type: str | None = None, artist_id: int | None = None, subaccount_id: int | None = None, group_by: GroupBy | None = None ) -> PaginatedExpenseSchema | list[ExpenseSchema]: """GET ledger adjustments expenses for a specified account. Args: account_id (int): ID of the account limit (int): how many entities to retrieve. offset (int): the offset (for pagination). contract_id (int): ID of the contract to get expenses for statement_period_id_start (int): Start of the period range statement_period_id_end (int): End of the period range upc (str): UPC to filter expenses by expense_type_id (int): Expense type to filter expenses by distribution_type (str): Distribution type to filter expenses by artist_id (int): Artist id to filter expenses by subaccount_id (int): Subaccount id to filter by group_by (str): Optional dimension to group expenses by Returns: list: list of ledger adjustments expenses """ return logic.get_expenses_by_account_id( account_id, limit, offset, contract_id, statement_period_id_start, statement_period_id_end, upc, expense_type_id, distribution_type, artist_id, subaccount_id, group_by ) @expenses_router.get( '/account/{account_id}/artists', status_code=200 ) def get_expenses_artists_by_account_id( account_id: int ) -> list[LedgerAdjustmentExpenseArtistSchema]: """GET associated artists for expenses for a given account. Args: account_id (int): ID of an account Returns: list: list of artists """ return logic.get_expenses_artists_by_account_id(account_id) @expenses_router.get( '/account/{account_id}/upcs', status_code=200 ) @cache(ttl=ONE_MONTH) @tracer.wrap('tracing expenses by upcs endpoint') def get_expenses_upcs_by_account_id(account_id: int) -> list[LedgerAdjustmentExpenseUPCsSchema]: """GET associated UPCs for expenses for a given account. Args: account_id (int): ID of an account Returns: list: list of UPCs """ return logic.get_expenses_upcs_by_account_id(account_id) @expenses_router.get( '/account/{account_id}/types', status_code=200 ) def get_expenses_types_by_account_id(account_id: int) -> list[ReferenceAdjustmentType]: """GET associated expenses types for expenses for a given account. Args: account_id (int): ID of an account Returns: list: list of expenses types """ return logic.get_expenses_types_by_account_id(account_id) @expenses_router.get( '/account/{account_id}/subaccounts', status_code=200 ) def get_expenses_subaccounts_by_account_id(account_id: int) -> list[ExpenseSubaccountSchema]: """GET associated expenses subaccounts for expenses for a given account. Args: account_id (int): ID of an account Returns: list: list of expenses subaccounts """ return logic.get_expenses_subaccounts_by_account_id(account_id) @expenses_router.get( '/account/{account_id}/statement-period/{statement_period_id}', status_code=200 ) def get_expenses_by_account_and_statement_period( account_id: int, statement_period_id: int, contract_id: int | None = None ) -> LedgerAdjustmentExpenseSchema | None: """GET aggregated expenses for a specified account. Args: account_id (int): The id of an account statement_period_id (int): The id of the statement period contract_id (int): the id of a contract Returns: LedgerAdjustmentExpenseSchema: Aggregated expenses """ result = logic.get_expenses_by_account_and_statement_periods( account_id, [statement_period_id], contract_id ) return result[0] if result else None