"""Payment Allocation repository.""" from abacus_common_logic.connectors.database import db from abacus_common_logic.utils.users import get_flask_user_id from sqlalchemy import select, update from payment.constants.constants import ( PAYMENT_ALLOCATION_LEDGER_STATUSES, PAYMENT_ALLOCATION_STATUSES, ) from payment.models.payment_allocation import PaymentAllocationFlowthrough from payment.models.payment_group_payment_account import ( PaymentGroupPaymentAccount, ) from payment.models.payment_group_payment_account_detail import ( PaymentGroupPaymentAccountDetail, ) def _reset_allocations_to_init(contract_ids_subquery, commit: bool = True) -> int: """Reset flowthrough allocations to init status for given contract IDs. Resets all active flowthrough allocations that are in ATTACHED_TO_PAYMENT status for the provided contract IDs subquery. Args: contract_ids_subquery: Subquery that returns contract IDs commit: Whether to commit the transaction (default: True) Returns: Number of records updated """ result = db.session.execute( update(PaymentAllocationFlowthrough) .where( PaymentAllocationFlowthrough.deleted_at.is_(None), PaymentAllocationFlowthrough.contract_id.in_(contract_ids_subquery), PaymentAllocationFlowthrough.payment_status == PAYMENT_ALLOCATION_STATUSES.ATTACHED_TO_PAYMENT, ) .values( payment_status=PAYMENT_ALLOCATION_STATUSES.INIT, payment_status_modified=PaymentAllocationFlowthrough.current_timestamp(), ledger_status=PAYMENT_ALLOCATION_LEDGER_STATUSES.INIT, ledger_status_modified=PaymentAllocationFlowthrough.current_timestamp(), last_modified=PaymentAllocationFlowthrough.current_timestamp(), last_modified_by=get_flask_user_id(), ) .execution_options(synchronize_session=False) ) if commit: db.session.commit() return result.rowcount def reset_to_init_by_payment_group_payment( payment_group_payment_id: int, commit: bool = True ) -> int: """Reset flowthrough allocations to init status by payment group payment ID. Resets all active flowthrough allocations that are in ATTACHED_TO_PAYMENT status for contracts associated with the given payment group payment. Args: payment_group_payment_id: ID of the payment group payment commit: Whether to commit the transaction (default: True) Returns: Number of records updated """ contract_ids_subquery = ( select(PaymentGroupPaymentAccountDetail.contract_id) .where( PaymentGroupPaymentAccountDetail.deleted_at.is_(None), PaymentGroupPaymentAccountDetail.payment_group_payment_account_id.in_( select( PaymentGroupPaymentAccount.payment_group_payment_account_id ).where( PaymentGroupPaymentAccount.payment_group_payment_id == payment_group_payment_id, PaymentGroupPaymentAccount.deleted_at.is_(None), ) ), ) .distinct() ) return _reset_allocations_to_init(contract_ids_subquery, commit) def reset_to_init_by_payment_group_payment_account( payment_group_payment_account_id: int, commit: bool = True ) -> int: """Reset flowthrough allocations to init status by payment group payment account ID. Resets all active flowthrough allocations that are in ATTACHED_TO_PAYMENT status for contracts associated with the given payment group payment account. Args: payment_group_payment_account_id: ID of the payment group payment account commit: Whether to commit the transaction (default: True) Returns: Number of records updated """ contract_ids_subquery = ( select(PaymentGroupPaymentAccountDetail.contract_id) .where( PaymentGroupPaymentAccountDetail.deleted_at.is_(None), PaymentGroupPaymentAccountDetail.payment_group_payment_account_id == payment_group_payment_account_id, ) .distinct() ) return _reset_allocations_to_init(contract_ids_subquery, commit)