diff --git a/mhr_api/src/mhr_api/utils/registration_validator.py b/mhr_api/src/mhr_api/utils/registration_validator.py index d18afda9f..5dc4c6659 100644 --- a/mhr_api/src/mhr_api/utils/registration_validator.py +++ b/mhr_api/src/mhr_api/utils/registration_validator.py @@ -109,6 +109,7 @@ QS_DEALER_INVALID = 'No approved qualified supplier information found: supplier account set up invalid.' DEALER_TRANSFER_OWNER_INVALID = 'QS dealer transfer invalid: either current owner group is not SOLE or the owner ' + \ 'name does not match the qualified supplier account name. ' +TRANSFER_DATE_FUTURE = 'The transfer date of execution (transferDate) cannot be in the future. ' PPR_SECURITY_AGREEMENT = ' SA TA TG TM ' @@ -172,8 +173,7 @@ def validate_transfer(registration: MhrRegistration, # pylint: disable=too-many MhrDocumentTypes.TRANS_SEVER_GRANT)): if not json_data.get('consideration'): error_msg += CONSIDERATION_REQUIRED - if not json_data.get('transferDate'): - error_msg += TRANSFER_DATE_REQUIRED + error_msg += validate_transfer_date(json_data) if json_data.get('deleteOwnerGroups') and len(json_data.get('deleteOwnerGroups')) != 1 and \ group == QUALIFIED_USER_GROUP and \ len(json_data.get('deleteOwnerGroups')) != validator_utils.get_existing_group_count(registration): @@ -492,9 +492,15 @@ def validate_transfer_cert_corp(reg_type: str, owner_json: dict) -> str: def is_delete_exec_admin(reg_type: str, owner_json: dict) -> bool: """Evaluate if a deleted owner is an executor or an administrator for one of the death transfers types.""" - if reg_type == MhrRegistrationTypes.TRANS_WILL and owner_json.get('partyType', '') == MhrPartyTypes.EXECUTOR: + if reg_type == MhrRegistrationTypes.TRANS_WILL and owner_json.get('partyType', '') in (MhrPartyTypes.EXECUTOR, + MhrPartyTypes.ADMINISTRATOR, + MhrPartyTypes.TRUST, + MhrPartyTypes.TRUSTEE): return True - if reg_type == MhrRegistrationTypes.TRANS_ADMIN and owner_json.get('partyType', '') == MhrPartyTypes.ADMINISTRATOR: + if reg_type == MhrRegistrationTypes.TRANS_ADMIN and owner_json.get('partyType', '') in (MhrPartyTypes.EXECUTOR, + MhrPartyTypes.ADMINISTRATOR, + MhrPartyTypes.TRUST, + MhrPartyTypes.TRUSTEE): return True return False @@ -742,3 +748,17 @@ def validate_transfer_dealer(registration: MhrRegistration, json_data, reg_type: if json_data.get('supplier'): # Added just for this validation. del json_data['supplier'] return error_msg + + +def validate_transfer_date(json_data) -> str: + """Transfer execution date is required and cannot be in the future.""" + error_msg = '' + if not json_data.get('transferDate'): + error_msg += TRANSFER_DATE_REQUIRED + else: + now = model_utils.now_ts() + transfer_dt = model_utils.ts_from_iso_format(json_data.get('transferDate')) + current_app.logger.info(f'Comparing transfer {transfer_dt} with current ts {now}') + if transfer_dt.date() > now.date(): + error_msg += TRANSFER_DATE_FUTURE + return error_msg diff --git a/mhr_api/src/mhr_api/version.py b/mhr_api/src/mhr_api/version.py index 70bf1455c..7d70de18f 100644 --- a/mhr_api/src/mhr_api/version.py +++ b/mhr_api/src/mhr_api/version.py @@ -22,4 +22,4 @@ Development release segment: .devN """ -__version__ = '1.8.21' # pylint: disable=invalid-name +__version__ = '1.8.22' # pylint: disable=invalid-name diff --git a/mhr_api/tests/unit/utils/test_transfer_validator.py b/mhr_api/tests/unit/utils/test_transfer_validator.py index 520b46858..b3ab08085 100644 --- a/mhr_api/tests/unit/utils/test_transfer_validator.py +++ b/mhr_api/tests/unit/utils/test_transfer_validator.py @@ -98,6 +98,7 @@ ('Valid staff missing', True, True, False, False, False, None), ('Valid non-staff exists', True, False, True, True, True, None), ('Invalid non-staff missing transfer date', False, False, False, True, True, validator.TRANSFER_DATE_REQUIRED), + ('Invalid non-staff future transfer date', False, False, True, True, True, validator.TRANSFER_DATE_FUTURE), ('Invalid non-staff missing declared value', False, False, True, False, True, validator.DECLARED_VALUE_REQUIRED), ('Invalid non-staff missing consideration', False, False, True, True, False, validator.CONSIDERATION_REQUIRED) ] @@ -364,6 +365,10 @@ def test_validate_transfer_details(session, desc, valid, staff, trans_dt, dec_va del json_data['documentId'] if not trans_dt: del json_data['transferDate'] + elif desc == 'Valid non-staff exists': + json_data['transferDate'] = model_utils.format_ts(model_utils.now_ts()) + elif desc == 'Invalid non-staff future transfer date': + json_data['transferDate'] = model_utils.format_ts(model_utils.now_ts_offset(1, True)) if not dec_value: del json_data['declaredValue'] if not consideration: