"""Pydantic Model For Revenue Analysis.""" from pydantic import BaseModel from pydantic import ConfigDict from pydantic import field_validator from moneyhub.constants.constants import ORDER_BY_PROJECT_ID from moneyhub.constants.constants import OrderDirection from moneyhub.schemas import PaginationSchema class RevenueByProductSchema(BaseModel): """Revenue aggregated by product.""" product_id: int account_payee_currency: str project_name: str | None = None net_share_payee_currency: float | None = None mechanical_deduction_amount_payee_currency: float publisher_admin_fee_payee_currency: float gross_revenue_payee_currency: float subaccount_revenue: float | None = None model_config = ConfigDict(from_attributes=True) class PaginatedRevenueByProductSchema(BaseModel): """Revenue aggregated by product with pagination.""" items: list[RevenueByProductSchema] pagination: PaginationSchema class RevenueByStatementPeriodSchema(BaseModel): """Revenue aggregated by statement period.""" statement_period_id: int account_payee_currency: str net_revenue_payee_currency: float | None = None gross_revenue_payee_currency: float | None = None net_publishing_revenue_payee_currency: float | None = None gross_publishing_revenue_payee_currency: float | None = None subaccount_revenue: float | None = None model_config = ConfigDict(from_attributes=True) class RevenueByTrackSchema(BaseModel): """Revenue aggregated by track.""" account_id: int contract_id: int | None = None subaccount_id: int | None = None track_unique_id: int track_name: str | None = None isrc: str account_payee_currency: str project_name: str | None = None mechanical_deduction_amount_payee_currency: float publisher_admin_fee_payee_currency: float net_revenue_payee_currency: float gross_revenue_payee_currency: float subaccount_revenue: float | None = None model_config = ConfigDict(from_attributes=True) class PaginatedRevenueByTrackSchema(BaseModel): """Revenue aggregated by track with pagination.""" items: list[RevenueByTrackSchema] pagination: PaginationSchema class RevenueByArtistSchema(BaseModel): """Revenue aggregated by artist.""" account_id: int contract_id: int | None = None subaccount_id: int | None = None artist_id: int artist_name: str account_payee_currency: str mechanical_deduction_amount_payee_currency: float publisher_admin_fee_payee_currency: float net_revenue_payee_currency: float gross_revenue_payee_currency: float subaccount_revenue: float | None = None model_config = ConfigDict(from_attributes=True) class PaginatedRevenueByArtistSchema(BaseModel): """Revenue aggregated by artist with pagination.""" items: list[RevenueByArtistSchema] pagination: PaginationSchema class RevenueBySubaccountSchema(BaseModel): """Revenue aggregated by subacount.""" account_id: int contract_id: int | None = None subaccount_id: int subaccount_name: str account_payee_currency: str mechanical_deduction_amount_payee_currency: float publisher_admin_fee_payee_currency: float net_revenue_payee_currency: float gross_revenue_payee_currency: float model_config = ConfigDict(from_attributes=True) class PaginatedRevenueBySubaccountSchema(BaseModel): """Revenue aggregated by subaccount with pagination.""" items: list[RevenueBySubaccountSchema] pagination: PaginationSchema class RevenueByRecordingSchema(BaseModel): """Revenue aggregated by recording.""" recording_id: str recording_title: str artist: str version: str | None = None isrc: str | None = None account_id: int contract_id: int | None = None account_payee_currency: str net_share_payee_currency: float gross_revenue_payee_currency: float model_config = ConfigDict(from_attributes=True) @field_validator('recording_id', mode='before') @classmethod def validate_string(cls, value: str | int) -> str: """Ensure that the value is a string, converting if need be. Args: value (str | int): Value to validate Returns: str: String value """ return str(value) class RevenueByStoreSchema(BaseModel): """Revenue aggregated by store.""" store_id: int store_name: str account_payee_currency: str net_revenue_payee_currency: float | None = None gross_revenue_payee_currency: float | None = None subaccount_revenue: float | None = None model_config = ConfigDict(from_attributes=True) class StoreSchema(BaseModel): """Store schema.""" store_id: int store_name: str model_config = ConfigDict(from_attributes=True) class RevenueByImprintSchema(BaseModel): """Revenue aggregated by imprint.""" account_id: int contract_id: int | None = None imprintid: int imprint: str account_payee_currency: str net_share_payee_currency: float | None = None mechanical_deduction_amount_payee_currency: float publisher_admin_fee_payee_currency: float gross_revenue_payee_currency: float subaccount_id: int | None = None subaccount_revenue: float | None = None model_config = ConfigDict(from_attributes=True) class RevenuePayeeCurrencyTotalsSchema(BaseModel): """Revenue payee currency totals.""" net_revenue_payee_currency: float | None = None gross_revenue_payee_currency: float | None = None subaccount_revenue: float | None = None class PaginatedRevenueByStoreSchema(BaseModel): """Revenue aggregated by recording with pagination.""" items: list[RevenueByStoreSchema] totals: RevenuePayeeCurrencyTotalsSchema pagination: PaginationSchema class RevenueByProjectSchema(BaseModel): """Revenue aggregated by project.""" project_id: int project_name: str | None = None project_code: str | None = None project_artist: str | None = None product_count: int account_payee_currency: str net_share_payee_currency: float | None = None gross_revenue_payee_currency: float | None = None subaccount_revenue: float | None = None model_config = ConfigDict(from_attributes=True) class PaginatedRevenueByProjectSchema(BaseModel): """Revenue aggregated by project with pagination.""" items: list[RevenueByProjectSchema] pagination: PaginationSchema class RevenueByProjectRequestSchema(BaseModel): """Request body for revenue by project endpoint.""" limit: int = 50 offset: int = 0 contract_id: int | None = None subaccount_id: int | None = None statement_period_id_start: int | None = None statement_period_id_end: int | None = None order_by: str | None = ORDER_BY_PROJECT_ID order_dir: OrderDirection = OrderDirection.DESC search_term: str | None = None is_subaccount: bool = False activity_period_id_start: int | None = None activity_period_id_end: int | None = None store_ids: list[int] | None = None country_codes: list[str] | None = None imprint_ids: list[int] | None = None transaction_type_ids: list[int] | None = None class PaginatedRevenueByRecordingSchema(BaseModel): """Revenue aggregated by recording with pagination.""" items: list[RevenueByRecordingSchema] pagination: PaginationSchema class PaginatedRevenueByImprintSchema(BaseModel): """Revenue aggregated by imprint with pagination.""" items: list[RevenueByImprintSchema] pagination: PaginationSchema class AccountRevenueSchema(BaseModel): """Account total revenue response.""" since_statement_period_id: int | None = None currency_code: str | None = None gross_revenue_payee_currency: float | None = None net_revenue_payee_currency: float | None = None subaccount_revenue: float | None = None model_config = ConfigDict(from_attributes=True) class AccountStatementPeriodRevenueSchema(BaseModel): """Account statement period revenue response.""" currency_code: str gross_revenue_payee_currency: float | None = None net_revenue_payee_currency: float | None = None gross_publishing_revenue_payee_currency: float | None = None net_publishing_revenue_payee_currency: float | None = None statement_period_id: int subaccount_revenue: float | None = None model_config = ConfigDict(from_attributes=True) class RevenueByCountrySchema(BaseModel): """Revenue aggregated by country.""" account_id: int account_payee_currency: str country_code: str net_revenue_payee_currency: float gross_revenue_payee_currency: float subaccount_revenue: float | None = None model_config = ConfigDict(from_attributes=True) class RevenueByTransactionTypeSchema(BaseModel): """Revenue aggregated by transaction type.""" account_payee_currency: str transaction_type_id: int transaction_type_desc: str transaction_type_group_name: str quantity: int net_revenue_payee_currency: float gross_revenue_payee_currency: float subaccount_revenue: float | None = None model_config = ConfigDict(from_attributes=True) class TransactionTypeSchema(BaseModel): """Transaction type schema.""" transaction_type_id: int transaction_type_desc: str transaction_type_group_name: str class ResponseRevenueByTransactionTypeSchema(BaseModel): """Response model for aggregated revenue by transaction type.""" items: list[RevenueByTransactionTypeSchema] totals: RevenuePayeeCurrencyTotalsSchema class RevenueByActivityMonthSchema(BaseModel): """Revenue aggregated by activity month.""" account_payee_currency: str activity_month_name: str activity_period_id: int net_share_payee_currency: float | None = None gross_revenue_payee_currency: float | None = None net_publishing_revenue_payee_currency: float | None = None gross_publishing_revenue_payee_currency: float | None = None subaccount_revenue: float | None = None model_config = ConfigDict(from_attributes=True) class PaginatedRevenueByActivityMonthSchema(BaseModel): """Revenue aggregated by activity month with pagination.""" items: list[RevenueByActivityMonthSchema] pagination: PaginationSchema