"""Payment Allocation model.""" from sqlalchemy import Column from sqlalchemy import Enum from sqlalchemy import func from sqlalchemy import Integer from moneyhub.constants.constants import PaymentAllocationType from moneyhub.models.mysql_base import BaseModel from moneyhub.models.reference_adjustment_type import ReferenceAdjustmentType from moneyhub.models.worksheet_adjustment import WorksheetAdjustment class PaymentAllocation(BaseModel): """Payment Allocation model.""" __tablename__ = 'payment_allocation' payment_allocation_id = Column(Integer, nullable=False, primary_key=True) contract_id = Column(Integer, nullable=False) statement_period_id = Column(Integer, nullable=False) payment_allocation_type = Column(Enum( *PaymentAllocationType, name='payment_allocation_type', create_type=False), nullable=False ) @classmethod def get_flowthrough_details( cls, contract_ids: list[int] | None, statement_period_ids: list[int] ) -> list: """Get flowthrough details for a contract by statement periods. Args: contract_ids (list[int]): The ids of contracts statement_period_ids (list[int]): The list of statement period ids Returns: list: list of flowthrough details """ from moneyhub.models import LedgerAdjustmentApplied from moneyhub.models import PaymentAllocationLedgerAdjustment filters = [ WorksheetAdjustment.apply_to_statement_period_id.in_(statement_period_ids), cls.contract_id.in_(contract_ids), cls.payment_allocation_type == PaymentAllocationType.FLOWTHROUGH ] with_entities = [ ReferenceAdjustmentType.reference_adjustment_type_id, WorksheetAdjustment.apply_to_statement_period_id, ReferenceAdjustmentType.type_name.label('reference_adjustment_type'), func.sum(LedgerAdjustmentApplied.adjustment_amount_payee_currency).label('adjustment_amount'), # noqa: E501 LedgerAdjustmentApplied.adjustment_payee_currency_code.label('currency_code'), ] group_by = [ ReferenceAdjustmentType.reference_adjustment_type_id, WorksheetAdjustment.apply_to_statement_period_id, ReferenceAdjustmentType.type_name, LedgerAdjustmentApplied.adjustment_payee_currency_code, ] return cls.query.join( PaymentAllocationLedgerAdjustment, PaymentAllocationLedgerAdjustment.payment_allocation_id == cls.payment_allocation_id ).join( LedgerAdjustmentApplied, LedgerAdjustmentApplied.ledger_adjustment_applied_id == PaymentAllocationLedgerAdjustment.ledger_adjustment_applied_id # noqa: E501 ).join( WorksheetAdjustment, WorksheetAdjustment.worksheet_adjustment_id == LedgerAdjustmentApplied.worksheet_adjustment_id # noqa: E501 ).join( ReferenceAdjustmentType, ReferenceAdjustmentType.reference_adjustment_type_id == WorksheetAdjustment.reference_adjustment_type_id # noqa: E501 ).with_entities(*with_entities).filter(*filters).group_by(*group_by).distinct().all()