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

19794 colin sync for amalgamationApplication #2837

Merged
merged 4 commits into from
Jul 17, 2024
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
1 change: 1 addition & 0 deletions colin-api/src/colin_api/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Model imports."""
from .address import Address
from .business import Business
from .corp_involved import CorpInvolved
from .corp_name import CorpName
from .corp_party import Party
from .filing_type import FilingType
Expand Down
6 changes: 5 additions & 1 deletion colin-api/src/colin_api/models/business.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class CorpStateTypes(Enum):

VOLUNTARY_DISSOLUTION = 'HDV'
ADMINISTRATIVE_DISSOLUTION = 'HDA'
AMALGAMATED = 'HAM'

NUMBERED_CORP_NAME_SUFFIX = {
TypeCodes.BCOMP.value: 'B.C. LTD.',
Expand Down Expand Up @@ -173,7 +174,10 @@ def _get_bn_15s(cls, cursor, identifiers: List) -> Dict:
for row in cursor.fetchall():
row = dict(zip([x[0].lower() for x in cursor.description], row))
if row['bn_15']:
bn_15s[f'BC{row["corp_num"]}'] = row['bn_15']
if row['corp_num'].isdecimal(): # valid only for BC
bn_15s[f'BC{row["corp_num"]}'] = row['bn_15']
else:
bn_15s[row['corp_num']] = row['bn_15']
return bn_15s

except Exception as err:
Expand Down
121 changes: 121 additions & 0 deletions colin-api/src/colin_api/models/corp_involved.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# Copyright © 2024 Province of British Columbia
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Meta information about the service.

Currently this only provides API versioning information
"""
from __future__ import annotations

from typing import List

from flask import current_app

from colin_api.resources.db import DB


class CorpInvolved:
"""Corp Involved object."""

event_id = None
corp_involve_id = None
corp_num = None
can_jur_typ_cd = None
adopted_corp_ind = None
home_juri_num = None
othr_juri_desc = None
foreign_nme = None

def __init__(self):
"""Initialize with all values None."""

def as_dict(self):
"""Return dict camel case version of self."""
return {
'eventId': self.event_id,
'corpInvolveId': self.corp_involve_id,
'corpNum': self.corp_num,
'canJurTypCd': self.can_jur_typ_cd,
'adoptedCorpInd': self.adopted_corp_ind,
'homeJuriNum': self.home_juri_num,
'othrJuriDesc': self.othr_juri_desc,
'foreignName': self.foreign_nme,
}

@classmethod
def _create_corp_involved_objs(cls, cursor) -> List:
"""Return a CorpInvolved obj by parsing cursor."""
corps_involved = cursor.fetchall()

corp_involved_objs = []
for corp_involved in corps_involved:
corp_involved = dict(zip([x[0].lower() for x in cursor.description], corp_involved))
corp_involved_obj = CorpInvolved()
corp_involved_obj.event_id = corp_involved['event_id']
corp_involved_obj.corp_involve_id = corp_involved['corp_involve_id']
corp_involved_obj.corp_num = corp_involved['corp_num']
corp_involved_obj.can_jur_typ_cd = corp_involved['can_jur_typ_cd']
corp_involved_obj.adopted_corp_ind = corp_involved['adopted_corp_ind']
corp_involved_obj.home_juri_num = corp_involved['home_juri_num']
corp_involved_obj.othr_juri_desc = corp_involved['othr_juri_desc']
corp_involved_obj.foreign_nme = corp_involved['foreign_nme']
corp_involved_objs.append(corp_involved_obj)

return corp_involved_objs

@classmethod
def create_corp_involved(cls, cursor, corp_involved_obj) -> CorpInvolved:
"""Add record to the CORP INVOLVED table."""
try:
cursor.execute(
"""
insert into CORP_INVOLVED (EVENT_ID, CORP_INVOLVE_ID, CORP_NUM, CAN_JUR_TYP_CD, ADOPTED_CORP_IND,
HOME_JURI_NUM, OTHR_JURI_DESC, FOREIGN_NME)
values (:event_id, :corp_involve_id, :corp_num, :can_jur_typ_cd, :adopted_corp_ind,
:home_juri_num, :othr_juri_desc, :foreign_nme)
""",
event_id=corp_involved_obj.event_id,
corp_involve_id=corp_involved_obj.corp_involve_id,
corp_num=corp_involved_obj.corp_num,
can_jur_typ_cd=corp_involved_obj.can_jur_typ_cd,
adopted_corp_ind=corp_involved_obj.adopted_corp_ind,
home_juri_num=corp_involved_obj.home_juri_num,
othr_juri_desc=corp_involved_obj.othr_juri_desc,
foreign_nme=corp_involved_obj.foreign_nme,
)

except Exception as err:
current_app.logger.error(f'Error inserting corp involved for event {corp_involved_obj.event_id}.')
raise err

@classmethod
def get_by_event(cls, cursor, event_id: str) -> List[CorpInvolved]:
"""Get the corps involved with the given event id."""
querystring = (
"""
select event_id, corp_involve_id, corp_num, can_jur_typ_cd, adopted_corp_ind, home_juri_num,
othr_juri_desc, foreign_nme, dd_event_id
from corp_involved
where event_id=:event_id
"""
)

try:
if not cursor:
cursor = DB.connection.cursor()
cursor.execute(querystring, event_id=event_id)
return cls._create_corp_involved_objs(cursor=cursor)

except Exception as err:
current_app.logger.error(f'error getting corp involved for event {event_id}')
raise err
127 changes: 90 additions & 37 deletions colin-api/src/colin_api/models/filing.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
PartiesNotFoundException, # noqa: I001
UnableToDetermineCorpTypeException, # noqa: I001
) # noqa: I001
from colin_api.models import Business, CorpName, FilingType, Office, Party, ShareObject
from colin_api.models import Business, CorpInvolved, CorpName, FilingType, Office, Party, ShareObject
from colin_api.resources.db import DB
from colin_api.utils import convert_to_json_date, convert_to_json_datetime, convert_to_snake

Expand Down Expand Up @@ -111,8 +111,30 @@ class FilingSource(Enum):
Business.TypeCodes.COOP.value: 'OTSPE',
},
'amalgamationApplication': {
'type_code_list': ['OTAMA'],
Business.TypeCodes.COOP.value: 'OTAMA',
'sub_type_property': 'type',
'sub_type_list': ['regular', 'horizontal', 'vertical'],
'type_code_list': ['OTAMA', 'AMALR', 'AMLRU', 'AMALH', 'AMLHU', 'AMALV', 'AMLVU'],
'regular': {
Business.TypeCodes.COOP.value: 'OTAMA',
Business.TypeCodes.BCOMP.value: 'AMALR',
Business.TypeCodes.BC_COMP.value: 'AMALR',
Business.TypeCodes.ULC_COMP.value: 'AMLRU',
Business.TypeCodes.CCC_COMP.value: 'AMALR'
},
'horizontal': {
Business.TypeCodes.COOP.value: 'OTAMA',
Business.TypeCodes.BCOMP.value: 'AMALH',
Business.TypeCodes.BC_COMP.value: 'AMALH',
Business.TypeCodes.ULC_COMP.value: 'AMLHU',
Business.TypeCodes.CCC_COMP.value: 'AMALH'
},
'vertical': {
Business.TypeCodes.COOP.value: 'OTAMA',
Business.TypeCodes.BCOMP.value: 'AMALV',
Business.TypeCodes.BC_COMP.value: 'AMALV',
Business.TypeCodes.ULC_COMP.value: 'AMLVU',
Business.TypeCodes.CCC_COMP.value: 'AMALV'
}
},
'dissolved': {
'type_code_list': ['OTDIS'],
Expand Down Expand Up @@ -425,35 +447,19 @@ def _insert_filing(cls, cursor, filing, ar_date: str, agm_date: str): # pylint:
effective_dt=filing.effective_date,
filing_date=filing.filing_date
)
elif filing_type_code in ['NOCAD', 'BEINC', 'ICORP', 'ICORU', 'ICORC', 'CRBIN', 'TRANS']:
insert_stmnt = insert_stmnt + ', arrangement_ind, ods_typ_cd) '
values_stmnt = values_stmnt + ", 'N', 'F')"
cursor.execute(
insert_stmnt + values_stmnt,
event_id=filing.event_id,
filing_type_code=filing_type_code,
effective_dt=filing.effective_date
)
elif filing_type_code in ['NOALA', 'NOALB', 'NOALC', 'NOALE', 'NOALR', 'NOALU']:
arragement_ind = 'N'
elif filing_type_code in ['NOCAD', 'CRBIN', 'TRANS',
'BEINC', 'ICORP', 'ICORU', 'ICORC',
'AMALR', 'AMALH', 'AMALV',
'NOALA', 'NOALB', 'NOALC', 'NOALE', 'NOALR', 'NOALU',
'REGSN', 'REGSO', 'COURT']:
arrangement_ind = 'N'
court_order_num = None
if court_order := filing.body.get('courtOrder', None):
arragement_ind = 'Y' if court_order.get('effectOfOrder', None) else 'N'
court_order_num = court_order['fileNumber']

insert_stmnt = insert_stmnt + ', arrangement_ind, court_order_num, ods_typ_cd) '
values_stmnt = values_stmnt + ", :arragement_ind, :court_order_num, 'F')"
cursor.execute(
insert_stmnt + values_stmnt,
event_id=filing.event_id,
filing_type_code=filing_type_code,
effective_dt=filing.effective_date,
arragement_ind=arragement_ind,
court_order_num=court_order_num
)
elif filing_type_code in ['REGSN', 'REGSO', 'COURT']:
arrangement_ind = 'Y' if filing.body.get('effectOfOrder', '') == 'planOfArrangement' else 'N'
court_order_num = filing.body.get('fileNumber', None)
if filing_type_code in ['REGSN', 'REGSO', 'COURT']:
arrangement_ind = 'Y' if filing.body.get('effectOfOrder', '') == 'planOfArrangement' else 'N'
court_order_num = filing.body.get('fileNumber', None)
elif court_order := filing.body.get('courtOrder', None):
arrangement_ind = 'Y' if court_order.get('effectOfOrder', None) else 'N'
court_order_num = court_order.get('fileNumber', None)

insert_stmnt = insert_stmnt + ', arrangement_ind, court_order_num, ods_typ_cd) '
values_stmnt = values_stmnt + ", :arrangement_ind, :court_order_num, 'F')"
Expand Down Expand Up @@ -990,10 +996,10 @@ def add_administrative_dissolution_event(cls, con, corp_num) -> int:
def add_filing(cls, con, filing: Filing) -> int:
"""Add new filing to COLIN tables."""
try:
if filing.filing_type not in ['annualReport', 'changeOfAddress', 'changeOfDirectors',
'incorporationApplication', 'alteration', 'transition', 'correction',
'registrarsNotation', 'registrarsOrder', 'courtOrder', 'dissolution',
'specialResolution']:
if filing.filing_type not in ['alteration', 'amalgamationApplication', 'annualReport', 'changeOfAddress',
'changeOfDirectors', 'correction', 'courtOrder', 'dissolution',
'incorporationApplication', 'registrarsNotation', 'registrarsOrder',
'specialResolution', 'transition']:
raise InvalidFilingTypeException(filing_type=filing.filing_type)

if filing.filing_sub_type \
Expand All @@ -1020,6 +1026,9 @@ def add_filing(cls, con, filing: Filing) -> int:
# create new filing
cls._insert_filing(cursor=cursor, filing=filing, ar_date=ar_date, agm_date=agm_date)

if filing.filing_type == 'amalgamationApplication':
cls._process_amalgamating_businesses(cursor, filing)

if filing.filing_type == 'correction':
cls._process_correction(cursor, business, filing, corp_num)
else:
Expand Down Expand Up @@ -1133,6 +1142,50 @@ 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_amalgamating_businesses(cls, cursor, filing):
"""Process amalgamating businesses."""
for index, amalgamating_business in enumerate(filing.body.get('amalgamatingBusinesses', [])):
corp_involved = CorpInvolved()
corp_involved.event_id = filing.event_id
corp_involved.corp_involve_id = index

identifier = amalgamating_business.get('identifier')

if ((foreign_jurisdiction := amalgamating_business.get('foreignJurisdiction', {})) and
not (identifier.startswith('A') and # is expro
foreign_jurisdiction.get('country') == 'CA' and
foreign_jurisdiction.get('region') == 'BC')):
corp_involved.home_juri_num = identifier
corp_involved.foreign_nme = amalgamating_business.get('legalName')

country_code = foreign_jurisdiction.get('country').upper()
region_code = (foreign_jurisdiction.get('region') or '').upper()
if country_code == 'CA':
if region_code == 'FEDERAL':
corp_involved.can_jur_typ_cd = 'FD'
else:
corp_involved.can_jur_typ_cd = region_code
else:
corp_involved.can_jur_typ_cd = 'OT'
corp_involved.othr_juri_desc = \
f'{country_code}, {region_code}' if region_code else country_code
else:
# strip prefix BC
if identifier.startswith('BC'):
identifier = identifier[-7:]
corp_involved.corp_num = identifier

if amalgamating_business['role'] in ['holding', 'primary']:
corp_involved.adopted_corp_ind = 'Y'

Business.update_corp_state(cursor,
filing.event_id,
identifier,
Business.CorpStateTypes.AMALGAMATED.value)

CorpInvolved.create_corp_involved(cursor, corp_involved)

@classmethod
# pylint: disable=too-many-arguments;
def _process_ar(cls, cursor, filing: Filing, corp_num: str, ar_date: str, agm_date: str, filing_source: str) -> str:
Expand Down Expand Up @@ -1185,7 +1238,7 @@ def _process_office(cls, cursor, filing: Filing) -> str:
office_type=office_type
)
# create new ledger text for address change
if filing.filing_type != 'incorporationApplication':
if filing.filing_type not in ['amalgamationApplication', 'incorporationApplication']:
office_desc = (office_type.replace('O', ' O')).title()
if text:
text = f'{text} Change to the {office_desc}.'
Expand Down Expand Up @@ -1249,7 +1302,7 @@ def _process_directors(cls, cursor, filing: Filing, business: Business, corp_num
@classmethod
def _create_corp_name(cls, cursor, filing: Filing, corp_num: str, name: str = None):
"""Create name."""
if filing.filing_type == 'incorporationApplication':
if filing.filing_type in ['amalgamationApplication', 'incorporationApplication']:
# create corp state
Business.create_corp_state(cursor=cursor, corp_num=corp_num, event_id=filing.event_id)
elif filing.filing_type == 'alteration':
Expand Down
2 changes: 1 addition & 1 deletion colin-api/src/colin_api/models/reset.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ def reset_filings(cls, start_date: str = None, end_date: str = None, identifiers
raise err

@classmethod
def reset_filings_by_event(cls, event_ids: list = []):
def reset_filings_by_event(cls, event_ids: list = []): # pylint: disable=dangerous-default-value
"""Reset changes made for given event ids."""
# initialize reset object
reset_obj = Reset()
Expand Down
3 changes: 2 additions & 1 deletion colin-api/src/colin_api/resources/business.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ def get(info_type, legal_type=None, identifier=None): # pylint: disable = too-m
if not json_data or not json_data['identifiers']:
return jsonify({'message': 'No input data provided'}), HTTPStatus.BAD_REQUEST
# remove the BC prefix
identifiers = [x[-7:] for x in json_data['identifiers']]
identifiers = [x[-7:] if identifier.startswith('BC') else x
for x in json_data['identifiers']]
bn_15s = Business._get_bn_15s( # pylint: disable = protected-access; internal call
cursor=cursor,
identifiers=identifiers
Expand Down
7 changes: 4 additions & 3 deletions colin-api/src/colin_api/resources/filing.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ def post(legal_type, identifier, **kwargs):
'changeOfDirectors': json_data.get('changeOfDirectors', None),
'annualReport': json_data.get('annualReport', None),
'incorporationApplication': json_data.get('incorporationApplication', None),
'amalgamationApplication': json_data.get('amalgamationApplication', None),
'alteration': json_data.get('alteration', None),
'transition': json_data.get('transition', None),
'registrarsNotation': json_data.get('registrarsNotation', None),
Expand Down Expand Up @@ -213,10 +214,10 @@ def _add_filings(con, json_data: dict, filing_list: list, identifier: str) -> li
# get utc lear effective date and convert to pacific time for insert into oracle
filing.effective_date = convert_to_pacific_time(filing.header['learEffectiveDate'])

if filing_type != 'incorporationApplication':
filing.business = Business.find_by_identifier(identifier, con=con)
else:
if filing_type in ['amalgamationApplication', 'incorporationApplication']:
filing.business = Business.create_corporation(con, json_data)
else:
filing.business = Business.find_by_identifier(identifier, con=con)
# add the new filing
event_id = Filing.add_filing(con, filing)
filings_added.append({'event_id': event_id,
Expand Down
Loading
Loading