"""Logic for ContractParty.""" from typing import Type from owsresponse import response from abacus_contract import models from abacus_contract.constants.constants import DEFAULT_PAGE_LIMIT, DEFAULT_PAGE_OFFSET from abacus_contract.schemas.contract_party import ContractPartyDetailSchema from abacus_contract.utils.format_error import validation_error from abacus_contract.utils.request import validate_pagination_params def create_contract_party( contract_id: int, target_id: str, target_type: str ) -> Type[response.Response]: """Create a contract_party. If contract_party already exists for specified contract_id, target_id, and target_type and has been deleted, then this method updates the "deleted_at" and "deleted_by" columns of contract_party to NULL, otherwise it creates a new contract_party. Args: contract_id (str): id of the related contract target_id (str): id of the target_type target_type (str): must be one of 'contributor', 'label' Returns: a newly created contract_party record """ models.Contract.get_by_id_or_error(contract_id) contract_party = models.ContractParty.get_contract_party( contract_id, target_id, target_type ) if contract_party: updated_contract_party = dict( contract_party_id=contract_party.contract_party_id, deleted_by=None, deleted_at=None, ) contract_party.update_attributes(**updated_contract_party) models.ContractParty.commit_changes() else: contract_party = models.ContractParty.create( contract_id=contract_id, target_id=target_id, target_type=target_type ) message = ContractPartyDetailSchema().dump(contract_party) return response.Response(message=message, status=201) def get_contract_parties( contract_id: int, target_type: str, request_params: dict ) -> Type[response.Response]: """Get a list of contract parties by contract_id and/or target_type. Arg: contract_id (str): id of the related contract target_type (str)(Optional): must be one of 'contributor', 'label' request_params (dict)(Optional): dict of query string passed to the url - limit(int): the size of page - offset(int): the number of items to skip before returning results Returns: A List of contract parties """ try: params = _validate_request_params(contract_id, target_type, request_params) items, total_count = models.ContractParty.get_by_contract_id(**params) message = dict( items=ContractPartyDetailSchema().dump(items, many=True), total_count=total_count, ) except Exception as exc: return validation_error(str(exc)) return response.Response(message=message, status=200) def _validate_request_params( contract_id: int, target_type: str, request_params: dict ) -> dict: """Validate request parameters. Args: contract_id(int): id of the contract target_type(str): must be one of 'contributor', 'label' request_params (dict)(Optional): dict of query string passed to the url - limit(int): the size of page - offset(int): the number of items to skip before returning results Returns: A dict of request parameters """ limit = request_params.get('limit', DEFAULT_PAGE_LIMIT) offset = request_params.get('offset', DEFAULT_PAGE_OFFSET) # validate pagination params pagination_params = validate_pagination_params(limit, offset) # validate contract models.Contract.get_by_id_or_error(contract_id) # validate target_type if target_type: ContractPartyDetailSchema().load({'target_type': target_type}, partial=True) return {'contract_id': contract_id, 'target_type': target_type, **pagination_params} def delete_contract_party( contract_party: Type[models.ContractParty], ) -> Type[response.Response]: """Soft delete specified contract_party. Args: contract_party (class): ContractParty instance """ contract_party_id = contract_party.contract_party_id models.ContractParty.delete_by_id_or_error(contract_party_id, soft_delete=True) models.ContractParty.commit_changes() return response.Response(status=204)