diff --git a/mhr-api/migrations/versions/0001_rebase_2024-10.py b/mhr-api/migrations/versions/0001_rebase_2024-10.py index 4bad5d6d2..66ab92045 100644 --- a/mhr-api/migrations/versions/0001_rebase_2024-10.py +++ b/mhr-api/migrations/versions/0001_rebase_2024-10.py @@ -3612,7 +3612,7 @@ def downgrade(): public_mhr_account_reg_vw = PGView( schema="public", signature="mhr_account_reg_vw", - definition="SELECT r.mhr_number, r.status_type, r.registration_ts,\n (SELECT CASE WHEN p.business_name IS NOT NULL THEN p.business_name\n WHEN p.middle_name IS NOT NULL THEN p.first_name || ' ' || p.middle_name || ' ' || p.last_name\n ELSE p.first_name || ' ' || p.last_name\n END\n FROM mhr_parties p\n WHERE p.registration_id = r.id \n AND p.party_type = 'SUBMITTING') AS submitting_name,\n r.client_reference_id,\n r.registration_type, \n (SELECT string_agg((CASE WHEN p.business_name IS NOT NULL THEN p.business_name\n WHEN p.middle_name IS NOT NULL THEN p.first_name || ' ' || p.middle_name || ' ' || p.last_name\n ELSE p.first_name || ' ' || p.last_name END), '\\n')\n FROM mhr_registrations r1, mhr_owner_groups og, mhr_parties p\n WHERE r1.mhr_number = r.mhr_number \n AND r1.id = og.registration_id\n AND og.registration_id = p.registration_id\n AND og.id = p.owner_group_id\n AND r1.registration_ts = (SELECT MAX(r2.registration_ts)\n FROM mhr_registrations r2, mhr_owner_groups og2\n WHERE r2.mhr_number = r.mhr_number\n AND og2.registration_id = r2.id\n AND r2.id <= r.id)) AS owner_names, \n (SELECT CASE WHEN r.user_id IS NULL THEN ''\n ELSE (SELECT u.firstname || ' ' || u.lastname\n FROM users u\n WHERE u.username = r.user_id FETCH FIRST 1 ROWS ONLY) END) AS registering_name,\n d.document_id,\n d.document_registration_number,\n (SELECT d2.document_type\n FROM mhr_documents d2\n WHERE d2.id = (SELECT MAX(d3.id)\n FROM mhr_documents d3, mhr_registrations r2\n WHERE r2.id = d3.registration_id\n AND r2.mhr_number = r.mhr_number)) AS last_doc_type,\n (SELECT n.status_type\n FROM mhr_notes n\n WHERE n.registration_id = r.id) AS note_status,\n (SELECT n.expiry_date\n FROM mhr_notes n\n WHERE n.registration_id = r.id) AS note_expiry,\n (CASE\n WHEN d.document_type in ('NCAN', 'NRED') THEN\n (SELECT n.document_type\n FROM mhr_notes n\n WHERE n.status_type != 'ACTIVE'\n AND n.change_registration_id = r.id\n AND n.document_type != 'CAUC'\n AND n.document_type != 'CAUE'\n FETCH FIRST 1 ROWS ONLY)\n ELSE NULL\n END) AS cancel_doc_type,\n (SELECT n.document_type\n FROM mhr_notes n, mhr_registrations r2\n WHERE r2.mhr_number = r.mhr_number\n AND r2.id = n.registration_id\n AND n.status_type = 'ACTIVE'\n AND (n.document_type IN ('TAXN', 'NCON', 'REST') OR \n (n.document_type IN ('REG_103', 'REG_103E') AND \n n.expiry_date IS NOT NULL AND n.expiry_date > (now() at time zone 'UTC')))\n FETCH FIRST 1 ROWS ONLY) AS frozen_doc_type,\n r.account_id,\n dt.document_type_desc,\n (SELECT CASE WHEN r.registration_type NOT IN ('MHREG', 'MHREG_CONVERSION') THEN ''\n ELSE (SELECT lcv.registration_type\n FROM mhr_lien_check_vw lcv\n WHERE lcv.mhr_number = r.mhr_number\n ORDER BY lcv.base_registration_ts\n FETCH FIRST 1 ROWS ONLY) END) AS ppr_lien_type,\n d.document_type,\n r.id AS registration_id,\n (SELECT mrr.doc_storage_url\n FROM mhr_registration_reports mrr\n WHERE mrr.registration_id = r.id) AS doc_storage_url,\n (SELECT l.location_type\n FROM mhr_locations l, mhr_registrations r2\n WHERE r2.mhr_number = r.mhr_number\n AND r2.id = l.registration_id\n AND l.status_type = 'ACTIVE') AS location_type,\n d.affirm_by,\n (SELECT COUNT(mrr.id)\n FROM mhr_registration_reports mrr\n WHERE mrr.registration_id = r.id) AS report_count\n FROM mhr_registrations r, mhr_documents d, mhr_document_types dt\n WHERE r.id = d.registration_id\n AND d.document_type = dt.document_type" + definition="SELECT r.mhr_number, r.status_type, r.registration_ts,\n (SELECT CASE WHEN p.business_name IS NOT NULL THEN p.business_name\n WHEN p.middle_name IS NOT NULL THEN p.first_name || ' ' || p.middle_name || ' ' || p.last_name\n ELSE p.first_name || ' ' || p.last_name\n END\n FROM mhr_parties p\n WHERE p.registration_id = r.id \n AND p.party_type = 'SUBMITTING') AS submitting_name,\n r.client_reference_id,\n r.registration_type, \n (SELECT string_agg((CASE WHEN p.business_name IS NOT NULL THEN p.business_name\n WHEN p.middle_name IS NOT NULL THEN p.first_name || ' ' || p.middle_name || ' ' || p.last_name\n ELSE p.first_name || ' ' || p.last_name END), '\\n')\n FROM mhr_registrations r1, mhr_owner_groups og, mhr_parties p\n WHERE r1.mhr_number = r.mhr_number \n AND r1.id = og.registration_id\n AND og.registration_id = p.registration_id\n AND og.id = p.owner_group_id\n AND r1.registration_ts = (SELECT MAX(r2.registration_ts)\n FROM mhr_registrations r2, mhr_owner_groups og2\n WHERE r2.mhr_number = r.mhr_number\n AND og2.registration_id = r2.id\n AND r2.id <= r.id)) AS owner_names, \n (SELECT CASE WHEN r.user_id IS NULL THEN ''\n ELSE (SELECT u.firstname || ' ' || u.lastname\n FROM users u\n WHERE u.username = r.user_id FETCH FIRST 1 ROWS ONLY) END) AS registering_name,\n d.document_id,\n d.document_registration_number,\n (SELECT d2.document_type\n FROM mhr_documents d2\n WHERE d2.id = (SELECT MAX(d3.id)\n FROM mhr_documents d3, mhr_registrations r2\n WHERE r2.id = d3.registration_id\n AND r2.mhr_number = r.mhr_number)) AS last_doc_type,\n (SELECT n.status_type\n FROM mhr_notes n\n WHERE n.registration_id = r.id) AS note_status,\n (SELECT n.expiry_date\n FROM mhr_notes n\n WHERE n.registration_id = r.id) AS note_expiry,\n (CASE\n WHEN d.document_type in ('NCAN', 'NRED') THEN\n (SELECT n.document_type\n FROM mhr_notes n\n WHERE n.status_type != 'ACTIVE'\n AND n.change_registration_id = r.id\n AND n.document_type != 'CAUC'\n AND n.document_type != 'CAUE'\n FETCH FIRST 1 ROWS ONLY)\n ELSE NULL\n END) AS cancel_doc_type,\n (SELECT n.document_type\n FROM mhr_notes n, mhr_registrations r2\n WHERE r2.mhr_number = r.mhr_number\n AND r2.id = n.registration_id\n AND n.status_type = 'ACTIVE'\n AND n.document_type IN ('TAXN', 'NCON', 'REST') FETCH FIRST 1 ROWS ONLY) AS frozen_doc_type,\n r.account_id,\n dt.document_type_desc,\n (SELECT CASE WHEN r.registration_type NOT IN ('MHREG', 'MHREG_CONVERSION') THEN ''\n ELSE (SELECT lcv.registration_type\n FROM mhr_lien_check_vw lcv\n WHERE lcv.mhr_number = r.mhr_number\n ORDER BY lcv.base_registration_ts\n FETCH FIRST 1 ROWS ONLY) END) AS ppr_lien_type,\n d.document_type,\n r.id AS registration_id,\n (SELECT mrr.doc_storage_url\n FROM mhr_registration_reports mrr\n WHERE mrr.registration_id = r.id) AS doc_storage_url,\n (SELECT l.location_type\n FROM mhr_locations l, mhr_registrations r2\n WHERE r2.mhr_number = r.mhr_number\n AND r2.id = l.registration_id\n AND l.status_type = 'ACTIVE') AS location_type,\n d.affirm_by,\n (SELECT COUNT(mrr.id)\n FROM mhr_registration_reports mrr\n WHERE mrr.registration_id = r.id) AS report_count\n FROM mhr_registrations r, mhr_documents d, mhr_document_types dt\n WHERE r.id = d.registration_id\n AND d.document_type = dt.document_type" ) op.drop_entity(public_mhr_account_reg_vw) diff --git a/mhr-api/pyproject.toml b/mhr-api/pyproject.toml index 3ac5d9379..1c72b87b2 100644 --- a/mhr-api/pyproject.toml +++ b/mhr-api/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mhr-api" -version = "2.0.5" +version = "2.0.6" description = "" authors = ["dlovett "] license = "BSD 3" diff --git a/mhr-api/src/database/postgres_views/mhr_account_reg_vw.py b/mhr-api/src/database/postgres_views/mhr_account_reg_vw.py index e30a28ce0..4a78078de 100644 --- a/mhr-api/src/database/postgres_views/mhr_account_reg_vw.py +++ b/mhr-api/src/database/postgres_views/mhr_account_reg_vw.py @@ -66,9 +66,7 @@ WHERE r2.mhr_number = r.mhr_number AND r2.id = n.registration_id AND n.status_type = 'ACTIVE' - AND (n.document_type IN ('TAXN', 'NCON', 'REST') OR - (n.document_type IN ('REG_103', 'REG_103E') AND - n.expiry_date IS NOT NULL AND n.expiry_date > (now() at time zone 'UTC'))) + AND n.document_type IN ('TAXN', 'NCON', 'REST') FETCH FIRST 1 ROWS ONLY) AS frozen_doc_type, r.account_id, dt.document_type_desc, diff --git a/mhr-api/src/mhr_api/resources/registration_utils.py b/mhr-api/src/mhr_api/resources/registration_utils.py index a969d5ef0..af372e43c 100644 --- a/mhr-api/src/mhr_api/resources/registration_utils.py +++ b/mhr-api/src/mhr_api/resources/registration_utils.py @@ -62,7 +62,6 @@ "DISCHARGE": "Register a Discharge Statement", } TO_DRS_DOC_TYPE = { - "CANCEL_PERMIT": "REGC", "TRANS_SEVER_GRANT": "TRAN", "TRANS_RECEIVERSHIP": "TRAN", "TRANS_LAND_TITLE": "TRAN", @@ -70,7 +69,6 @@ "TRANS_QUIT_CLAIM": "TRAN", "TRANS_INFORMAL_SALE": "TRAN", "TRANS_WRIT_SEIZURE": "TRAN", - "AMEND_PERMIT": "REGC", "REGC_STAFF": "REGC", "REGC_CLIENT": "REGC", } diff --git a/mhr-api/src/mhr_api/resources/v1/permits.py b/mhr-api/src/mhr_api/resources/v1/permits.py index 645c17e43..310f9fa21 100644 --- a/mhr-api/src/mhr_api/resources/v1/permits.py +++ b/mhr-api/src/mhr_api/resources/v1/permits.py @@ -99,13 +99,7 @@ def post_permits(mhr_number: str): # pylint: disable=too-many-return-statements response_json["description"] = current_json.get("description") response_json["status"] = current_json.get("status") response_json["ownerGroups"] = current_json.get("ownerGroups") - if response_json.get("amendment") or response_json.get("extension"): - response_json["permitRegistrationNumber"] = current_json.get("permitRegistrationNumber", "") - response_json["permitDateTime"] = current_json.get("permitDateTime", "") - response_json["permitExpiryDateTime"] = current_json.get("permitExpiryDateTime", "") - response_json["permitStatus"] = current_json.get("permitStatus", "") - if existing_status != current_json.get("status"): - response_json["previousStatus"] = existing_status + response_json = set_amend_extend(response_json, current_json, existing_status) setup_report(registration, response_json, group, jwt, current_json) return jsonify(response_json), HTTPStatus.CREATED except DatabaseException as db_exception: @@ -118,8 +112,24 @@ def post_permits(mhr_number: str): # pylint: disable=too-many-return-statements return resource_utils.default_exception_response(default_exception) +def set_amend_extend(response_json: dict, current_json: dict, existing_status: str) -> dict: + """Add amend/extend permit extra information.""" + if response_json.get("amendment") or response_json.get("extension"): + response_json["permitRegistrationNumber"] = current_json.get("permitRegistrationNumber", "") + response_json["permitDateTime"] = current_json.get("permitDateTime", "") + if response_json.get("note") and response_json["note"].get("expiryDateTime"): + response_json["permitExpiryDateTime"] = response_json["note"].get("expiryDateTime") + response_json["permitStatus"] = response_json["note"].get("status", "") + else: + response_json["permitExpiryDateTime"] = current_json.get("permitExpiryDateTime", "") + response_json["permitStatus"] = current_json.get("permitStatus", "") + if existing_status != current_json.get("status"): + response_json["previousStatus"] = existing_status + return response_json + + def setup_report(registration: MhrRegistration, response_json: dict, group: str, j_token, current_json: dict): - """Perform all extra set up of the transfer report request data and add it to the queue.""" + """Perform all extra set up of the permit report request data and add it to the queue.""" response_json["usergroup"] = group if is_staff(j_token): response_json["username"] = reg_utils.get_affirmby(g.jwt_oidc_token_info) diff --git a/mhr-api/src/mhr_api/utils/validator_owner_utils.py b/mhr-api/src/mhr_api/utils/validator_owner_utils.py index 78052f42a..d0c595673 100644 --- a/mhr-api/src/mhr_api/utils/validator_owner_utils.py +++ b/mhr-api/src/mhr_api/utils/validator_owner_utils.py @@ -26,6 +26,8 @@ DELETE_GROUP_ID_INVALID = "The owner group with ID {group_id} is not active and cannot be changed. " DELETE_GROUP_ID_NONEXISTENT = "No owner group with ID {group_id} exists. " DELETE_GROUP_TYPE_INVALID = "The owner group tenancy type with ID {group_id} is invalid. " +DELETE_GROUPS_MISSING = "The delete owner groups are required. " +DELETE_GROUP_ID_MISSING = "Delete owner group ID is missing. " GROUP_INTEREST_MISMATCH = "The owner group interest numerator sum does not equal the interest common denominator. " GROUP_NUMERATOR_MISSING = "The owner group interest numerator is required and must be an integer greater than 0. " GROUP_DENOMINATOR_MISSING = "The owner group interest denominator is required and must be an integer greater than 0. " @@ -373,19 +375,27 @@ def validate_owner_groups_common(groups, registration: MhrRegistration = None, d return error_msg -def validate_owner_groups( +def validate_owner_groups( # pylint: disable=too-many-branches groups, new: bool, registration: MhrRegistration = None, delete_groups=None, active_count: int = 0 ): """Verify owner groups are valid.""" - error_msg = "" + error_msg: str = "" if not groups: return error_msg so_count: int = 0 staff: bool = False + + if not new and delete_groups is None: + error_msg += DELETE_GROUPS_MISSING + elif not new and delete_groups: + for del_group in delete_groups: + if not del_group.get("groupId"): + error_msg += DELETE_GROUP_ID_MISSING if registration: staff = registration.staff if common_tenancy(groups, new, active_count): - return validate_owner_groups_common(groups, registration, delete_groups) + error_msg += validate_owner_groups_common(groups, registration, delete_groups) + return error_msg for group in groups: tenancy_type: str = group.get("type", "") if new and tenancy_type == MhrTenancyTypes.COMMON: diff --git a/mhr-api/tests/unit/utils/test_transfer_validator.py b/mhr-api/tests/unit/utils/test_transfer_validator.py index 23a0c1b3e..1532a2812 100644 --- a/mhr-api/tests/unit/utils/test_transfer_validator.py +++ b/mhr-api/tests/unit/utils/test_transfer_validator.py @@ -104,6 +104,8 @@ # testdata pattern is ({description}, {valid}, {numerator}, {denominator}, {add_group}, {message content}) TEST_TRANSFER_DATA_GROUP = [ ('Valid', True, 1, 2, None, None), + ('Invalid no delete group', False, 1, 2, None, val_owner_utils.DELETE_GROUPS_MISSING), + ('Invalid no delete groupId', False, 1, 2, None, val_owner_utils.DELETE_GROUP_ID_MISSING), ('Invalid add TC no owner', False, None, None, TC_GROUP_TRANSFER_ADD2, val_owner_utils.OWNERS_COMMON_INVALID), ('Invalid add JT 1 owner', False, None, None, JT_OWNER_SINGLE, val_owner_utils.OWNERS_JOINT_INVALID), ('Invalid TC numerator missing', False, None, 2, TC_GROUPS_VALID, val_owner_utils.GROUP_NUMERATOR_MISSING), @@ -397,8 +399,13 @@ def test_validate_transfer_group(session, desc, valid, numerator, denominator, a """Assert that MH transfer validation of owner groups works as expected.""" # setup json_data = copy.deepcopy(TRANSFER) - json_data['deleteOwnerGroups'][0]['groupId'] = 1 - json_data['deleteOwnerGroups'][0]['type'] = 'SOLE' + if desc == 'Invalid no delete group': + del json_data['deleteOwnerGroups'] + elif desc == 'Invalid no delete groupId': + del json_data['deleteOwnerGroups'][0]['groupId'] + else: + json_data['deleteOwnerGroups'][0]['groupId'] = 1 + json_data['deleteOwnerGroups'][0]['type'] = 'SOLE' if add_group: json_data['addOwnerGroups'] = copy.deepcopy(add_group) if desc == 'Invalid add TC no owner':