"""Account search logic.""" from typing import Any, Tuple, Union from urllib.parse import unquote from owsresponse import response from sqlalchemy.orm import joinedload from werkzeug.datastructures import ImmutableMultiDict from abacus_account.constants.constants import DEFAULT_PAGE_LIMIT, DEFAULT_PAGE_OFFSET from abacus_account.models.account import Account from abacus_account.schemas.account import AccountDetail, AccountDetailSchema account_detail_schema = AccountDetailSchema() account_model = Account() def get_accounts(params): """Search accounts by params.""" accounts_by_params, total_count = _execute_account_query(params) account_list = account_detail_schema.dump(accounts_by_params, many=True) return response.Response({'items': account_list, 'total_count': total_count}) def get_accounts_by_ids( params: Union[dict[str, Any], ImmutableMultiDict] ) -> Tuple[list[AccountDetail], int]: """Search accounts by ids.""" accounts_by_params, total_count = _execute_account_query(params) account_list = account_detail_schema.dump(accounts_by_params, many=True) return account_list, total_count def _execute_account_query(params): """Search for account.""" query_config = { 'account_name': _get_account_name_from_params(params), # Deprecated 'account_ids': params.getlist('account_ids') or None if isinstance(params, ImmutableMultiDict) else params.get('account_ids', None), 'search_term': params.get('search_term', None), 'payment_entity_id': params.get('payment_entity_id'), 'reference_payment_type_id': params.get('reference_payment_type_id'), 'agreement_type_ids': params.getlist('agreement_type_ids') or None if isinstance(params, ImmutableMultiDict) else params.get('agreement_type_ids', None), } query_config = {k: v for k, v in query_config.items() if v not in [None, '']} query = Account.get_filtered_query(**query_config) limit = max(int(params.get('limit', DEFAULT_PAGE_LIMIT)), 1) offset = max(int(params.get('offset', DEFAULT_PAGE_OFFSET)), 0) result = _execute_paged_query(query, limit, offset) total_count = len(result) if len(result) == limit or offset > 0: total_count = query.count() return result, total_count def _get_account_name_from_params(params): """Get the correct search term from the params.""" return unquote(params.get('account_name', '')) def _execute_paged_query(query, limit, offset): """Get the offset and limit from the params and execute the paged query.""" return query \ .order_by(account_model.default_order()) \ .offset(offset) \ .limit(limit) \ .options( joinedload(Account.account_payee), joinedload(Account.account_payment_term) ).all()