Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion legal-api/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "legal-api"
version = "3.1.11"
version = "3.1.12"
description = ""
authors = [
{name = "thor",email = "1042854+thorwolpert@users.noreply.github.com"}
Expand Down
7 changes: 7 additions & 0 deletions legal-api/src/legal_api/services/authz.py
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,13 @@ def get_allowable_filings_dict(is_authorization: bool = False):
}
},
Business.State.HISTORICAL: {
"correction": {
"legalTypes": ["BEN", "BC", "ULC", "CC", "C", "CBEN", "CUL", "CCC"],
"blockerChecks": {
"warningTypes": [WarningType.MISSING_REQUIRED_BUSINESS_INFO],
"business": [BusinessBlocker.DEFAULT]
}
},
"courtOrder": {
"legalTypes": ["SP", "GP", "CP", "BC", "BEN", "CC", "ULC", "C", "CBEN", "CUL", "CCC"],
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def validate(business: Business, filing: dict) -> Error | None:
is_valid_co_date = True
is_valid_foreign_jurisdiction = True

if err := validate_amalgamation_out_date(filing, filing_type):
if err := validate_amalgamation_out_date(filing, f"/filing/{filing_type}/amalgamationOutDate"):
msg.extend(err)
is_valid_co_date = False

Expand Down Expand Up @@ -96,10 +96,9 @@ def validate_active_cao(business: Business, filing: dict, filing_type: str) -> l
return msg


def validate_amalgamation_out_date(filing: dict, filing_type: str) -> list:
def validate_amalgamation_out_date(filing: dict, amalgamation_out_date_path: str) -> list:
"""Validate amalgamation out date."""
msg = []
amalgamation_out_date_path = f"/filing/{filing_type}/amalgamationOutDate"
amalgamation_out_date = get_date(filing, amalgamation_out_date_path)

now = LegislationDatetime.now().date()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,11 @@ def validate(business: Business, filing: dict) -> Error | None:
msg = []
filing_type = "continuationOut"


if err := validate_continuation_out_date(filing, filing_type):
msg.extend(err)

if err := validate_foreign_jurisdiction(filing["filing"][filing_type]["foreignJurisdiction"],
f"/filing/{filing_type}/foreignJurisdiction"):
msg.extend(err)
msg.extend(validate_continuation_out_date(filing, f"/filing/{filing_type}/continuationOutDate"))
msg.extend(validate_foreign_jurisdiction(
filing["filing"][filing_type]["foreignJurisdiction"],
f"/filing/{filing_type}/foreignJurisdiction"
))

if court_order := filing.get("filing", {}).get(filing_type, {}).get("courtOrder", None):
court_order_path: Final = f"/filing/{filing_type}/courtOrder"
Expand All @@ -60,10 +58,9 @@ def validate(business: Business, filing: dict) -> Error | None:
return None


def validate_continuation_out_date(filing: dict, filing_type: str) -> list:
def validate_continuation_out_date(filing: dict, continuation_out_date_path: str) -> list:
"""Validate continuation out date."""
msg = []
continuation_out_date_path = f"/filing/{filing_type}/continuationOutDate"
continuation_out_date = get_date(filing, continuation_out_date_path)

now = LegislationDatetime.now().date()
Expand Down
37 changes: 30 additions & 7 deletions legal-api/src/legal_api/services/filings/validations/correction.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@
from legal_api.errors import Error
from legal_api.services import STAFF_ROLE, SYSTEM_ROLE, NaicsService
from legal_api.services.filings.validations.alteration import validate_type_change
from legal_api.services.filings.validations.amalgamation_out import validate_amalgamation_out_date
from legal_api.services.filings.validations.common_validations import (
validate_court_order,
validate_foreign_jurisdiction,
validate_name_request,
validate_offices_addresses,
validate_parties_addresses,
Expand All @@ -41,6 +43,7 @@
validate_continuation_in_foreign_jurisdiction,
validate_continuation_in_xpro_business_in_colin,
)
from legal_api.services.filings.validations.continuation_out import validate_continuation_out_date
from legal_api.services.filings.validations.incorporation_application import (
validate_coop_parties_mailing_address,
validate_roles,
Expand Down Expand Up @@ -84,6 +87,11 @@ def validate(business: Business, filing: dict) -> Error:
path = "/filing/correction/correctedFilingId"
msg.append({"error": _("Corrected filing is not a valid filing for this business."), "path": path})

elif corrected_filing.filing_type != filing["filing"]["correction"]["correctedFilingType"]:
path = "/filing/correction/correctedFilingType"
msg.append({"error": _("The corrected filing type does not match filing type of corrected filing."),
"path": path})

# skip all the other validation checks if comment only correction
if not is_comment_only_correction:
if filing.get("filing", {}).get("correction", {}).get("parties", None):
Expand All @@ -105,19 +113,22 @@ def validate(business: Business, filing: dict) -> Error:
))
if filing.get("filing", {}).get("correction", {}).get("offices", None):
msg.extend(validate_offices_addresses(filing, filing_type))
# validations for firms
if business.legal_type in [Business.LegalTypes.SOLE_PROP.value, Business.LegalTypes.PARTNERSHIP.value]:
_validate_firms_correction(business, filing, business.legal_type, msg)
elif business.legal_type in Business.CORPS:
_validate_corps_correction(business, filing, business.legal_type, msg)
elif business.legal_type == Business.LegalTypes.COOP.value:
_validate_special_resolution_correction(filing, business.legal_type, msg)

_validate_type_specific_props(business, filing, msg)

if msg:
return Error(HTTPStatus.BAD_REQUEST, msg)

return None

def _validate_type_specific_props(business: Business, filing: dict, msg: list):
if business.legal_type in [Business.LegalTypes.SOLE_PROP.value, Business.LegalTypes.PARTNERSHIP.value]:
_validate_firms_correction(business, filing, business.legal_type, msg)
elif business.legal_type in Business.CORPS:
_validate_corps_correction(business, filing, business.legal_type, msg)
elif business.legal_type == Business.LegalTypes.COOP.value:
_validate_special_resolution_correction(filing, business.legal_type, msg)


def _validate_firms_correction(business: Business, filing, legal_type, msg):
filing_type = "correction"
Expand Down Expand Up @@ -160,6 +171,7 @@ def _validate_corps_correction(business: Business, filing_dict, legal_type, msg)
msg.extend(validate_resolution_date_in_share_structure(filing_dict, filing_type, business))

msg.extend(_validate_continuation_in_correction(filing_dict, filing_type, legal_type))
msg.extend(_validate_out_correction(filing_dict, filing_type))


def _validate_continuation_in_correction(filing_dict, filing_type, legal_type):
Expand All @@ -179,6 +191,17 @@ def _validate_continuation_in_correction(filing_dict, filing_type, legal_type):
return msg


def _validate_out_correction(filing_dict, filing_type):
msg = []
if continuation_out := filing_dict["filing"][filing_type].get("continuationOut"):
msg.extend(validate_continuation_out_date(filing_dict, f"/filing/{filing_type}/continuationOut/date"))
msg.extend(validate_foreign_jurisdiction(continuation_out, f"/filing/{filing_type}/continuationOut"))
elif amalgamation_out := filing_dict["filing"][filing_type].get("amalgamationOut"):
msg.extend(validate_amalgamation_out_date(filing_dict, f"/filing/{filing_type}/amalgamationOut/date"))
msg.extend(validate_foreign_jurisdiction(amalgamation_out, f"/filing/{filing_type}/amalgamationOut"))
return msg


def _validate_special_resolution_correction(filing_dict, legal_type, msg):
filing_type = "correction"
if filing_dict.get("filing", {}).get(filing_type, {}).get("nameRequest", {}).get("nrNumber", None):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ def test_valid_firms_correction(app, session, jwt, test_name, filing):

f['filing']['header']['identifier'] = identifier
f['filing']['correction']['correctedFilingId'] = corrected_filing.id
f['filing']['correction']['correctedFilingType'] = 'changeOfRegistration'

nr_res = copy.deepcopy(nr_response)
nr_res['legalType'] = legal_type
Expand Down Expand Up @@ -121,6 +122,7 @@ def test_firms_correction_invalid_parties(app, session, jwt, test_name, filing,

f['filing']['header']['identifier'] = identifier
f['filing']['correction']['correctedFilingId'] = corrected_filing.id
f['filing']['correction']['correctedFilingType'] = 'changeOfRegistration'

del f['filing']['correction']['parties'][0]['roles'][0]
nr_res = copy.deepcopy(nr_response)
Expand Down Expand Up @@ -189,6 +191,7 @@ def test_firms_correction_naics(app, session, jwt, test_name, filing, existing_n

f['filing']['header']['identifier'] = identifier
f['filing']['correction']['correctedFilingId'] = corrected_filing.id
f['filing']['correction']['correctedFilingType'] = 'changeOfRegistration'
if correction_naics_code:
f['filing']['correction']['business']['naics']['naicsCode'] = correction_naics_code
else:
Expand Down Expand Up @@ -252,6 +255,7 @@ def test_firms_correction_start_date(app, session, jwt, test_name, filing, usern

f['filing']['header']['identifier'] = identifier
f['filing']['correction']['correctedFilingId'] = corrected_filing.id
f['filing']['correction']['correctedFilingType'] = 'changeOfRegistration'
f['filing']['correction']['startDate'] = start_date.strftime('%Y-%m-%d')

nr_res = copy.deepcopy(nr_response)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import copy
import datedelta
import pycountry
from datetime import datetime, timezone
from freezegun import freeze_time
from http import HTTPStatus
Expand All @@ -23,13 +24,17 @@
import pytest

from business_model.models import Business, Resolution
from business_common.utils.legislation_datetime import LegislationDatetime
from business_common.utils.datetime import datetime as dt, timedelta
from legal_api.services import NameXService
from legal_api.services.authz import BASIC_USER, STAFF_ROLE
from legal_api.services.filings import validate
from registry_schemas.example_data import (
CORRECTION_INCORPORATION,
AMALGAMATION_OUT,
CORRECTION_INCORPORATION,
CONTINUATION_IN_FILING_TEMPLATE,
CONTINUATION_OUT,
FILING_HEADER,
INCORPORATION_FILING_TEMPLATE
)

Expand All @@ -39,6 +44,7 @@
from tests.unit.services.utils import jwt_request_context


date_format = '%Y-%m-%d'
INCORPORATION_APPLICATION = copy.deepcopy(INCORPORATION_FILING_TEMPLATE)
CORRECTION = copy.deepcopy(CORRECTION_INCORPORATION)

Expand Down Expand Up @@ -808,3 +814,108 @@ def test_validate_continuation_in_xpro_founding_date_match(mocker, app, session,
err = validate(business, filing)
assert not err


@pytest.mark.parametrize('filing_type', ['continuationOut', 'amalgamationOut'])
@pytest.mark.parametrize(
'test_name, expected_code, message',
[
('FAIL_IN_FUTURE', HTTPStatus.BAD_REQUEST, '{0} out date must be today or past.'),
('SUCCESS_NO_CCO', None, None),
('SUCCESS', None, None)
]
)
def test_validate_continuation_out_date(session, app, jwt, filing_type, test_name, expected_code, message):
"""Assert validate continuation_out_date."""
identifier = 'BC1234567'
business = factory_business(identifier, entity_type='BC')
continuation_out_filing = copy.deepcopy(FILING_HEADER)
continuation_out_filing['filing'][filing_type] = copy.deepcopy(CONTINUATION_OUT if filing_type == 'continuationOut' else AMALGAMATION_OUT)
continuation_out_filing['filing']['header']['name'] = filing_type

corrected_filing = factory_completed_filing(business, continuation_out_filing)


filing = copy.deepcopy(CORRECTION)
filing['filing']['header']['identifier'] = identifier
filing['filing']['correction']['correctedFilingId'] = corrected_filing.id
filing['filing']['correction']['correctedFilingType'] = filing_type
filing['filing']['correction'][filing_type] = {
'country': 'CA',
'region': 'AB',
'legalName': 'HAULER SERVICES',
'date': '2023-06-19'
}
del filing['filing']['correction']['commentOnly']

if test_name == 'FAIL_IN_FUTURE':
filing['filing']['correction'][filing_type]['date'] = \
(LegislationDatetime.now() + datedelta.datedelta(days=1)).strftime(date_format)

with jwt_request_context(app, jwt, [BASIC_USER]):
err = validate(business, filing)

# validate outcomes
if test_name == 'FAIL_IN_FUTURE':
assert expected_code == err.code
assert message.format(filing_type.replace('Out', '').capitalize()) == err.msg[0]['error']
else:
assert not err


@pytest.mark.parametrize('filing_type', ['continuationOut', 'amalgamationOut'])
@pytest.mark.parametrize(
'test_name, expected_code, message',
[
('FAIL_NO_COUNTRY', HTTPStatus.UNPROCESSABLE_ENTITY, None),
('FAIL_INVALID_COUNTRY', HTTPStatus.BAD_REQUEST, 'Invalid country.'),
('FAIL_REGION_BC', HTTPStatus.BAD_REQUEST, 'Region should not be BC.'),
('FAIL_INVALID_REGION', HTTPStatus.BAD_REQUEST, 'Invalid region.'),
('FAIL_INVALID_US_REGION', HTTPStatus.BAD_REQUEST, 'Invalid region.'),
('SUCCESS', None, None)
]
)
def test_validate_continuation_out_foreign_jurisdiction(session, app, jwt, filing_type, test_name, expected_code, message):
"""Assert validate continuation_out foreign jurisdiction."""
identifier = 'BC1234567'
business = factory_business(identifier, entity_type='BC')
continuation_out_filing = copy.deepcopy(FILING_HEADER)
continuation_out_filing['filing'][filing_type] = copy.deepcopy(CONTINUATION_OUT if filing_type == 'continuationOut' else AMALGAMATION_OUT)
continuation_out_filing['filing']['header']['name'] = filing_type

corrected_filing = factory_completed_filing(business, continuation_out_filing)

filing = copy.deepcopy(CORRECTION)
filing['filing']['header']['identifier'] = identifier
filing['filing']['correction']['correctedFilingId'] = corrected_filing.id
filing['filing']['correction']['correctedFilingType'] = filing_type
filing['filing']['correction'][filing_type] = {
'country': 'CA',
'region': 'AB',
'legalName': 'HAULER SERVICES',
'date': '2023-06-19'
}
del filing['filing']['correction']['commentOnly']


if test_name == 'FAIL_NO_COUNTRY':
del filing['filing']['correction'][filing_type]['country']
elif test_name == 'FAIL_INVALID_COUNTRY':
filing['filing']['correction'][filing_type]['country'] = 'NONE'
elif test_name == 'FAIL_REGION_BC':
filing['filing']['correction'][filing_type]['region'] = 'BC'
elif test_name == 'FAIL_INVALID_REGION':
filing['filing']['correction'][filing_type]['region'] = 'NONE'
elif test_name == 'FAIL_INVALID_US_REGION':
filing['filing']['correction'][filing_type]['country'] = 'US'
filing['filing']['correction'][filing_type]['region'] = 'NONE'

with jwt_request_context(app, jwt, [BASIC_USER]):
err = validate(business, filing)

# validate outcomes
if test_name != 'SUCCESS':
assert expected_code == err.code
if message:
assert message == err.msg[0]['error']
else:
assert not err
Loading