"""Statement Period Payment Entity model.""" from sqlalchemy import Column from sqlalchemy import ForeignKey from sqlalchemy import Integer from sqlalchemy import or_ from sqlalchemy.sql import literal_column from sqlalchemy.sql import table from moneyhub.constants.constants import StatementPeriodStatus from moneyhub.models.account_payment_term import AccountPaymentTerm from moneyhub.models.mysql_base import BaseModel from moneyhub.models.statement_period import StatementPeriod class StatementPeriodPaymentEntity(BaseModel): """Statement Period Payment Entity model.""" __tablename__ = 'statement_period_payment_entity' statement_period_payment_entity_id = Column(Integer, primary_key=True) statement_period_id = Column( Integer, ForeignKey(StatementPeriod.statement_period_id), nullable=False ) is_visible_to_customer = Column(Integer, nullable=False) reference_payment_entity_id = Column(Integer, nullable=False) @classmethod def get_for_account_and_statement_period( cls, account_id: int, statement_period_id: int ) -> dict: """Get an entity based on an account and statement period ID. Args: account_id (int): Account to get the entity for. statement_period_id (int): Statement period to get the entity for. Returns: StatementPeriodPaymentEntity: Payment entity. """ filter_condition = \ [literal_column('account_payment_term.payment_entity_id') == cls.reference_payment_entity_id] # noqa: E501 return cls.query\ .join( table('account_payment_term'), *filter_condition )\ .filter( cls.statement_period_id == statement_period_id, literal_column('account_payment_term.account_id') == account_id )\ .first() @classmethod def get_visible_statement_period_ids( cls, account_id: int) -> list: """Get a list of statement period IDs that are visible to the specified account. Args: account_id (int): Account to get statement periods for. Returns: list: List of statement period IDs. """ filter_condition = \ [literal_column('account_payment_term.payment_entity_id') == cls.reference_payment_entity_id] # noqa: E501 visible_query = cls.query \ .with_entities(StatementPeriodPaymentEntity.statement_period_id) \ .join( table('account_payment_term'), *filter_condition )\ .filter( literal_column('account_payment_term.account_id') == account_id, StatementPeriodPaymentEntity.is_visible_to_customer == 1 )\ statement_period_query = StatementPeriod.query \ .with_entities(StatementPeriod.statement_period_id) \ .filter(StatementPeriod.statement_period_status == StatementPeriodStatus.CLOSED) results = visible_query.union_all(statement_period_query).distinct() return sorted([item.statement_period_id for item in results]) @classmethod def is_statement_period_visible( cls, account_id: int, statement_period_id: int) -> bool: """Return True if statement period ID is visible to the specified account. Args: account_id (int): Account to check if statement periods is visible. statement_period_id (int): ID of statement period. Returns: bool: True or False. """ filter_condition = [ AccountPaymentTerm.account_id == account_id, or_( cls.is_visible_to_customer == 1, StatementPeriod.statement_period_status == StatementPeriodStatus.CLOSED, ), ] return bool( cls.query.with_entities(cls.statement_period_id) .join( AccountPaymentTerm, AccountPaymentTerm.payment_entity_id == cls.reference_payment_entity_id, ) .join( StatementPeriod, StatementPeriod.statement_period_id == statement_period_id ).filter(*filter_condition).first())