Skip to content

Commit

Permalink
21752 restoration filing sync (bcgov#3016)
Browse files Browse the repository at this point in the history
  • Loading branch information
vysakh-menon-aot authored Oct 1, 2024
1 parent a30995b commit 363b55d
Show file tree
Hide file tree
Showing 10 changed files with 185 additions and 77 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/entity-filer-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:

strategy:
matrix:
python-version: [3.9.19]
python-version: [3.9]

steps:
- uses: actions/checkout@v3
Expand Down Expand Up @@ -79,7 +79,7 @@ jobs:

strategy:
matrix:
python-version: [3.9.19]
python-version: [3.9]

services:
postgres:
Expand Down
8 changes: 5 additions & 3 deletions colin-api/src/colin_api/models/business.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,15 @@ class CorpFrozenTypes(Enum):
class CorpStateTypes(Enum):
"""Render an Enum of the CorpState Type Codes."""

VOLUNTARY_DISSOLUTION = 'HDV'
ACTIVE = 'ACT'
ADMINISTRATIVE_DISSOLUTION = 'HDA'
AMALGAMATED = 'HAM'
INVOLUNTARY_DISSOLUTION_NO_AR = 'HDF'
INVOLUNTARY_DISSOLUTION_NO_TR = 'HDT'
CONTINUE_IN = 'HCI'
CONTINUE_OUT = 'HCO'
INVOLUNTARY_DISSOLUTION_NO_AR = 'HDF'
INVOLUNTARY_DISSOLUTION_NO_TR = 'HDT'
LIMITED_RESTORATION = 'LRS'
VOLUNTARY_DISSOLUTION = 'HDV'

NUMBERED_CORP_NAME_SUFFIX = {
TypeCodes.BCOMP.value: 'B.C. LTD.',
Expand Down
92 changes: 52 additions & 40 deletions colin-api/src/colin_api/models/corp_party.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,16 @@ class Party: # pylint: disable=too-many-instance-attributes; need all these fie
corp_num = None

role_types = {
'Director': 'DIR',
'Incorporator': 'INC',
'Liquidator': 'LIQ',
'Officer': 'OFF',
'Applicant': 'APP',
'Attorney': 'ATT',
'Completing Party': 'CPRTY',
'Custodian': 'RCC',
'Director': 'DIR',
'Firm Business Owner': 'FBO',
'Firm Individual Owner': 'FIO'
'Firm Individual Owner': 'FIO',
'Incorporator': 'INC',
'Liquidator': 'LIQ',
'Officer': 'OFF',
}

def __init__(self):
Expand Down Expand Up @@ -438,10 +439,11 @@ def create_new_corp_party(cls, cursor, event_id: int, party: Dict, business: Dic
"""
insert into corp_party (corp_party_id, mailing_addr_id, delivery_addr_id, corp_num, party_typ_cd,
start_event_id, end_event_id, appointment_dt, cessation_dt, last_nme, middle_nme, first_nme,
bus_company_num, business_nme, prev_party_id)
bus_company_num, business_nme, office_notification_dt, prev_party_id)
values (:corp_party_id, :mailing_addr_id, :delivery_addr_id, :corp_num, :party_typ_cd, :start_event_id,
:end_event_id, TO_DATE(:appointment_dt, 'YYYY-mm-dd'), TO_DATE(:cessation_dt, 'YYYY-mm-dd'),
:last_nme, :middle_nme, :first_nme, :bus_company_num, :business_name, :prev_party_id)
:last_nme, :middle_nme, :first_nme, :bus_company_num, :business_name,
TO_DATE(:office_notification_dt, 'YYYY-mm-dd'), :prev_party_id)
"""

completing_party_query = \
Expand All @@ -460,31 +462,6 @@ def create_new_corp_party(cls, cursor, event_id: int, party: Dict, business: Dic

# create new corp party entry
corp_num = business['business']['identifier']
try:
if corp_num == 'CP':
cursor.execute("""select noncorp_party_seq.NEXTVAL from dual""")
row = cursor.fetchone()
corp_party_id = int(row[0])
else:
cursor.execute("""
SELECT id_num
FROM system_id
WHERE id_typ_cd = 'CP'
FOR UPDATE
""")

corp_party_id = int(cursor.fetchone()[0])

if corp_party_id:
cursor.execute("""
UPDATE system_id
SET id_num = :new_num
WHERE id_typ_cd = 'CP'
""", new_num=corp_party_id + 1)

except Exception as err:
current_app.logger.error('Error in corp_party: Failed to get next corp_party_id.')
raise err
try:
role_type = party.get('role_type', 'DIR')

Expand Down Expand Up @@ -520,6 +497,31 @@ def create_new_corp_party(cls, cursor, event_id: int, party: Dict, business: Dic
)
else:
date_format = '%Y-%m-%d'
try:
if corp_num == 'CP':
cursor.execute("""select noncorp_party_seq.NEXTVAL from dual""")
row = cursor.fetchone()
corp_party_id = int(row[0])
else:
cursor.execute("""
SELECT id_num
FROM system_id
WHERE id_typ_cd = 'CP'
FOR UPDATE
""")

corp_party_id = int(cursor.fetchone()[0])

if corp_party_id:
cursor.execute("""
UPDATE system_id
SET id_num = :new_num
WHERE id_typ_cd = 'CP'
""", new_num=corp_party_id + 1)

except Exception as err:
current_app.logger.error('Error in corp_party: Failed to get next corp_party_id.')
raise err
if party.get('prev_id'):
cursor.execute(
query,
Expand All @@ -530,9 +532,15 @@ def create_new_corp_party(cls, cursor, event_id: int, party: Dict, business: Dic
party_typ_cd=role_type,
start_event_id=event_id,
end_event_id=event_id if party.get('cessationDate', '') else None,
appointment_dt=str(datetime.datetime.strptime(party['appointmentDate'], date_format))[:10],
cessation_dt=str(datetime.datetime.strptime(party['cessationDate'], date_format))[:10]
if party.get('cessationDate', None) else None,
appointment_dt=(
str(datetime.datetime.strptime(party['appointmentDate'], date_format))[:10]
if party.get('appointmentDate', None) else None),
cessation_dt=(
str(datetime.datetime.strptime(party['cessationDate'], date_format))[:10]
if party.get('cessationDate', None) else None),
office_notification_dt=(
str(datetime.datetime.strptime(party['officeNotificationDt'], date_format))[:10]
if party.get('officeNotificationDt') else None),
last_nme=party['officer']['lastName'],
middle_nme=party['officer'].get('middleInitial', ''),
first_nme=party['officer']['firstName'],
Expand All @@ -551,9 +559,15 @@ def create_new_corp_party(cls, cursor, event_id: int, party: Dict, business: Dic
party_typ_cd=role_type,
start_event_id=event_id,
end_event_id=event_id if party.get('cessationDate', '') else None,
appointment_dt=str(datetime.datetime.strptime(party['appointmentDate'], date_format))[:10],
cessation_dt=str(datetime.datetime.strptime(party['cessationDate'], date_format))[:10]
if party.get('cessationDate', None) else None,
appointment_dt=(
str(datetime.datetime.strptime(party['appointmentDate'], date_format))[:10]
if party.get('appointmentDate', None) else None),
cessation_dt=(
str(datetime.datetime.strptime(party['cessationDate'], date_format))[:10]
if party.get('cessationDate', None) else None),
office_notification_dt=(
str(datetime.datetime.strptime(party['officeNotificationDt'], date_format))[:10]
if party.get('officeNotificationDt') else None),
last_nme=party['officer']['lastName'],
middle_nme=party['officer'].get('middleInitial', ''),
first_nme=party['officer']['firstName'],
Expand All @@ -565,8 +579,6 @@ def create_new_corp_party(cls, cursor, event_id: int, party: Dict, business: Dic
current_app.logger.error(f'Error in corp_party: Failed create new party for {corp_num}')
raise err

return corp_party_id

@classmethod
def compare_parties(cls, party: Party, officer_json: Dict):
"""Compare corp party with json, return true if their names are equal."""
Expand Down
107 changes: 101 additions & 6 deletions colin-api/src/colin_api/models/filing.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,54 @@ class FilingSource(Enum):
'type_code_list': ['OTNCN'],
Business.TypeCodes.COOP.value: 'OTNCN',
},
'restoration': {
'sub_type_property': 'type',
'sub_type_list': ['fullRestoration',
'limitedRestoration',
'limitedRestorationExtension',
'limitedRestorationToFull'],
'type_code_list': ['RESTF', 'RESTL', 'RESXL', 'RESXF'],
'fullRestoration': {
Business.TypeCodes.BCOMP.value: 'RESTF',
Business.TypeCodes.BC_COMP.value: 'RESTF',
Business.TypeCodes.ULC_COMP.value: 'RESTF',
Business.TypeCodes.CCC_COMP.value: 'RESTF',
Business.TypeCodes.BCOMP_CONTINUE_IN.value: 'RESTF',
Business.TypeCodes.CONTINUE_IN.value: 'RESTF',
Business.TypeCodes.ULC_CONTINUE_IN.value: 'RESTF',
Business.TypeCodes.CCC_CONTINUE_IN.value: 'RESTF',
},
'limitedRestoration': {
Business.TypeCodes.BCOMP.value: 'RESTL',
Business.TypeCodes.BC_COMP.value: 'RESTL',
Business.TypeCodes.ULC_COMP.value: 'RESTL',
Business.TypeCodes.CCC_COMP.value: 'RESTL',
Business.TypeCodes.BCOMP_CONTINUE_IN.value: 'RESTL',
Business.TypeCodes.CONTINUE_IN.value: 'RESTL',
Business.TypeCodes.ULC_CONTINUE_IN.value: 'RESTL',
Business.TypeCodes.CCC_CONTINUE_IN.value: 'RESTL',
},
'limitedRestorationExtension': {
Business.TypeCodes.BCOMP.value: 'RESXL',
Business.TypeCodes.BC_COMP.value: 'RESXL',
Business.TypeCodes.ULC_COMP.value: 'RESXL',
Business.TypeCodes.CCC_COMP.value: 'RESXL',
Business.TypeCodes.BCOMP_CONTINUE_IN.value: 'RESXL',
Business.TypeCodes.CONTINUE_IN.value: 'RESXL',
Business.TypeCodes.ULC_CONTINUE_IN.value: 'RESXL',
Business.TypeCodes.CCC_CONTINUE_IN.value: 'RESXL',
},
'limitedRestorationToFull': {
Business.TypeCodes.BCOMP.value: 'RESXF',
Business.TypeCodes.BC_COMP.value: 'RESXF',
Business.TypeCodes.ULC_COMP.value: 'RESXF',
Business.TypeCodes.CCC_COMP.value: 'RESXF',
Business.TypeCodes.BCOMP_CONTINUE_IN.value: 'RESXF',
Business.TypeCodes.CONTINUE_IN.value: 'RESXF',
Business.TypeCodes.ULC_CONTINUE_IN.value: 'RESXF',
Business.TypeCodes.CCC_CONTINUE_IN.value: 'RESXF',
}
},
'restorationApplication': {
'type_code_list': ['OTRES'],
Business.TypeCodes.COOP.value: 'OTRES',
Expand Down Expand Up @@ -565,6 +613,7 @@ def _insert_filing(cls, cursor, filing, ar_date: str, agm_date: str): # pylint:
'NOALA', 'NOALB', 'NOALU', 'NOALC',
'CONTO', 'COUTI',
'AGMDT', 'AGMLC',
'RESTF', 'RESTL', 'RESXL', 'RESXF',
'REGSN', 'REGSO', 'COURT']:
arrangement_ind = 'N'
court_order_num = None
Expand Down Expand Up @@ -903,13 +952,25 @@ def get_filing(cls, filing: Filing, con=None, year: int = None) -> Dict:
is_corp_num_decimal = corp_num.isdecimal() # valid only for BC
filing.body['business'] = {}
if filing_event_info['filing_type_code'] in ['NOALR', 'NOALB']:
filing.body['business']['legalType'] = Business.TypeCodes.BC_COMP.value
filing.body['business']['legalType'] = (
Business.TypeCodes.BC_COMP.value if is_corp_num_decimal
else Business.TypeCodes.CONTINUE_IN.value
)
elif filing_event_info['filing_type_code'] in ['NOALE', 'NOALD', 'NOABE']:
filing.body['business']['legalType'] = Business.TypeCodes.BCOMP.value
filing.body['business']['legalType'] = (
Business.TypeCodes.BCOMP.value if is_corp_num_decimal
else Business.TypeCodes.BCOMP_CONTINUE_IN.value
)
elif filing_event_info['filing_type_code'] == 'NOALU':
filing.body['business']['legalType'] = Business.TypeCodes.ULC_COMP.value
filing.body['business']['legalType'] = (
Business.TypeCodes.ULC_COMP.value if is_corp_num_decimal
else Business.TypeCodes.ULC_CONTINUE_IN.value
)
elif filing_event_info['filing_type_code'] == 'NOALC':
filing.body['business']['legalType'] = Business.TypeCodes.CCC_COMP.value
filing.body['business']['legalType'] = (
Business.TypeCodes.CCC_COMP.value if is_corp_num_decimal
else Business.TypeCodes.CCC_CONTINUE_IN.value
)
elif filing_event_info['filing_type_code'] == 'NOALA':
corp_type = cls._get_corp_type_for_event(corp_num=corp_num,
event_id=filing_event_info['event_id'],
Expand Down Expand Up @@ -1147,7 +1208,7 @@ def add_filing(cls, con, filing: Filing) -> int:
'changeOfDirectors', 'consentContinuationOut', 'continuationIn',
'continuationOut', 'correction', 'courtOrder',
'dissolution', 'incorporationApplication', 'registrarsNotation',
'registrarsOrder', 'specialResolution', 'transition']:
'registrarsOrder', 'restoration', 'specialResolution', 'transition']:
raise InvalidFilingTypeException(filing_type=filing.filing_type)

if filing.filing_sub_type \
Expand Down Expand Up @@ -1180,6 +1241,8 @@ def add_filing(cls, con, filing: Filing) -> int:
cls._process_continuation_in(cursor, filing)
elif filing.filing_type == 'continuationOut':
cls._process_continuation_out(cursor, filing)
elif filing.filing_type == 'restoration':
cls._process_restoration(cursor, filing)

if filing.filing_type == 'correction':
cls._process_correction(cursor, business, filing, corp_num)
Expand Down Expand Up @@ -1332,6 +1395,38 @@ def is_filing_type_match(cls, filing: Filing, filing_type: str, filing_sub_type:
"""Return whether filing has specificed filing type and filing sub-type."""
return filing.filing_type == filing_type and filing.filing_sub_type == filing_sub_type

@classmethod
def _process_restoration(cls, cursor, filing):
"""Process restoration."""
corp_num = filing.get_corp_num()

Office.end_office(cursor=cursor,
event_id=filing.event_id,
corp_num=corp_num,
office_code=Office.OFFICE_TYPES_CODES['custodialOffice'])

Party.end_current(cursor, filing.event_id, corp_num, 'Custodian')

approval_type = filing.body.get('approvalType')
if approval_type == 'registrar':
for party in filing.body['parties']:
for role in party['roles']:
party['role_type'] = Party.role_types[(role['roleType'])]
if party['role_type'] == 'APP':
party['officeNotificationDt'] = filing.body.get('applicationDate')
role['appointmentDate'] = filing.body.get('noticeDate')

corp_state = Business.CorpStateTypes.ACTIVE.value # Active for fullRestoration and limitedRestorationToFull
if filing.filing_sub_type in ['limitedRestoration', 'limitedRestorationExtension']:
expiry_date = filing.body.get('expiry')
cursor.execute("""UPDATE event SET trigger_dts=TO_DATE(:trigger_dts, 'YYYY-mm-dd')
WHERE event_id=:event_id""",
event_id=filing.event_id,
trigger_dts=expiry_date
)
corp_state = Business.CorpStateTypes.LIMITED_RESTORATION.value
Business.update_corp_state(cursor, filing.event_id, corp_num, corp_state)

@classmethod
def _process_continuation_out(cls, cursor, filing):
"""Process continuation out."""
Expand Down Expand Up @@ -1569,7 +1664,7 @@ def _create_corp_name(cls, cursor, filing: Filing, corp_num: str, name: str = No
if filing.filing_type in ['amalgamationApplication', 'continuationIn', 'incorporationApplication']:
# create corp state
Business.create_corp_state(cursor=cursor, corp_num=corp_num, event_id=filing.event_id)
elif filing.filing_type == 'alteration':
elif filing.filing_type in ['alteration', 'restoration']:
old_corp_name = CorpName.get_current_name_or_numbered(cursor=cursor, corp_num=corp_num)
if old_corp_name.corp_name != name:
# end old corp name
Expand Down
23 changes: 15 additions & 8 deletions colin-api/src/colin_api/models/office.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,27 +166,34 @@ def get_by_event(cls, cursor, event_id: str = None):
raise err

@classmethod
def update_office(cls, cursor, office_info: Dict):
"""Update old office end event id and insert new row into office table.
office_info.keys() = ['new_event_id', 'corp_num', 'new_delivery_addr_id', 'new_mailing_addr_id', 'office_code']
"""
def end_office(cls, cursor, event_id: str, corp_num: str, office_code: str):
"""Update old office with end event id."""
try:
cursor.execute(
"""
UPDATE office
SET end_event_id = :event_id
WHERE corp_num = :corp_num and office_typ_cd = :office_typ_cd and end_event_id is null
""",
event_id=office_info['new_event_id'],
corp_num=office_info['corp_num'],
office_typ_cd=office_info['office_code']
event_id=event_id,
corp_num=corp_num,
office_typ_cd=office_code
)

except Exception as err: # pylint: disable=broad-except; want to catch all errs
current_app.logger.error('Error updating office table')
raise err

@classmethod
def update_office(cls, cursor, office_info: Dict):
"""Update old office end event id and insert new row into office table.
office_info.keys() = ['new_event_id', 'corp_num', 'new_delivery_addr_id', 'new_mailing_addr_id', 'office_code']
"""
cls.end_office(cursor,
event_id=office_info['new_event_id'],
corp_num=office_info['corp_num'],
office_code=office_info['office_code'])
try:
cursor.execute(
"""
Expand Down
Loading

0 comments on commit 363b55d

Please sign in to comment.