From cfdf931ea2425469d45f629e079264dd8e129580 Mon Sep 17 00:00:00 2001 From: Kial Jinnah Date: Fri, 19 Sep 2025 16:02:13 -0400 Subject: [PATCH 1/6] API - add state filing id to business slim, add filing slim Signed-off-by: Kial Jinnah --- legal-api/flags.json | 1 + .../src/legal_api/models/amalgamation.py | 6 +- legal-api/src/legal_api/models/business.py | 14 ++-- .../business_filings/business_filings.py | 39 ++++++++++- legal-api/src/legal_api/services/flags.py | 18 ++--- .../tests/unit/resources/v2/test_business.py | 69 +++++++++++++++++-- .../v2/test_business_filings/test_filings.py | 51 +++++++++++++- 7 files changed, 174 insertions(+), 24 deletions(-) diff --git a/legal-api/flags.json b/legal-api/flags.json index 9fb68ecafd..89e4f3c424 100644 --- a/legal-api/flags.json +++ b/legal-api/flags.json @@ -10,6 +10,7 @@ "enable-involuntary-dissolution-filter": false, "enable-new-ben-statements": false, "enable-auth-v2-business": true, + "enable-auth-v2-filing": true, "enable-permissions-for-action": false, "enabled-deeper-permission-action": false, "involuntary-dissolution-filter": { diff --git a/legal-api/src/legal_api/models/amalgamation.py b/legal-api/src/legal_api/models/amalgamation.py index 7f024d7e8c..f8c22655ba 100644 --- a/legal-api/src/legal_api/models/amalgamation.py +++ b/legal-api/src/legal_api/models/amalgamation.py @@ -127,11 +127,13 @@ def get_revision_json(cls, transaction_id, business_id, tombstone=False): 'legalName': 'Not Available', 'amalgamationDate': 'Not Available' } - + print(5) amalgamation = Amalgamation.get_revision(transaction_id, business_id) + print(6) from .business import Business # pylint: disable=import-outside-toplevel + print(7) business = Business.find_by_internal_id(amalgamation.business_id) - + print(8) return { 'amalgamationDate': amalgamation.amalgamation_date.isoformat(), 'amalgamationType': amalgamation.amalgamation_type.name, diff --git a/legal-api/src/legal_api/models/business.py b/legal-api/src/legal_api/models/business.py index 6892f347e4..2ffc2aef2c 100644 --- a/legal-api/src/legal_api/models/business.py +++ b/legal-api/src/legal_api/models/business.py @@ -636,13 +636,18 @@ def _slim_json(self): if self.tax_id: d['taxId'] = self.tax_id + + if self.state_filing_id: + if (amalgamated_into := self.get_amalgamated_into()): + d['amalgamatedInto'] = amalgamated_into + else: + base_url = current_app.config.get('LEGAL_API_BASE_URL') + d['stateFiling'] = f'{base_url}/{self.identifier}/filings/{self.state_filing_id}' return d def _extend_json(self, d): """Include conditional fields to json.""" - base_url = current_app.config.get('LEGAL_API_BASE_URL') - if self.last_coa_date: d['lastAddressChangeDate'] = LegislationDatetime.format_as_legislation_date(self.last_coa_date) if self.last_cod_date: @@ -653,11 +658,6 @@ def _extend_json(self, d): if self.fiscal_year_end_date: d['fiscalYearEndDate'] = datetime.date(self.fiscal_year_end_date).isoformat() - if self.state_filing_id: - if (amalgamated_into := self.get_amalgamated_into()): - d['amalgamatedInto'] = amalgamated_into - else: - d['stateFiling'] = f'{base_url}/{self.identifier}/filings/{self.state_filing_id}' if self.start_date: d['startDate'] = LegislationDatetime.format_as_legislation_date(self.start_date) diff --git a/legal-api/src/legal_api/resources/v2/business/business_filings/business_filings.py b/legal-api/src/legal_api/resources/v2/business/business_filings/business_filings.py index b3ce4b9c7c..cc21594c31 100644 --- a/legal-api/src/legal_api/resources/v2/business/business_filings/business_filings.py +++ b/legal-api/src/legal_api/resources/v2/business/business_filings/business_filings.py @@ -20,7 +20,7 @@ from contextlib import suppress from datetime import datetime as _datetime from http import HTTPStatus -from typing import Generic, Optional, Tuple, TypeVar, Union +from typing import Any, Generic, Optional, Tuple, TypeVar, Union import requests # noqa: I001; grouping out of order to make both pylint & isort happy from requests import exceptions # noqa: I001; grouping out of order to make both pylint & isort happy @@ -300,6 +300,43 @@ def get_single_filing(identifier: str, filing_id: int): if not rv: return jsonify({'message': f'{identifier} no filings found'}), HTTPStatus.NOT_FOUND + if str(request.args.get('slim', None)).lower() == 'true': + # only return publicly accessible data + if str(request.accept_mimetypes) == 'application/pdf': + return jsonify({'message': 'A slim version of the filing pdf is not available.'}), HTTPStatus.BAD_REQUEST + + def get_redacted_json(json: dict[str, Any], allowed_keys: list[str]): + """Return the json with only the specified allowed_keys.""" + return {key: json[key] for key in allowed_keys if json.get(key)} + + filing_json = rv.json + filing_name = filing_json['filing']['header']['name'] + + # only need 'header' and '' sections from 'filing' + public_root_filing_keys = ['header', filing_name] + filing_json['filing'] = get_redacted_json(filing_json['filing'], public_root_filing_keys) + + # only need 'name' and 'effectiveDate' from 'header' + public_header_keys = ['name', 'effectiveDate'] + filing_json['filing']['header'] = get_redacted_json(filing_json['filing']['header'], public_header_keys) + + # only need the following keys when they are available in the nested filing info + public_filing_keys = ['dissolutionType', 'dissolutionDate', 'type', 'reason'] + filing_json['filing'][filing_name] = get_redacted_json(filing_json['filing'][filing_name], public_filing_keys) + + return jsonify(filing_json) + + if flags.is_on('enable-auth-v2-filing') and not authorized(identifier, jwt, action=['view']): + current_app.logger.warning( + 'Unauthorized request for filing: %s, from username: %s, accountId: %s, app-name: %s', + identifier, + g.jwt_oidc_token_info.get('preferred_username'), + request.args.get('account'), + request.headers.get('app-name')) + return jsonify({'message': + f'You are not authorized to view filing {identifier}.'}), \ + HTTPStatus.UNAUTHORIZED + if original_filing: return jsonify(rv.redacted(rv.raw, jwt)) diff --git a/legal-api/src/legal_api/services/flags.py b/legal-api/src/legal_api/services/flags.py index 156e1b84e8..bc991aa958 100644 --- a/legal-api/src/legal_api/services/flags.py +++ b/legal-api/src/legal_api/services/flags.py @@ -76,15 +76,15 @@ def init_app(self, app): if self.sdk_key or app.env != 'production': self.logger.debug("sdk key used: %s", self.sdk_key) - - if app.env == 'production': - config = Config(sdk_key=self.sdk_key) - else: - factory = FileDataSource.factory(paths=['flags.json'], - auto_update=True) - config = Config(sdk_key=self.sdk_key, - update_processor_class=factory, - send_events=False) + config = Config(sdk_key=self.sdk_key) + # if app.env == 'production': + # config = Config(sdk_key=self.sdk_key) + # else: + # factory = FileDataSource.factory(paths=['flags.json'], + # auto_update=True) + # config = Config(sdk_key=self.sdk_key, + # update_processor_class=factory, + # send_events=False) ldclient_set_config(config) client = ldclient_get() diff --git a/legal-api/tests/unit/resources/v2/test_business.py b/legal-api/tests/unit/resources/v2/test_business.py index 4e6535d594..5baf3c787f 100644 --- a/legal-api/tests/unit/resources/v2/test_business.py +++ b/legal-api/tests/unit/resources/v2/test_business.py @@ -21,10 +21,17 @@ import pytest import registry_schemas -from registry_schemas.example_data import ANNUAL_REPORT, CORRECTION_AR, COURT_ORDER_FILING_TEMPLATE, FILING_HEADER, \ - FILING_TEMPLATE, INCORPORATION - -from legal_api.models import Business, Filing, RegistrationBootstrap +from registry_schemas.example_data import ( + AMALGAMATION_APPLICATION, + ANNUAL_REPORT, + CORRECTION_AR, + COURT_ORDER_FILING_TEMPLATE, + FILING_HEADER, + FILING_TEMPLATE, + INCORPORATION +) + +from legal_api.models import Amalgamation, Business, Filing, RegistrationBootstrap from legal_api.services.authz import ACCOUNT_IDENTITY, PUBLIC_USER, STAFF_ROLE, SYSTEM_ROLE from legal_api.services import flags from legal_api.utils.datetime import datetime @@ -196,6 +203,60 @@ def test_get_business_info(app, session, client, jwt, requests_mock, test_name, assert registry_schemas.validate(rv.json, 'business') +@pytest.mark.parametrize('test_name,role,amalgamated', [ + ('regular', PUBLIC_USER, False), + ('amalgamated', PUBLIC_USER, True), +]) +def test_get_business_slim_info(app, session, client, jwt, requests_mock, test_name, role, amalgamated): + """Assert that the business slim info can be received with the expected data.""" + identifier = 'BC7654321' + legal_type = 'BC' + legal_name = identifier + ' legal name' + tax_id = '123' + business = factory_business_model(legal_name=legal_name, + legal_type=legal_type, + identifier=identifier, + founding_date=datetime.fromtimestamp(0), + last_ledger_timestamp=datetime.fromtimestamp(0), + last_modified=datetime.fromtimestamp(0), + fiscal_year_end_date=None, + tax_id=tax_id, + dissolution_date=None) + + if amalgamated: + filing = copy.deepcopy(FILING_TEMPLATE) + filing['filing'].pop('business') + filing['filing']['amalgamationApplication'] = copy.deepcopy(AMALGAMATION_APPLICATION) + filing['filing']['header']['name'] = 'amalgamationApplication' + filing = factory_completed_filing(business, filing) + business.state_filing_id = filing.id + business.state = 'HISTORICAL' + amalgamation = Amalgamation( + amalgamation_type=Amalgamation.AmalgamationTypes.regular, + business_id=business.id, + filing_id=filing.id, + amalgamation_date=datetime.utcnow(), + court_approval=True + ) + amalgamation.save() + business.save() + + # with patch('legal_api.services.warnings.business.business_checks.business.involuntary_dissolution_check', return_value=filing.id): + rv = client.get(f'/api/v2/businesses/{identifier}?slim=true' , + headers=create_header(jwt, [role], identifier)) + + print('business json', rv.json) + + assert rv.status_code == HTTPStatus.OK + assert rv.json['business']['identifier'] == identifier + assert rv.json['business']['legalType'] == legal_type + assert rv.json['business']['taxId'] == tax_id + assert rv.json['business'].get('state') is not None + assert rv.json['business'].get('goodStanding') is not None + if amalgamated: + assert rv.json['business'].get('amalgamatedInto') is not None + + @pytest.mark.parametrize('test_name, slim_version, auth_check_on', [ ('slim business request', True, True), ('regular business request', False, True), diff --git a/legal-api/tests/unit/resources/v2/test_business_filings/test_filings.py b/legal-api/tests/unit/resources/v2/test_business_filings/test_filings.py index 8836f1854a..bb0416fcc8 100644 --- a/legal-api/tests/unit/resources/v2/test_business_filings/test_filings.py +++ b/legal-api/tests/unit/resources/v2/test_business_filings/test_filings.py @@ -38,15 +38,19 @@ CHANGE_OF_OFFICERS, CONTINUATION_IN, CONTINUATION_IN_FILING_TEMPLATE, + CONTINUATION_OUT, CORRECTION_AR, CORRECTION_INCORPORATION, CP_SPECIAL_RESOLUTION_TEMPLATE, DISSOLUTION, FILING_HEADER, + FILING_TEMPLATE, INCORPORATION, INCORPORATION_FILING_TEMPLATE, + PUT_BACK_OFF, NOTICE_OF_WITHDRAWAL as SCHEMA_NOTICE_OF_WITHDRAWAL, REGISTRATION, + RESTORATION, SPECIAL_RESOLUTION, TRANSITION_FILING_TEMPLATE ) @@ -62,7 +66,7 @@ UserRoles, ) from legal_api.resources.v2.business.business_filings.business_filings import ListFilingResource -from legal_api.services.authz import BASIC_USER, STAFF_ROLE +from legal_api.services.authz import BASIC_USER, PUBLIC_USER, STAFF_ROLE from legal_api.services.bootstrap import RegistrationBootstrapService from legal_api.services.minio import MinioService from legal_api.utils.legislation_datetime import LegislationDatetime @@ -249,6 +253,51 @@ def test_get_one_business_filing_by_id_raw_json(session, client, jwt): assert rv.json['filing']['business'] == ANNUAL_REPORT['filing']['business'] +@pytest.mark.parametrize( + 'test_name, filing_name, filing', + [ + ('Annual Report', 'annualReport', ANNUAL_REPORT), + ('Dissolution', 'dissolution', DISSOLUTION), + ('Contintuation Out', 'continuationOut', CONTINUATION_OUT), + ('Resoration', 'restoration', RESTORATION), + ('Put back off', 'putBackOff', PUT_BACK_OFF), + ] +) +def test_get_one_business_filing_by_id_slim_json(session, client, jwt, test_name, filing_name, filing): + """Assert that the raw json originally submitted is returned.""" + identifier = 'CP7654321' + b = factory_business(identifier) + filing_json = copy.deepcopy(FILING_TEMPLATE) + filing_json['filing'].pop('business') + if filing_name not in filing.get('filing', {}): + filing_json['filing'][filing_name] = copy.deepcopy(filing) + else: + filing_json['filing'][filing_name] = copy.deepcopy(filing['filing'][filing_name]) + + filing_json['filing']['header']['name'] = filing_name + + filing = factory_filing(b, filing_json) + + rv = client.get(f'/api/v2/businesses/{identifier}/filings/{filing.id}?slim=true', + headers=create_header(jwt, [PUBLIC_USER], identifier)) + + assert rv.status_code == HTTPStatus.OK + assert rv.json['filing']['header']['name'] == filing_name + assert rv.json['filing']['header'].get('effectiveDate') is not None + assert rv.json['filing'].get(filing_name) is not None + if filing_name == 'dissolution': + assert rv.json['filing'][filing_name].get('dissolutionType') is not None + assert rv.json['filing'][filing_name].get('dissolutionDate') is not None + if filing_json['filing'][filing_name].get('type'): + assert rv.json['filing'][filing_name].get('type') is not None + if filing_json['filing'][filing_name].get('reason'): + assert rv.json['filing'][filing_name].get('reason') is not None + + assert not any([key for key in rv.json['filing'] if key not in ['header', filing_name]]) + assert not any([key for key in rv.json['filing']['header'] if key not in ['name', 'effectiveDate']]) + assert not any([key for key in rv.json['filing'][filing_name] if key not in ['dissolutionType', 'dissolutionDate', 'type', 'reason']]) + + def test_get_404_when_business_invalid_filing_id(session, client, jwt): """Assert that the business info cannot be received in a valid JSONSchema format.""" identifier = 'CP7654321' From 45957ef4cdc128a06a61811b226a6cffd7d16e8a Mon Sep 17 00:00:00 2001 From: Kial Jinnah Date: Fri, 19 Sep 2025 16:04:28 -0400 Subject: [PATCH 2/6] cleanup Signed-off-by: Kial Jinnah --- legal-api/src/legal_api/models/amalgamation.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/legal-api/src/legal_api/models/amalgamation.py b/legal-api/src/legal_api/models/amalgamation.py index f8c22655ba..7f024d7e8c 100644 --- a/legal-api/src/legal_api/models/amalgamation.py +++ b/legal-api/src/legal_api/models/amalgamation.py @@ -127,13 +127,11 @@ def get_revision_json(cls, transaction_id, business_id, tombstone=False): 'legalName': 'Not Available', 'amalgamationDate': 'Not Available' } - print(5) + amalgamation = Amalgamation.get_revision(transaction_id, business_id) - print(6) from .business import Business # pylint: disable=import-outside-toplevel - print(7) business = Business.find_by_internal_id(amalgamation.business_id) - print(8) + return { 'amalgamationDate': amalgamation.amalgamation_date.isoformat(), 'amalgamationType': amalgamation.amalgamation_type.name, From 3877e19a3de18b06324174559d5ac2f1bc2fadc8 Mon Sep 17 00:00:00 2001 From: Kial Jinnah Date: Fri, 19 Sep 2025 16:06:04 -0400 Subject: [PATCH 3/6] cleanup Signed-off-by: Kial Jinnah --- legal-api/src/legal_api/services/flags.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/legal-api/src/legal_api/services/flags.py b/legal-api/src/legal_api/services/flags.py index bc991aa958..156e1b84e8 100644 --- a/legal-api/src/legal_api/services/flags.py +++ b/legal-api/src/legal_api/services/flags.py @@ -76,15 +76,15 @@ def init_app(self, app): if self.sdk_key or app.env != 'production': self.logger.debug("sdk key used: %s", self.sdk_key) - config = Config(sdk_key=self.sdk_key) - # if app.env == 'production': - # config = Config(sdk_key=self.sdk_key) - # else: - # factory = FileDataSource.factory(paths=['flags.json'], - # auto_update=True) - # config = Config(sdk_key=self.sdk_key, - # update_processor_class=factory, - # send_events=False) + + if app.env == 'production': + config = Config(sdk_key=self.sdk_key) + else: + factory = FileDataSource.factory(paths=['flags.json'], + auto_update=True) + config = Config(sdk_key=self.sdk_key, + update_processor_class=factory, + send_events=False) ldclient_set_config(config) client = ldclient_get() From 3694235760df1917469890954324a97acdc4f89a Mon Sep 17 00:00:00 2001 From: Kial Jinnah Date: Mon, 22 Sep 2025 16:53:30 -0400 Subject: [PATCH 4/6] Reworked based on pr comment Signed-off-by: Kial Jinnah --- .../business_filings/business_filings.py | 72 +++++++++---------- .../v2/test_business_filings/test_filings.py | 7 +- 2 files changed, 37 insertions(+), 42 deletions(-) diff --git a/legal-api/src/legal_api/resources/v2/business/business_filings/business_filings.py b/legal-api/src/legal_api/resources/v2/business/business_filings/business_filings.py index cc21594c31..f8bad3d320 100644 --- a/legal-api/src/legal_api/resources/v2/business/business_filings/business_filings.py +++ b/legal-api/src/legal_api/resources/v2/business/business_filings/business_filings.py @@ -99,6 +99,20 @@ class FilingModel(GenericModel, Generic[FilingT]): def get_filings(identifier: str, filing_id: Optional[int] = None): """Return a JSON object with meta information about the Filing Submission.""" if filing_id or identifier.startswith('T'): + if str(request.args.get('public', None)).lower() == 'true': + return ListFilingResource.get_single_filing_public_json(filing_id) + + if flags.is_on('enable-auth-v2-filing') and not authorized(identifier, jwt, action=['view']): + current_app.logger.warning( + 'Unauthorized request for filing: %s, from username: %s, accountId: %s, app-name: %s', + identifier, + g.jwt_oidc_token_info.get('preferred_username'), + request.args.get('account'), + request.headers.get('app-name')) + return jsonify({'message': + f'You are not authorized to view filing {identifier}.'}), \ + HTTPStatus.UNAUTHORIZED + return ListFilingResource.get_single_filing(identifier, filing_id) return ListFilingResource.get_ledger_listing(identifier, jwt) @@ -292,6 +306,27 @@ def get_single_filing_by_filing_id(filing_id): class ListFilingResource(): # pylint: disable=too-many-public-methods """Business Filings service.""" + @staticmethod + def get_single_filing_public_json(filing_id: int): + """Return public details of a filing.""" + filing: Filing = Filing.find_by_id(filing_id) + if not filing or not (filing_name := filing.filing_type): + return jsonify({'message': f'Filing {filing_id} not found'}), HTTPStatus.NOT_FOUND + + filing_json = {'header': {'name': filing_name}, filing_name: {}} + + if effective_date := filing.effective_date: + filing_json['header']['effectiveDate'] = effective_date.isoformat() + + if sub_type := filing.filing_sub_type: + filing_json[filing_name]['type'] = sub_type + + if filing.filing_json and (reason := filing.filing_json.get('filing', {}).get(filing_name, {}).get('reason')): + filing_json[filing_name]['reason'] = reason + + return jsonify({'filing': filing_json}) + + @staticmethod def get_single_filing(identifier: str, filing_id: int): """Return a single filing and all of its components.""" @@ -300,43 +335,6 @@ def get_single_filing(identifier: str, filing_id: int): if not rv: return jsonify({'message': f'{identifier} no filings found'}), HTTPStatus.NOT_FOUND - if str(request.args.get('slim', None)).lower() == 'true': - # only return publicly accessible data - if str(request.accept_mimetypes) == 'application/pdf': - return jsonify({'message': 'A slim version of the filing pdf is not available.'}), HTTPStatus.BAD_REQUEST - - def get_redacted_json(json: dict[str, Any], allowed_keys: list[str]): - """Return the json with only the specified allowed_keys.""" - return {key: json[key] for key in allowed_keys if json.get(key)} - - filing_json = rv.json - filing_name = filing_json['filing']['header']['name'] - - # only need 'header' and '' sections from 'filing' - public_root_filing_keys = ['header', filing_name] - filing_json['filing'] = get_redacted_json(filing_json['filing'], public_root_filing_keys) - - # only need 'name' and 'effectiveDate' from 'header' - public_header_keys = ['name', 'effectiveDate'] - filing_json['filing']['header'] = get_redacted_json(filing_json['filing']['header'], public_header_keys) - - # only need the following keys when they are available in the nested filing info - public_filing_keys = ['dissolutionType', 'dissolutionDate', 'type', 'reason'] - filing_json['filing'][filing_name] = get_redacted_json(filing_json['filing'][filing_name], public_filing_keys) - - return jsonify(filing_json) - - if flags.is_on('enable-auth-v2-filing') and not authorized(identifier, jwt, action=['view']): - current_app.logger.warning( - 'Unauthorized request for filing: %s, from username: %s, accountId: %s, app-name: %s', - identifier, - g.jwt_oidc_token_info.get('preferred_username'), - request.args.get('account'), - request.headers.get('app-name')) - return jsonify({'message': - f'You are not authorized to view filing {identifier}.'}), \ - HTTPStatus.UNAUTHORIZED - if original_filing: return jsonify(rv.redacted(rv.raw, jwt)) diff --git a/legal-api/tests/unit/resources/v2/test_business_filings/test_filings.py b/legal-api/tests/unit/resources/v2/test_business_filings/test_filings.py index bb0416fcc8..ce93a011fa 100644 --- a/legal-api/tests/unit/resources/v2/test_business_filings/test_filings.py +++ b/legal-api/tests/unit/resources/v2/test_business_filings/test_filings.py @@ -263,7 +263,7 @@ def test_get_one_business_filing_by_id_raw_json(session, client, jwt): ('Put back off', 'putBackOff', PUT_BACK_OFF), ] ) -def test_get_one_business_filing_by_id_slim_json(session, client, jwt, test_name, filing_name, filing): +def test_get_one_business_filing_by_id_public_json(session, client, jwt, test_name, filing_name, filing): """Assert that the raw json originally submitted is returned.""" identifier = 'CP7654321' b = factory_business(identifier) @@ -278,16 +278,13 @@ def test_get_one_business_filing_by_id_slim_json(session, client, jwt, test_name filing = factory_filing(b, filing_json) - rv = client.get(f'/api/v2/businesses/{identifier}/filings/{filing.id}?slim=true', + rv = client.get(f'/api/v2/businesses/{identifier}/filings/{filing.id}?public=true', headers=create_header(jwt, [PUBLIC_USER], identifier)) assert rv.status_code == HTTPStatus.OK assert rv.json['filing']['header']['name'] == filing_name assert rv.json['filing']['header'].get('effectiveDate') is not None assert rv.json['filing'].get(filing_name) is not None - if filing_name == 'dissolution': - assert rv.json['filing'][filing_name].get('dissolutionType') is not None - assert rv.json['filing'][filing_name].get('dissolutionDate') is not None if filing_json['filing'][filing_name].get('type'): assert rv.json['filing'][filing_name].get('type') is not None if filing_json['filing'][filing_name].get('reason'): From 5b91add6a76a0f0f8590b81620920e1fa5e66852 Mon Sep 17 00:00:00 2001 From: Kial Jinnah Date: Mon, 22 Sep 2025 17:02:21 -0400 Subject: [PATCH 5/6] cleanup Signed-off-by: Kial Jinnah --- .../resources/v2/business/business_filings/business_filings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/legal-api/src/legal_api/resources/v2/business/business_filings/business_filings.py b/legal-api/src/legal_api/resources/v2/business/business_filings/business_filings.py index f8bad3d320..5b038c829c 100644 --- a/legal-api/src/legal_api/resources/v2/business/business_filings/business_filings.py +++ b/legal-api/src/legal_api/resources/v2/business/business_filings/business_filings.py @@ -20,7 +20,7 @@ from contextlib import suppress from datetime import datetime as _datetime from http import HTTPStatus -from typing import Any, Generic, Optional, Tuple, TypeVar, Union +from typing import Generic, Optional, Tuple, TypeVar, Union import requests # noqa: I001; grouping out of order to make both pylint & isort happy from requests import exceptions # noqa: I001; grouping out of order to make both pylint & isort happy From 4c6fdb3c9d6dc2dc0c8ecb7dbe6d6a41b9aad85a Mon Sep 17 00:00:00 2001 From: Kial Jinnah Date: Tue, 23 Sep 2025 09:30:04 -0400 Subject: [PATCH 6/6] Update putBackOff value collection Signed-off-by: Kial Jinnah --- .../business_filings/business_filings.py | 5 ++++- .../v2/test_business_filings/test_filings.py | 20 ++++++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/legal-api/src/legal_api/resources/v2/business/business_filings/business_filings.py b/legal-api/src/legal_api/resources/v2/business/business_filings/business_filings.py index 5b038c829c..fdb2ba485b 100644 --- a/legal-api/src/legal_api/resources/v2/business/business_filings/business_filings.py +++ b/legal-api/src/legal_api/resources/v2/business/business_filings/business_filings.py @@ -321,9 +321,12 @@ def get_single_filing_public_json(filing_id: int): if sub_type := filing.filing_sub_type: filing_json[filing_name]['type'] = sub_type - if filing.filing_json and (reason := filing.filing_json.get('filing', {}).get(filing_name, {}).get('reason')): + if filing.meta_data and (reason := filing.meta_data.get(filing_name, {}).get('reason')): filing_json[filing_name]['reason'] = reason + if filing.meta_data and (expiryDate := filing.meta_data.get(filing_name, {}).get('expiryDate')): + filing_json[filing_name]['expiryDate'] = expiryDate + return jsonify({'filing': filing_json}) diff --git a/legal-api/tests/unit/resources/v2/test_business_filings/test_filings.py b/legal-api/tests/unit/resources/v2/test_business_filings/test_filings.py index ce93a011fa..a9e9b7721c 100644 --- a/legal-api/tests/unit/resources/v2/test_business_filings/test_filings.py +++ b/legal-api/tests/unit/resources/v2/test_business_filings/test_filings.py @@ -17,6 +17,7 @@ Test-Suite to ensure that the /businesses endpoint is working as expected. """ import copy +import json from datetime import datetime, timedelta, timezone from http import HTTPStatus from typing import Final @@ -277,6 +278,18 @@ def test_get_one_business_filing_by_id_public_json(session, client, jwt, test_na filing_json['filing']['header']['name'] = filing_name filing = factory_filing(b, filing_json) + expected_expiry_date = (datetime.now()).isoformat() + expected_reason = 'Limited Restoration Expired' + if filing_name == 'putBackOff': + # Filer adds these values into the meta_data so we need to do this manually here as part of the setup + filing._meta_data = json.loads(json.dumps( + { + filing_name: { + 'expiryDate': expected_expiry_date, + 'reason': expected_reason + } + })) + filing.save() rv = client.get(f'/api/v2/businesses/{identifier}/filings/{filing.id}?public=true', headers=create_header(jwt, [PUBLIC_USER], identifier)) @@ -287,12 +300,13 @@ def test_get_one_business_filing_by_id_public_json(session, client, jwt, test_na assert rv.json['filing'].get(filing_name) is not None if filing_json['filing'][filing_name].get('type'): assert rv.json['filing'][filing_name].get('type') is not None - if filing_json['filing'][filing_name].get('reason'): - assert rv.json['filing'][filing_name].get('reason') is not None + if filing_name == 'putBackOff': + assert rv.json['filing'][filing_name].get('reason') == expected_reason + assert rv.json['filing'][filing_name].get('expiryDate') == expected_expiry_date assert not any([key for key in rv.json['filing'] if key not in ['header', filing_name]]) assert not any([key for key in rv.json['filing']['header'] if key not in ['name', 'effectiveDate']]) - assert not any([key for key in rv.json['filing'][filing_name] if key not in ['dissolutionType', 'dissolutionDate', 'type', 'reason']]) + assert not any([key for key in rv.json['filing'][filing_name] if key not in ['expiryDate', 'type', 'reason']]) def test_get_404_when_business_invalid_filing_id(session, client, jwt):