"""Logic for Payment Group.""" import typing from payment.constants import error from payment.constants.constants import SPECIFIC_ACCOUNTS_PAYMENT_GROUP_NAME from payment.logic.exceptions import LogicError from payment.logic.payment_group_payment import create_payment_group_payment from payment.models import Items from payment.models.payment_group import PaymentGroup from payment.utils.format_error import validate_currency from payment.utils.models import as_dict def create_payment_group(**params) -> dict[str, typing.Any]: """Create payment_group.""" _validate_payment_group(**params) payment_name = params.pop('payment_name', None) is_reusable = params.get('is_reusable') if _is_specific_accounts_payment(**params): params['group_name'] = SPECIFIC_ACCOUNTS_PAYMENT_GROUP_NAME new_payment_group = PaymentGroup.create(**params) result = as_dict(new_payment_group) if payment_name and not is_reusable: payment_group_payment = create_payment_group_payment( new_payment_group.payment_group_id, payment_name ) result = {**result, **as_dict(payment_group_payment)} return result def _is_specific_accounts_payment(**params): return len(params.get('group_criteria', {}).get('account_ids', [])) > 1 def _validate_payment_group(**params): """Validate payment group params.""" group_name = params.get('group_name') is_reusable = params.get('is_reusable') payment_name = params.get('payment_name', None) group_criteria = params.get('group_criteria', {}) account_id = group_criteria.get('account_id') account_ids = group_criteria.get('account_ids') if account_id and not account_ids: account_ids = [account_id] currency_codes = group_criteria.get('currency_codes', []) reference_payment_entities = group_criteria.get('reference_payment_entities', []) validations = [ (account_ids and len(group_criteria) > 1, error.ERROR_INVALID_GROUP_CRITERIA), (account_ids and is_reusable, error.ERROR_CANNOT_REUSE), (account_ids and not payment_name, error.ERROR_PAYMENT_NAME_MISSING), (not account_ids and not is_reusable, error.ERROR_REUSE), ] for condition, error_message in validations: if condition: raise LogicError(error_message) for currency in currency_codes: try: validate_currency(currency, True) except ValueError as e: raise LogicError(str(e)) if len(reference_payment_entities) > 1: raise LogicError(error.ERROR_ONLY_ONE_REFERENCE_PAYMENT_ENTITY) # Validate that no two reusable groups can have the same name if is_reusable and PaymentGroup.find_by_name(group_name): raise LogicError(error.ERROR_ALREADY_EXISTS.format(object_type='Payment Group')) def get_reusable_payment_groups(limit, offset) -> Items[PaymentGroup]: """Get a reusable payment groups.""" items, count = PaymentGroup.get_reusable_payment_groups(limit, offset) return Items(items, count) def update_payment_group( object_id: int, **params: dict[str, typing.Any] ) -> PaymentGroup: """Update PaymentGroup.""" obj = PaymentGroup.get_by_id_or_error(object_id) if not obj.is_reusable: raise LogicError(error.ERROR_UPDATE_NON_REUSABLE_PAYMENT_GROUP) new_name = params.get('group_name') if new_name: existing = PaymentGroup.find_by_name(new_name) if existing and existing.payment_group_id != obj.payment_group_id: raise LogicError( error.ERROR_ALREADY_EXISTS.format(object_type='Payment Group') ) obj.update_attributes(**params) obj.commit_changes() return obj def get_payment_group(object_id: int) -> PaymentGroup: """Get PaymentGroup.""" return PaymentGroup.get_by_id_or_error(object_id)