Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

24987 24989 - Update to enable NoW for temporary businesses #3155

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,8 @@ def put_basic_checks(identifier, filing, client_request, business) -> Tuple[dict
if not filing_type:
return ({'message': 'filing/header/name is a required property'}, HTTPStatus.BAD_REQUEST)

if filing_type not in CoreFiling.NEW_BUSINESS_FILING_TYPES and business is None:
if filing_type not in CoreFiling.NEW_BUSINESS_FILING_TYPES + [CoreFiling.FilingTypes.NOTICEOFWITHDRAWAL] \
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

allow filing NoW without an existing business

and business is None:
return ({'message': 'A valid business is required.'}, HTTPStatus.BAD_REQUEST)

if client_request.method == 'PUT' and not filing:
Expand All @@ -497,9 +498,14 @@ def check_authorization(identifier, filing_json: dict,

# While filing IA business object will be None. Setting default values in that case.
state = business.state if business else Business.State.ACTIVE
if business:
legal_type = business.legal_type
# for temporary business notice of withdraw, get legalType from filing json
elif filing_type == CoreFiling.FilingTypes.NOTICEOFWITHDRAWAL.value:
legal_type = filing_json['filing'].get('business', None).get('legalType')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this work if the NoW is for a regular business? (eg, withdrawing a FE alteration)

# for incorporationApplication and registration, get legalType from nameRequest
legal_type = business.legal_type if business else \
filing_json['filing'][filing_type]['nameRequest'].get('legalType')
else:
legal_type = filing_json['filing'][filing_type]['nameRequest'].get('legalType')

if not authorized(identifier, jwt, action=['edit']) or \
not is_allowed(business, state, filing_type, legal_type, jwt, filing_sub_type, filing):
Expand Down Expand Up @@ -668,6 +674,9 @@ def get_filing_types(business: Business, filing_json: dict): # pylint: disable=

if filing_type in CoreFiling.NEW_BUSINESS_FILING_TYPES:
legal_type = filing_json['filing'][filing_type]['nameRequest']['legalType']
elif business.identifier.startswith('T') and \
filing_type == CoreFiling.FilingTypes.NOTICEOFWITHDRAWAL:
legal_type = filing_json['filing'].get('business', None).get('legalType')
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for temporary business notice of withdraw, get legalType from filing json

else:
legal_type = business.legal_type

Expand Down Expand Up @@ -826,6 +835,12 @@ def create_invoice(business: Business, # pylint: disable=too-many-locals,too-ma
mailing_address = business.mailing_address.one_or_none()
corp_type = business.legal_type if business.legal_type else \
filing.json['filing']['business'].get('legalType')
# deal with withdrawing a new business filing
elif business.identifier.startswith('T') and \
filing.filing_type == Filing.FILINGS['noticeOfWithdrawal']['name']:
mailing_address, corp_type, legal_name = \
ListFilingResource._get_address_from_withdrawn_new_business_filing(business, filing)
business.legal_name = legal_name
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for temporary business notice of withdraw, get mailng_address, corp_type, legal_name from the withdrawn new business filing (e.g. IA, Continuation In, Amalgamation)

else:
mailing_address = business.mailing_address.one_or_none()
corp_type = business.legal_type if business.legal_type else \
Expand Down Expand Up @@ -1044,3 +1059,27 @@ def submit_filing_for_review(filing: Filing):
{'email': {'filingId': filing.id, 'type': filing.filing_type, 'option': review.status}},
current_app.config.get('NATS_EMAILER_SUBJECT')
)

@staticmethod
def _get_address_from_withdrawn_new_business_filing(business: Business, filing: Filing):
if filing.filing_type != CoreFiling.FilingTypes.NOTICEOFWITHDRAWAL.value:
return None, None, None
withdrawn_filing_id = filing.filing_json['filing']['noticeOfWithdrawal']['filingId']
withdrawn_filing = Filing.find_by_id(withdrawn_filing_id)
if withdrawn_filing.filing_type in CoreFiling.NEW_BUSINESS_FILING_TYPES:
office_type = OfficeType.REGISTERED
if withdrawn_filing.filing_type == Filing.FILINGS['registration']['name']:
office_type = OfficeType.BUSINESS

mailing_address = Address.create_address(
withdrawn_filing.json['filing'][withdrawn_filing.filing_type]['offices'][office_type]['mailingAddress'])
corp_type = withdrawn_filing.json['filing'][withdrawn_filing.filing_type]['nameRequest'].get(
'legalType', Business.LegalTypes.BCOMP.value)

try:
legal_name = withdrawn_filing.json['filing'][withdrawn_filing.filing_type]['nameRequest']['legalName']
except KeyError:
legal_name = business.identifier

return mailing_address, corp_type, legal_name
return None, None, None
3 changes: 2 additions & 1 deletion legal-api/src/legal_api/services/authz.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,8 @@ def get_allowable_filings_dict():
'legalTypes': ['BC', 'BEN', 'CC', 'ULC', 'C', 'CBEN', 'CUL', 'CCC'],
'blockerChecks': {
'business': [BusinessBlocker.FILING_WITHDRAWAL]
}
},
'businessRequirement': BusinessRequirement.NO_RESTRICTION
Copy link
Collaborator Author

@eason-pan-bc eason-pan-bc Dec 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Allow NoW filing no matter there is an existing business or not for staff

}
},
Business.State.HISTORICAL: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,11 @@ def validate(filing: Dict) -> Optional[Error]:
msg.append({'error': babel('Filing Id is required.'), 'path': withdrawn_filing_id_path})
return msg # cannot continue validation without the to be withdrawn filing id

err = validate_withdrawn_filing(withdrawn_filing_id)
if err:
msg.extend(err)
is_not_found, err_msg = validate_withdrawn_filing(withdrawn_filing_id)
if is_not_found:
return Error(HTTPStatus.NOT_FOUND, err_msg)
if err_msg and not is_not_found:
msg.extend(err_msg)

if msg:
return Error(HTTPStatus.BAD_REQUEST, msg)
Expand All @@ -49,12 +51,14 @@ def validate(filing: Dict) -> Optional[Error]:
def validate_withdrawn_filing(withdrawn_filing_id: int):
"""Validate the to be withdrawn filing id exists, the filing has a FED, the filing status is PAID."""
msg = []
is_not_found = False
# check whether the filing ID exists
withdrawn_filing = db.session.query(Filing). \
filter(Filing.id == withdrawn_filing_id).one_or_none()
if not withdrawn_filing:
msg.append({'error': babel('The filing to be withdrawn cannot be found.')})
return msg # cannot continue if the withdrawn filing doesn't exist
is_not_found = True
return is_not_found, msg # cannot continue if the withdrawn filing doesn't exist

# check whether the filing has a Future Effective Date(FED)
now = dt.utcnow()
Expand All @@ -68,5 +72,5 @@ def validate_withdrawn_filing(withdrawn_filing_id: int):
msg.append({'error': babel('Only paid filings with a future effective date can be withdrawn.')})

if msg:
return msg
return None
return is_not_found, msg
return None, None
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
Test-Suite to ensure that the /businesses endpoint is working as expected.
"""
import copy
from datetime import datetime, timezone
from datetime import datetime, timedelta, timezone
from http import HTTPStatus
from typing import Final
from unittest.mock import patch
Expand All @@ -44,6 +44,7 @@
FILING_HEADER,
INCORPORATION,
INCORPORATION_FILING_TEMPLATE,
NOTICE_OF_WITHDRAWAL as SCHEMA_NOTICE_OF_WITHDRAWAL,
REGISTRATION,
SPECIAL_RESOLUTION,
TRANSITION_FILING_TEMPLATE
Expand Down Expand Up @@ -1595,3 +1596,64 @@ def test_resubmit_filing_failed(session, client, jwt, filing_status, review_stat
headers=create_header(jwt, [STAFF_ROLE], identifier))

assert rv.status_code == HTTPStatus.UNAUTHORIZED

@pytest.mark.parametrize(
'legal_type, filing_type, filing_json',
[
('BC', 'incorporationApplication', INCORPORATION),
('BEN', 'continuationIn', CONTINUATION_IN),
('CBEN', 'amalgamationApplication', AMALGAMATION_APPLICATION)
]
)
def test_notice_of_withdraw_filing_temporary_businesses(session, client, jwt, legal_type, filing_type, filing_json):
"""Assert that notice of withdraw for new business filings can be filed"""
# create a FE new business filing
today = datetime.utcnow().date()
future_effective_date = today + timedelta(days=5)
future_effective_date = future_effective_date.isoformat()
identifier = 'Tb31yQIuBw'
temp_reg = RegistrationBootstrap()
temp_reg._identifier = identifier
temp_reg.save()
json_data = copy.deepcopy(FILING_HEADER)
json_data['filing']['header']['name'] = filing_type
del json_data['filing']['business']
filing_json = copy.deepcopy(filing_json)
filing_json['nameRequest']['legalType'] = legal_type
json_data['filing'][filing_type] = filing_json
new_business_filing = factory_pending_filing(None, json_data)
new_business_filing.temp_reg = identifier
new_business_filing.effective_date = future_effective_date
new_business_filing.payment_completion_date = datetime.utcnow().isoformat()
new_business_filing.save()
withdrawn_filing_id = new_business_filing.id

# test filing a notice of withdraw for a temporary business
now_json_data = copy.deepcopy(FILING_HEADER)
now_json_data['filing']['header']['name'] = 'noticeOfWithdrawal'
del now_json_data['filing']['business']
now_json_data['filing']['business'] = {
"identifier": identifier,
"legalType": legal_type
}
now_json_data['filing']['noticeOfWithdrawal'] = copy.deepcopy(SCHEMA_NOTICE_OF_WITHDRAWAL)
now_json_data['filing']['noticeOfWithdrawal']['filingId'] = withdrawn_filing_id
del now_json_data['filing']['header']['filingId']
print(now_json_data)

# Test validation OK
rv_validation = client.post(f'/api/v2/businesses/{identifier}/filings?only_validate=true',
json=now_json_data,
headers=create_header(jwt, [STAFF_ROLE], identifier))

assert rv_validation.status_code == HTTPStatus.OK
assert rv_validation.json['filing']['header']['name'] == 'noticeOfWithdrawal'

# Test can create a draft
rv_draft = client.post(f'/api/v2/businesses/{identifier}/filings?draft=true',
json=now_json_data,
headers=create_header(jwt, [STAFF_ROLE], identifier))

# validate
assert rv_draft.status_code == HTTPStatus.CREATED
assert rv_draft.json['filing']['header']['name'] == 'noticeOfWithdrawal'
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
('EXIST_BUSINESS_SUCCESS', True, Filing.Status.PAID, True, True, None, None),
('EXIST_BUSINESS_FAIL_NOT_PAID', True, Filing.Status.PENDING, True, True, HTTPStatus.BAD_REQUEST, [FILING_NOT_PAID_MSG]),
('EXIST_BUSINESS_FAIL_NOT_FED', True, Filing.Status.PAID, False, True, HTTPStatus.BAD_REQUEST, [FILING_NOT_FED_MSG]),
('EXIST_BUSINESS_FAIL_FILING_NOT_EXIST', False, Filing.Status.PAID, True, True, HTTPStatus.BAD_REQUEST, [FILING_NOT_EXIST_MSG]),
('EXIST_BUSINESS_FAIL_FILING_NOT_EXIST', False, Filing.Status.PAID, True, True, HTTPStatus.NOT_FOUND, [FILING_NOT_EXIST_MSG]),
('EXIST_BUSINESS_FAIL_MISS_FILING_ID', True, Filing.Status.PAID, True, False, HTTPStatus.UNPROCESSABLE_ENTITY, ''),
('EXIST_BUSINESS_FAIL_NOT_PAID_NOT_FED', True, Filing.Status.PENDING, False, True, HTTPStatus.BAD_REQUEST, [FILING_NOT_FED_MSG, FILING_NOT_PAID_MSG])
]
Expand Down
24 changes: 16 additions & 8 deletions legal-api/tests/unit/services/test_authorization.py
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there already tests for NoW with a regular business filing (eg, COA, Alteration, others?)?

Original file line number Diff line number Diff line change
Expand Up @@ -1106,42 +1106,50 @@ def mock_auth(one, two): # pylint: disable=unused-argument; mocks of library me
expected_lookup([FilingKey.AMALGAMATION_REGULAR,
FilingKey.AMALGAMATION_VERTICAL,
FilingKey.AMALGAMATION_HORIZONTAL,
FilingKey.IA_BC])),
FilingKey.IA_BC,
FilingKey.NOTICE_OF_WITHDRAWAL])),
('staff_no_business_c', False, Business.State.ACTIVE, ['C'], 'staff', [STAFF_ROLE],
expected_lookup_continue_in_corps([FilingKey.AMALGAMATION_REGULAR,
FilingKey.AMALGAMATION_VERTICAL,
FilingKey.AMALGAMATION_HORIZONTAL,
FilingKey.CONTINUATION_IN_C])),
FilingKey.CONTINUATION_IN_C,
FilingKey.NOTICE_OF_WITHDRAWAL])),
('staff_no_business_ben', False, Business.State.ACTIVE, ['BEN'], 'staff', [STAFF_ROLE],
expected_lookup([FilingKey.AMALGAMATION_REGULAR,
FilingKey.AMALGAMATION_VERTICAL,
FilingKey.AMALGAMATION_HORIZONTAL,
FilingKey.IA_BEN])),
FilingKey.IA_BEN,
FilingKey.NOTICE_OF_WITHDRAWAL])),
('staff_no_business_cben', False, Business.State.ACTIVE, ['CBEN'], 'staff', [STAFF_ROLE],
expected_lookup_continue_in_corps([FilingKey.AMALGAMATION_REGULAR,
FilingKey.AMALGAMATION_VERTICAL,
FilingKey.AMALGAMATION_HORIZONTAL,
FilingKey.CONTINUATION_IN_CBEN])),
FilingKey.CONTINUATION_IN_CBEN,
FilingKey.NOTICE_OF_WITHDRAWAL])),
('staff_no_business_cc', False, Business.State.ACTIVE, ['CC'], 'staff', [STAFF_ROLE],
expected_lookup([FilingKey.AMALGAMATION_REGULAR,
FilingKey.AMALGAMATION_VERTICAL,
FilingKey.AMALGAMATION_HORIZONTAL,
FilingKey.IA_CC])),
FilingKey.IA_CC,
FilingKey.NOTICE_OF_WITHDRAWAL])),
('staff_no_business_ccc', False, Business.State.ACTIVE, ['CCC'], 'staff', [STAFF_ROLE],
expected_lookup_continue_in_corps([FilingKey.AMALGAMATION_REGULAR,
FilingKey.AMALGAMATION_VERTICAL,
FilingKey.AMALGAMATION_HORIZONTAL,
FilingKey.CONTINUATION_IN_CCC])),
FilingKey.CONTINUATION_IN_CCC,
FilingKey.NOTICE_OF_WITHDRAWAL])),
('staff_no_business_ulc', False, Business.State.ACTIVE, ['ULC'], 'staff', [STAFF_ROLE],
expected_lookup([FilingKey.AMALGAMATION_REGULAR,
FilingKey.AMALGAMATION_VERTICAL,
FilingKey.AMALGAMATION_HORIZONTAL,
FilingKey.IA_ULC])),
FilingKey.IA_ULC,
FilingKey.NOTICE_OF_WITHDRAWAL])),
('staff_no_business_cul', False, Business.State.ACTIVE, ['CUL'], 'staff', [STAFF_ROLE],
expected_lookup_continue_in_corps([FilingKey.AMALGAMATION_REGULAR,
FilingKey.AMALGAMATION_VERTICAL,
FilingKey.AMALGAMATION_HORIZONTAL,
FilingKey.CONTINUATION_IN_CUL])),
FilingKey.CONTINUATION_IN_CUL,
FilingKey.NOTICE_OF_WITHDRAWAL])),
('staff_no_business_llc', False, Business.State.ACTIVE, ['LLC'], 'staff', [STAFF_ROLE], []),
('staff_no_business_sp', False, Business.State.ACTIVE, ['SP'], 'staff', [STAFF_ROLE],
expected_lookup([FilingKey.REG_SP])),
Expand Down