diff --git a/colin-api/setup.cfg b/colin-api/setup.cfg index ab5a94286a..4a9634c670 100644 --- a/colin-api/setup.cfg +++ b/colin-api/setup.cfg @@ -67,12 +67,11 @@ good-names= [pylint] ignore=migrations,test -max_line_length=120 notes=FIXME,XXX,TODO ignored-modules=flask_sqlalchemy,sqlalchemy,SQLAlchemy,alembic,scoped_session ignored-classes=scoped_session min-similarity-lines=100 -disable=C0301,W0511,R0801,R0902A,E1136 +disable=C0301,W0511,R0801,R0902,E1136 [isort] line_length = 120 diff --git a/colin-api/src/colin_api/__init__.py b/colin-api/src/colin_api/__init__.py index 24f6826721..2fff04225a 100644 --- a/colin-api/src/colin_api/__init__.py +++ b/colin-api/src/colin_api/__init__.py @@ -19,11 +19,11 @@ import sentry_sdk # noqa: I001; pylint: disable=ungrouped-imports; conflicts with Flake8 from flask import Flask -from colin_api.services import flags from sentry_sdk.integrations.flask import FlaskIntegration # noqa: I001 from colin_api import config, errorhandlers from colin_api.resources import API, API_BLUEPRINT, OPS_BLUEPRINT +from colin_api.services import flags from colin_api.utils.auth import jwt from colin_api.utils.logging import setup_logging from colin_api.utils.run_version import get_run_version diff --git a/colin-api/src/colin_api/exceptions/__init__.py b/colin-api/src/colin_api/exceptions/__init__.py index 603d80d38c..aaa2e66fb4 100644 --- a/colin-api/src/colin_api/exceptions/__init__.py +++ b/colin-api/src/colin_api/exceptions/__init__.py @@ -23,7 +23,7 @@ class GenericException(Exception): def __init__(self, error, status_code, *args, **kwargs): """Return a valid GenericException.""" - super(GenericException, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.error = error self.status_code = status_code @@ -33,7 +33,7 @@ class BusinessNotFoundException(GenericException): def __init__(self, *args, identifier=None, **kwargs): """Return a valid BusinessNotFoundException.""" - super(BusinessNotFoundException, self).__init__(None, None, *args, **kwargs) + super().__init__(None, None, *args, **kwargs) if identifier: self.error = f'{identifier} not found' else: @@ -46,7 +46,7 @@ class FilingNotFoundException(GenericException): def __init__(self, *args, identifier: str, filing_type: str, **kwargs): """Return a valid FilingNotFoundException.""" - super(FilingNotFoundException, self).__init__(None, None, *args, **kwargs) + super().__init__(None, None, *args, **kwargs) self.error = f'{filing_type} not found for {identifier}' self.status_code = 404 @@ -56,7 +56,7 @@ class OfficeNotFoundException(GenericException): def __init__(self, *args, identifier: str = None, **kwargs): """Return a valid AddressNotFoundException.""" - super(OfficeNotFoundException, self).__init__(None, None, *args, **kwargs) + super().__init__(None, None, *args, **kwargs) if identifier: self.error = f'Office not found for {identifier}' else: @@ -69,7 +69,7 @@ class AddressNotFoundException(GenericException): def __init__(self, *args, address_id, **kwargs): """Return a valid AddressNotFoundException.""" - super(AddressNotFoundException, self).__init__(None, None, *args, **kwargs) + super().__init__(None, None, *args, **kwargs) if address_id: self.error = f'Address not found with id: {address_id}' else: @@ -82,7 +82,7 @@ class PartiesNotFoundException(GenericException): def __init__(self, *args, identifier: str = None, **kwargs): """Return a valid PartiesNotFoundException.""" - super(PartiesNotFoundException, self).__init__(None, None, *args, **kwargs) + super().__init__(None, None, *args, **kwargs) if identifier: self.error = f'Parties not found for {identifier}' else: @@ -94,8 +94,8 @@ class NamesNotFoundException(GenericException): """Exception with defined error code and messaging.""" def __init__(self, *args, identifier: str = None, **kwargs): - """Return a valid PartiesNotFoundException.""" - super(NamesNotFoundException, self).__init__(None, None, *args, **kwargs) + """Return a valid NamesNotFoundException.""" + super().__init__(None, None, *args, **kwargs) if identifier: self.error = f'Corp names not found for {identifier}' else: @@ -108,7 +108,7 @@ class InvalidFilingTypeException(GenericException): def __init__(self, *args, filing_type=None, **kwargs): """Return a valid InvalidFilingTypeException.""" - super(InvalidFilingTypeException, self).__init__(None, None, *args, **kwargs) + super().__init__(None, None, *args, **kwargs) if filing_type: self.error = f'{filing_type} is an invalid filing type' else: @@ -120,8 +120,8 @@ class UnableToDetermineCorpTypeException(GenericException): """Exception with defined error code and messaging.""" def __init__(self, *args, filing_type=None, **kwargs): - """Return a valid InvalidFilingTypeException.""" - super(UnableToDetermineCorpTypeException, self).__init__(None, None, *args, **kwargs) + """Return a valid UnableToDetermineCorpTypeException.""" + super().__init__(None, None, *args, **kwargs) if filing_type: self.error = f'Unable to determine corp type for {filing_type} filing type' else: diff --git a/colin-api/src/colin_api/models/address.py b/colin-api/src/colin_api/models/address.py index 281d3ad001..00f9eda8a8 100644 --- a/colin-api/src/colin_api/models/address.py +++ b/colin-api/src/colin_api/models/address.py @@ -128,7 +128,7 @@ def get_by_address_id(cls, cursor, address_id: str = None) -> Optional[Address]: except Exception as err: current_app.logger.error(err.with_traceback(None)) - raise AddressNotFoundException(address_id=address_id) + raise AddressNotFoundException(address_id=address_id) # pylint: disable=raise-missing-from @classmethod def create_new_address(cls, cursor, address_info: dict = None, corp_num: str = None): @@ -153,7 +153,7 @@ def create_new_address(cls, cursor, address_info: dict = None, corp_num: str = N UPDATE system_id SET id_num = :new_num WHERE id_typ_cd = 'ADD' - """, new_num=addr_id+1) + """, new_num=addr_id + 1) country_typ_cd = pycountry.countries.search_fuzzy(address_info.get('addressCountry'))[0].alpha_2 except Exception as err: @@ -225,7 +225,7 @@ def delete(cls, cursor, address_ids: list = None): if cursor.rowcount < 1: current_app.logger.error('Database not updated.') - raise Exception + raise Exception # pylint: disable=broad-exception-raised return except Exception as err: current_app.logger.error(f'Failed to delete addresses {address_ids}') diff --git a/colin-api/src/colin_api/models/business.py b/colin-api/src/colin_api/models/business.py index 90553a06ba..85467c49eb 100644 --- a/colin-api/src/colin_api/models/business.py +++ b/colin-api/src/colin_api/models/business.py @@ -30,27 +30,22 @@ from colin_api.utils import convert_to_json_date, convert_to_json_datetime, convert_to_pacific_time, stringify_list -class Business: # pylint: disable=too-many-instance-attributes +class Business: # pylint: disable=too-many-instance-attributes, too-many-public-methods """Class to contain all model-like functions for the corporation and related tables.""" - class LearBusinessTypes(Enum): - """Temp class for lear business types, will be importing these from lear after upgrading python inage to 3.8.""" - - COOP = 'CP' - BCOMP = 'BEN' - BC_COMP = 'BC' - EXTRA_PRO_A = 'A' - CONTINUE_IN = 'C' - - class TypeCodes(Enum): """Render an Enum of the Corporation Type Codes.""" + EXTRA_PRO_A = 'A' COOP = 'CP' BCOMP = 'BEN' BC_COMP = 'BC' ULC_COMP = 'ULC' CCC_COMP = 'CC' + BCOMP_CONTINUE_IN = 'CBEN' + CONTINUE_IN = 'C' + CCC_CONTINUE_IN = 'CCC' + ULC_CONTINUE_IN = 'CUL' class CorpFrozenTypes(Enum): """Render an Enum of the Corporation Frozen Type Codes. @@ -69,27 +64,19 @@ class CorpStateTypes(Enum): VOLUNTARY_DISSOLUTION = 'HDV' ADMINISTRATIVE_DISSOLUTION = 'HDA' - # temp converter because legal doesn't have codes only class (legal_type) - CORP_TYPE_CONVERSION = { - LearBusinessTypes.COOP.value: [ - TypeCodes.COOP.value - ], - LearBusinessTypes.BCOMP.value: [ - TypeCodes.BCOMP.value, - TypeCodes.BC_COMP.value, - TypeCodes.ULC_COMP.value - ], - LearBusinessTypes.BC_COMP.value: [ - TypeCodes.BCOMP.value, - TypeCodes.BC_COMP.value, - TypeCodes.ULC_COMP.value, - TypeCodes.CCC_COMP.value - ], - LearBusinessTypes.EXTRA_PRO_A.value: [ - TypeCodes.EXTRA_PRO_A.value - ], + NUMBERED_CORP_NAME_SUFFIX = { + TypeCodes.BCOMP: 'B.C. LTD.', + TypeCodes.BC_COMP: 'B.C. LTD.', + TypeCodes.ULC_COMP: 'B.C. UNLIMITED LIABILITY COMPANY', + TypeCodes.CCC_COMP: 'B.C. COMMUNITY CONTRIBUTION COMPANY LTD.', } + # CORPS Continuation In has the same suffix + NUMBERED_CORP_NAME_SUFFIX[TypeCodes.BCOMP_CONTINUE_IN] = NUMBERED_CORP_NAME_SUFFIX[TypeCodes.BCOMP] + NUMBERED_CORP_NAME_SUFFIX[TypeCodes.CONTINUE_IN] = NUMBERED_CORP_NAME_SUFFIX[TypeCodes.BC_COMP] + NUMBERED_CORP_NAME_SUFFIX[TypeCodes.ULC_CONTINUE_IN] = NUMBERED_CORP_NAME_SUFFIX[TypeCodes.ULC_COMP] + NUMBERED_CORP_NAME_SUFFIX[TypeCodes.CCC_CONTINUE_IN] = NUMBERED_CORP_NAME_SUFFIX[TypeCodes.CCC_COMP] + business_number = None corp_name = None corp_num = None @@ -154,6 +141,19 @@ def as_slim_dict(self) -> Dict: } } + @classmethod + def get_colin_identifier(cls, lear_identifier, legal_type): + """Convert identifier from lear to colin.""" + if legal_type in [ + cls.TypeCodes.BCOMP.value, + cls.TypeCodes.BC_COMP.value, + cls.TypeCodes.ULC_COMP.value, + cls.TypeCodes.CCC_COMP.value + ]: + return lear_identifier[-7:] + + return lear_identifier + @classmethod def _get_bn_15s(cls, cursor, identifiers: List) -> Dict: """Return a dict of idenifiers mapping to their bn_15 numbers.""" @@ -186,8 +186,8 @@ def _get_last_ar_dates_for_reset(cls, cursor, event_info: List, event_ids: List) events_by_corp_num = {} for info in event_info: if info['filing_typ_cd'] not in ['OTINC', 'BEINC'] and \ - (info['corp_num'] not in events_by_corp_num or - events_by_corp_num[info['corp_num']] > info['event_id']): + (info['corp_num'] not in events_by_corp_num or + events_by_corp_num[info['corp_num']] > info['event_id']): events_by_corp_num[info['corp_num']] = info['event_id'] dates_by_corp_num = [] @@ -225,7 +225,10 @@ def _get_last_ar_dates_for_reset(cls, cursor, event_info: List, event_ids: List) return dates_by_corp_num @classmethod - def find_by_identifier(cls, identifier: str, corp_types: List = None, con=None) -> Business: + def find_by_identifier(cls, # pylint: disable=too-many-statements + identifier: str, + corp_types: List = None, + con=None) -> Business: """Return a Business by identifier.""" business = None try: @@ -270,7 +273,7 @@ def find_by_identifier(cls, identifier: str, corp_types: List = None, con=None) assumed_name = None corp_name = None for name_obj in corp_names: - if name_obj.type_code == CorpName.TypeCodes.ASSUMED.value: + if name_obj.type_code == CorpName.TypeCodes.ASSUMED.value: # pylint: disable=no-else-break assumed_name = name_obj.corp_name break elif name_obj.type_code in [CorpName.TypeCodes.CORP.value, CorpName.TypeCodes.NUMBERED_CORP.value]: @@ -336,11 +339,8 @@ def create_corporation(cls, con, filing_info: Dict): business.corp_num = filing_info['business']['identifier'] business.founding_date = convert_to_pacific_time(filing_info['header']['learEffectiveDate']) - if filing_info['business']['legalType'] in cls.CORP_TYPE_CONVERSION[cls.LearBusinessTypes.BCOMP.value]: - business.corp_num = business.corp_num[-7:] - business.corp_type = Business.TypeCodes.BCOMP.value - else: - business.corp_type = Business.TypeCodes.COOP.value + business.corp_type = filing_info['business']['legalType'] + business.corp_num = cls.get_colin_identifier(business.corp_num, business.corp_type) cursor = con.cursor() @@ -563,7 +563,7 @@ def update_corp_type(cls, cursor, corp_num: str, corp_type: str): try: if corp_type not in [x.value for x in Business.TypeCodes.__members__.values()]: current_app.logger.error(f'Tried to update {corp_num} with invalid corp type code {corp_type}') - raise Exception + raise Exception # pylint: disable=broad-exception-raised cursor.execute( """ @@ -640,11 +640,11 @@ def get_next_corp_num(cls, con, corp_type: str) -> str: SET id_num = :new_num WHERE id_typ_cd = :corp_type """, - new_num=corp_num[0]+1, + new_num=corp_num[0] + 1, corp_type=corp_type ) - return '%07d' % corp_num + return '%07d' % corp_num # pylint: disable=consider-using-f-string except Exception as err: current_app.logger.error('Error looking up corp_num') raise err diff --git a/colin-api/src/colin_api/models/corp_name.py b/colin-api/src/colin_api/models/corp_name.py index a66ebd4dd6..09d035495b 100644 --- a/colin-api/src/colin_api/models/corp_name.py +++ b/colin-api/src/colin_api/models/corp_name.py @@ -232,3 +232,16 @@ def get_current_by_type(cls, cursor, corp_num: str, type_code: str) -> List: except Exception as err: current_app.logger.error(f'error getting current corp names by type {type_code} for {corp_num}') raise err + + @classmethod + def get_current_name_or_numbered(cls, cursor, corp_num: str) -> List: + """Get current entity name by type code name/numbered.""" + try: + querystring = cls.NAME_QUERY + " and corp_name_typ_cd in ('CO','NB') and end_event_id is null" + cursor.execute(querystring, corp_num=corp_num) + names = cls._create_name_objs(cursor=cursor) + return names[0] if names else None + + except Exception as err: + current_app.logger.error(f'error getting current corp name by type name/numbered for {corp_num}') + raise err diff --git a/colin-api/src/colin_api/models/corp_party.py b/colin-api/src/colin_api/models/corp_party.py index 3c78fa6b08..f5e3b2222f 100644 --- a/colin-api/src/colin_api/models/corp_party.py +++ b/colin-api/src/colin_api/models/corp_party.py @@ -163,8 +163,8 @@ def group_parties(cls, parties: List['Party'], completing_parties: dict) -> List role_dict = {v: k for k, v in cls.role_types.items()} # Used as a lookup for role names grouped_list = [] - role_func = (lambda x: x.officer['firstName'] + x.officer['middleInitial'] + x.officer['lastName'] - + x.officer['orgName']) # noqa: E731; + role_func = (lambda x: # pylint: disable=unnecessary-lambda-assignment; # noqa: E731; + x.officer['firstName'] + x.officer['middleInitial'] + x.officer['lastName'] + x.officer['orgName']) # CORP_PARTIES are stored as a separate row per Role, and need to be grouped to return a list of # Role(s) within each Party object. First the rows are grouped in-memory by party/organization name @@ -239,7 +239,7 @@ def get_all_parties(cls, cursor, corp_num: str) -> List[Party]: party.appointment_date = party.get_start_event_date(cursor) # only return the top level parent records - for party_id in party_id_map: + for party_id in party_id_map: # pylint: disable=consider-using-dict-items if party_id not in child_party_ids: party = party_id_map[party_id] if party.appointment_date == 'unknown': @@ -480,7 +480,7 @@ def create_new_corp_party(cls, cursor, event_id: int, party: Dict, business: Dic UPDATE system_id SET id_num = :new_num WHERE id_typ_cd = 'CP' - """, new_num=corp_party_id+1) + """, 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.') diff --git a/colin-api/src/colin_api/models/filing.py b/colin-api/src/colin_api/models/filing.py index b95b455fb4..3887e271ed 100644 --- a/colin-api/src/colin_api/models/filing.py +++ b/colin-api/src/colin_api/models/filing.py @@ -51,6 +51,7 @@ class LearSource(Enum): class FilingSource(Enum): """Enum that holds the sources of a filing.""" + BAR = 'BAR' LEAR = 'LEAR' @@ -362,7 +363,7 @@ def _get_events(cls, cursor, corp_num: str, filing_type_code: str) -> List: @classmethod def _get_filing_type(cls, filing_type_code: str) -> Optional[str]: - for filing_type in cls.FILING_TYPES: + for filing_type in cls.FILING_TYPES: # pylint: disable=consider-using-dict-items if filing_type_code in cls.FILING_TYPES[filing_type]['type_code_list']: return filing_type return None @@ -424,7 +425,7 @@ 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', 'CRBIN', 'TRANS']: + 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( @@ -525,14 +526,14 @@ def _insert_ledger_text(cls, cursor, filing, text: str): def _get_filing_event_info(cls, cursor, filing: Filing, year: int = None) -> Dict: """Get the basic filing info that we care about for all filings.""" # build base querystring - querystring = (""" + querystring = """ select event.event_id, event_timestmp, first_nme, middle_nme, last_nme, email_addr, period_end_dt, agm_date, effective_dt, event.corp_num, user_id, filing_typ_cd, arrangement_ind, court_order_num from event join filing on filing.event_id = event.event_id left join filing_user on event.event_id = filing_user.event_id where - """) + """ if filing.event_id: querystring += ' event.event_id=:event_id' else: @@ -610,7 +611,7 @@ def _get_filing_event_info(cls, cursor, filing: Filing, year: int = None) -> Dic @classmethod def _get_notation(cls, cursor, corp_num: str, filing_event_info: Dict) -> Dict: """Get notation for the corresponding event id.""" - querystring = ('select notation from ledger_text where event_id=:event_id') + querystring = 'select notation from ledger_text where event_id=:event_id' try: cursor.execute(querystring, event_id=filing_event_info['event_id']) notation = cursor.fetchone() @@ -960,8 +961,8 @@ def get_future_effective_filings(cls, business: Business) -> List: 'colinIds': [filing_info['event_id']] } filing.body = { - filing_info['filing_type']: { - } + filing_info['filing_type']: { + } } future_effective_filings.append(filing.as_dict()) return future_effective_filings @@ -1091,7 +1092,7 @@ def add_filing(cls, con, filing: Filing) -> int: # Freeze entity for Alteration if filing.filing_type == 'alteration' or ( filing.filing_type == 'incorporationApplication' and - business['business']['legalType'] == Business.LearBusinessTypes.BCOMP.value): + business['business']['legalType'] == Business.TypeCodes.BCOMP.value): Business.update_corp_frozen_type(cursor, corp_num, Business.CorpFrozenTypes.COMPANY_FROZEN.value) return filing.event_id @@ -1252,13 +1253,6 @@ def _create_corp_name(cls, cursor, filing: Filing, corp_num: str, name: str = No # create corp state Business.create_corp_state(cursor=cursor, corp_num=corp_num, event_id=filing.event_id) elif filing.filing_type == 'alteration': - if alter_corp_type := filing.body.get('business', {}).get('legalType'): - Business.update_corp_type( - cursor=cursor, - corp_num=corp_num, - corp_type=alter_corp_type - ) - # end old CorpName.end_current(cursor=cursor, event_id=filing.event_id, corp_num=corp_num) @@ -1272,7 +1266,14 @@ def _create_corp_name(cls, cursor, filing: Filing, corp_num: str, name: str = No corp_name_obj.corp_name = name corp_name_obj.type_code = CorpName.TypeCodes.CORP.value else: - corp_name_obj.corp_name = f'{corp_num} B.C. LTD.' + corp_name_prefix = corp_num + if filing.business.corp_type in (Business.TypeCodes.BCOMP_CONTINUE_IN.value, + Business.TypeCodes.ULC_CONTINUE_IN.value, + Business.TypeCodes.CCC_CONTINUE_IN.value, + Business.TypeCodes.CONTINUE_IN.value): + corp_name_prefix = corp_num[1:] + corp_name_suffix = Business.NUMBERED_CORP_NAME_SUFFIX[filing.business.corp_type] + corp_name_obj.corp_name = f'{corp_name_prefix} {corp_name_suffix}' corp_name_obj.type_code = CorpName.TypeCodes.NUMBERED_CORP.value CorpName.create_corp_name(cursor=cursor, corp_name_obj=corp_name_obj) @@ -1329,13 +1330,7 @@ def _process_correction(cls, cursor, business: dict, filing: Filing, corp_num: s if name_request := filing.body.get('nameRequest'): new_legal_name = name_request.get('legalName') - corp_names = CorpName.get_current(cursor=cursor, corp_num=corp_num) - old_corp_name = None - for name_obj in corp_names: - if name_obj.type_code in [CorpName.TypeCodes.CORP.value, CorpName.TypeCodes.NUMBERED_CORP.value]: - old_corp_name = name_obj - break - + old_corp_name = CorpName.get_current_name_or_numbered(cursor=cursor, corp_num=corp_num) if old_corp_name.corp_name != new_legal_name: # end old corp name CorpName.end_name( @@ -1346,9 +1341,8 @@ def _process_correction(cls, cursor, business: dict, filing: Filing, corp_num: s type_code=old_corp_name.type_code ) # create new corp name from NR - # If numbered set name to None, _create_corp_name will populate it. - name = None if new_legal_name.startswith(corp_num) else new_legal_name - cls._create_corp_name(cursor, filing, corp_num, name) + # If numbered, _create_corp_name will populate it. + cls._create_corp_name(cursor, filing, corp_num, new_legal_name) cls._process_name_translations(cursor, filing, corp_num) cls._process_office(cursor, filing) diff --git a/colin-api/src/colin_api/models/office.py b/colin-api/src/colin_api/models/office.py index b7f1f6daf5..fdc6ae744d 100644 --- a/colin-api/src/colin_api/models/office.py +++ b/colin-api/src/colin_api/models/office.py @@ -98,10 +98,10 @@ def convert_obj_list(cls, office_obj_list: list = None): offices_dict = {} for office_obj in office_obj_list: - if office_obj.office_type not in offices_dict.keys(): + if office_obj.office_type not in offices_dict.keys(): # pylint: disable=consider-iterating-dictionary offices_dict.update(office_obj.as_dict()) else: - current_app.logger.error('Received more than 1 office for {}'.format(office_obj.office_type)) + current_app.logger.error(f'Received more than 1 office for {office_obj.office_type}') return offices_dict @classmethod @@ -131,17 +131,17 @@ def get_current(cls, cursor, identifier: str = None): if not identifier: return None - querystring = (""" + querystring = """ select start_event_id, end_event_id, mailing_addr_id, delivery_addr_id, office_typ_cd from office where corp_num=:identifier and end_event_id is null - """) + """ try: offices = cls._build_offices_list(cursor, querystring=querystring, event_id=None, identifier=identifier) return offices except Exception as err: - current_app.logger.error('error getting office for corp: {}'.format(identifier)) + current_app.logger.error(f'error getting office for corp: {identifier}') raise err @classmethod @@ -150,18 +150,18 @@ def get_by_event(cls, cursor, event_id: str = None): if not event_id: return None - querystring = (""" + querystring = """ select start_event_id, end_event_id, mailing_addr_id, delivery_addr_id, office_typ_cd from office where start_event_id=:event_id - """) + """ try: offices = cls._build_offices_list(cursor, querystring=querystring, identifier=None, event_id=event_id) return offices except Exception as err: # pylint: disable=broad-except; want to catch all errs - current_app.logger.error('error getting office from event : {}'.format(event_id)) + current_app.logger.error(f'error getting office from event : {event_id}') raise err diff --git a/colin-api/src/colin_api/models/reset.py b/colin-api/src/colin_api/models/reset.py index 4b79f8c7d2..69239bb776 100644 --- a/colin-api/src/colin_api/models/reset.py +++ b/colin-api/src/colin_api/models/reset.py @@ -48,7 +48,7 @@ def as_dict(self): def get_filings_for_reset(self): """Return event/filing info for all filings getting reset.""" # build base query string - query_string = (""" + query_string = """ select event.event_id, event.corp_num, filing_typ_cd from event join filing on filing.event_id = event.event_id @@ -56,7 +56,7 @@ def get_filings_for_reset(self): where filing_user.user_id in ('COOPER', 'BCOMPS') AND event.event_timestmp>=TO_DATE(:start_date, 'yyyy-mm-dd') AND event.event_timestmp<=TO_DATE(:end_date, 'yyyy-mm-dd') - """) + """ if self.identifiers: query_string += f' AND event.corp_num in ({stringify_list(self.identifiers)})' @@ -83,7 +83,7 @@ def get_filings_for_reset(self): return reset_list except Exception as err: # pylint: disable=broad-except; want to catch all errors - current_app.logger.error('error getting filing/event info for reset for: {}'.format(self.as_dict())) + current_app.logger.error(f'error getting filing/event info for reset for: {self.as_dict()}') raise err @classmethod diff --git a/colin-api/src/colin_api/resources/business.py b/colin-api/src/colin_api/resources/business.py index 3e15eb6173..76aa74ec5f 100644 --- a/colin-api/src/colin_api/resources/business.py +++ b/colin-api/src/colin_api/resources/business.py @@ -61,6 +61,7 @@ def get(identifier: str): {'message': 'Error when trying to retrieve business record from COLIN'} ), HTTPStatus.INTERNAL_SERVER_ERROR + @cors_preflight('GET, POST') @API.route('//', methods=['GET']) @API.route('/', methods=['POST']) @@ -74,12 +75,10 @@ def get(legal_type: str, identifier: str): """Return the complete business info.""" try: # convert identifier if BC legal_type - if legal_type in Business.CORP_TYPE_CONVERSION[Business.LearBusinessTypes.BCOMP.value]: - identifier = identifier[-7:] + identifier = Business.get_colin_identifier(identifier, legal_type) # get business - corp_types = Business.CORP_TYPE_CONVERSION.get(legal_type, [legal_type]) - business = Business.find_by_identifier(identifier, corp_types) + business = Business.find_by_identifier(identifier) if not business: return jsonify({'message': f'{identifier} not found'}), HTTPStatus.NOT_FOUND return jsonify(business.as_dict()), HTTPStatus.OK @@ -99,7 +98,9 @@ def get(legal_type: str, identifier: str): @jwt.requires_roles([COLIN_SVC_ROLE]) def post(legal_type: str): """Create and return a new corp number for the given legal type.""" - if legal_type not in [x.value for x in Business.LearBusinessTypes]: + # BC: BEN, BC, ULC, CC + # C: CBEN, C, CUL, CCC + if legal_type not in ['BC', 'C']: # corp_type (id_typ_cd in system_id table) return jsonify({'message': 'Must provide a valid legal type.'}), HTTPStatus.BAD_REQUEST try: @@ -128,7 +129,7 @@ class BusinessNamesInfo(Resource): @jwt.requires_roles([COLIN_SVC_ROLE]) def get(legal_type, identifier, name_type): """Get active names by type code for a business.""" - if legal_type not in [x.value for x in Business.LearBusinessTypes]: + if legal_type not in [x.value for x in Business.TypeCodes]: return jsonify({'message': 'Must provide a valid legal type.'}), HTTPStatus.BAD_REQUEST if name_type not in [x.value for x in CorpName.TypeCodes.__members__.values()]: @@ -136,8 +137,7 @@ def get(legal_type, identifier, name_type): try: # convert identifier if BC legal_type - if legal_type in Business.CORP_TYPE_CONVERSION[Business.LearBusinessTypes.BCOMP.value]: - identifier = identifier[-7:] + identifier = Business.get_colin_identifier(identifier, legal_type) con = DB.connection con.begin() @@ -180,7 +180,7 @@ def get(info_type, legal_type=None, identifier=None): # pylint: disable = too-m return jsonify(bn_15s), HTTPStatus.OK if info_type == 'resolutions': - if not legal_type or legal_type not in [x.value for x in Business.LearBusinessTypes]: + if not legal_type or legal_type not in [x.value for x in Business.TypeCodes]: return jsonify({'message': 'Must provide a valid legal type.'}), HTTPStatus.BAD_REQUEST if not identifier: @@ -189,8 +189,7 @@ def get(info_type, legal_type=None, identifier=None): # pylint: disable = too-m ), HTTPStatus.BAD_REQUEST # convert identifier if BC legal_type - if legal_type in Business.CORP_TYPE_CONVERSION[Business.LearBusinessTypes.BCOMP.value]: - identifier = identifier[-7:] + identifier = Business.get_colin_identifier(identifier, legal_type) return jsonify( {'resolutionDates': Business.get_resolutions(cursor=cursor, corp_num=identifier)} diff --git a/colin-api/src/colin_api/resources/db.py b/colin-api/src/colin_api/resources/db.py index a73432e34b..9cc5b13cf9 100644 --- a/colin-api/src/colin_api/resources/db.py +++ b/colin-api/src/colin_api/resources/db.py @@ -58,22 +58,24 @@ def init_session(conn, *args): # pylint: disable=unused-argument; Extra var bei cursor = conn.cursor() cursor.execute("alter session set TIME_ZONE = 'America/Vancouver'") - return cx_Oracle.SessionPool(user=current_app.config.get('ORACLE_USER'), # pylint:disable=c-extension-no-member - password=current_app.config.get('ORACLE_PASSWORD'), - dsn='{0}:{1}/{2}'.format(current_app.config.get('ORACLE_HOST'), - current_app.config.get('ORACLE_PORT'), - current_app.config.get('ORACLE_DB_NAME')), - min=1, - max=10, - increment=1, - connectiontype=cx_Oracle.Connection, # pylint:disable=c-extension-no-member - threaded=True, - getmode=cx_Oracle.SPOOL_ATTRVAL_NOWAIT, # pylint:disable=c-extension-no-member - waitTimeout=1500, - timeout=3600, - sessionCallback=init_session, - encoding='UTF-8', - nencoding='UTF-8') + return cx_Oracle.SessionPool( # pylint:disable=c-extension-no-member + user=current_app.config.get('ORACLE_USER'), + password=current_app.config.get('ORACLE_PASSWORD'), + dsn='{0}:{1}/{2}'.format( # pylint:disable=consider-using-f-string + current_app.config.get('ORACLE_HOST'), + current_app.config.get('ORACLE_PORT'), + current_app.config.get('ORACLE_DB_NAME')), + min=1, + max=10, + increment=1, + connectiontype=cx_Oracle.Connection, # pylint:disable=c-extension-no-member + threaded=True, + getmode=cx_Oracle.SPOOL_ATTRVAL_NOWAIT, # pylint:disable=c-extension-no-member + waitTimeout=1500, + timeout=3600, + sessionCallback=init_session, + encoding='UTF-8', + nencoding='UTF-8') @property def connection(self): # pylint: disable=inconsistent-return-statements diff --git a/colin-api/src/colin_api/resources/event.py b/colin-api/src/colin_api/resources/event.py index 94351dcdb6..faf32b4314 100644 --- a/colin-api/src/colin_api/resources/event.py +++ b/colin-api/src/colin_api/resources/event.py @@ -31,13 +31,13 @@ class EventInfo(Resource): @jwt.requires_roles([COLIN_SVC_ROLE]) def get(corp_type, event_id): """Return all event_ids of the corp_type that are greater than the given event_id.""" - querystring = (""" + querystring = """ select event.event_id, corporation.corp_num, corporation.corp_typ_cd, filing.filing_typ_cd from event join filing on event.event_id = filing.event_id join corporation on EVENT.corp_num = corporation.corp_num where corporation.corp_typ_cd = :corp_type - """) + """ try: cursor = DB.connection.cursor() if event_id != 'earliest': @@ -69,13 +69,13 @@ class CorpEventInfo(Resource): @jwt.requires_roles([COLIN_SVC_ROLE]) def get(corp_num): """Return all event_ids of the corp_type that are greater than the given event_id.""" - querystring = (""" + querystring = """ select e.event_id, e.corp_num, f.filing_typ_cd from event e join filing f on e.event_id = f.event_id where e.corp_num = :corp_num order by e.event_id asc - """) + """ try: cursor = DB.connection.cursor() cursor.execute(querystring, corp_num=corp_num) diff --git a/colin-api/src/colin_api/resources/filing.py b/colin-api/src/colin_api/resources/filing.py index 76bdb1c36a..e5e167dc65 100644 --- a/colin-api/src/colin_api/resources/filing.py +++ b/colin-api/src/colin_api/resources/filing.py @@ -41,7 +41,7 @@ class FilingInfo(Resource): def get(legal_type, identifier, filing_type, filing_sub_type=None): """Return the complete filing info or historic (pre-bob-date=2019-03-08) filings.""" try: - if legal_type not in [x.value for x in Business.LearBusinessTypes]: + if legal_type not in [x.value for x in Business.TypeCodes]: return jsonify({'message': 'Must provide a valid legal type.'}), HTTPStatus.BAD_REQUEST # get optional parameters (event_id / year) @@ -51,12 +51,10 @@ def get(legal_type, identifier, filing_type, filing_sub_type=None): year = int(year) # convert identifier if BC legal_type - if legal_type in Business.CORP_TYPE_CONVERSION[Business.LearBusinessTypes.BCOMP.value]: - identifier = identifier[-7:] + identifier = Business.get_colin_identifier(identifier, legal_type) # get business - corp_types = Business.CORP_TYPE_CONVERSION[legal_type] - business = Business.find_by_identifier(identifier, corp_types) + business = Business.find_by_identifier(identifier) # get future effective filings if filing_type == 'future': @@ -96,7 +94,7 @@ def post(legal_type, identifier, **kwargs): """Create a new filing.""" # pylint: disable=unused-argument,too-many-branches; filing_type is only used for the get try: - if legal_type not in [x.value for x in Business.LearBusinessTypes]: + if legal_type not in [x.value for x in Business.TypeCodes]: return jsonify({'message': 'Must provide a valid legal type.'}), HTTPStatus.BAD_REQUEST json_data = request.get_json() @@ -120,10 +118,8 @@ def post(legal_type, identifier, **kwargs): ), HTTPStatus.BAD_REQUEST # convert identifier if BC legal_type - if legal_type in Business.CORP_TYPE_CONVERSION[Business.LearBusinessTypes.BCOMP.value]: - identifier = identifier[-7:] + identifier = Business.get_colin_identifier(identifier, legal_type) - corp_types = Business.CORP_TYPE_CONVERSION[legal_type] if json_data.get('correction', None): filing_list = {'correction': json_data['correction']} else: @@ -142,7 +138,7 @@ def post(legal_type, identifier, **kwargs): } # Filter out null-values in the filing_list dictionary - filing_list = {k: v for k, v in filing_list.items() if filing_list[k]} + filing_list = {k: v for k, v in filing_list.items() if v} try: # get db connection and start a session, in case we need to roll back con = DB.connection @@ -151,22 +147,22 @@ def post(legal_type, identifier, **kwargs): # No filing will be created for administrative dissolution. Create an event and update corp state. if ('dissolution' in filing_list and Filing.get_filing_sub_type('dissolution', filing_list['dissolution']) == 'administrative'): - if legal_type == Business.LearBusinessTypes.COOP.value: - raise Exception('Not implemented!') + if legal_type == Business.TypeCodes.COOP.value: + raise Exception('Not implemented!') # pylint: disable=broad-exception-raised event_id = Filing.add_administrative_dissolution_event(con, identifier) con.commit() return jsonify({ 'filing': { - 'header': { 'colinIds' : [event_id]} + 'header': {'colinIds': [event_id]} } }), HTTPStatus.CREATED - filings_added = FilingInfo._add_filings(con, json_data, filing_list, identifier, corp_types) + filings_added = FilingInfo._add_filings(con, json_data, filing_list, identifier) # return the completed filing data completed_filing = Filing() # get business info again - could have changed since filings were applied - completed_filing.business = Business.find_by_identifier(identifier, corp_types, con) + completed_filing.business = Business.find_by_identifier(identifier, con=con) completed_filing.body = {} for filing_info in filings_added: sub_filing = Filing() @@ -203,7 +199,7 @@ def post(legal_type, identifier, **kwargs): ), HTTPStatus.INTERNAL_SERVER_ERROR @staticmethod - def _add_filings(con, json_data: dict, filing_list: list, identifier: str, corp_types: list) -> list: + def _add_filings(con, json_data: dict, filing_list: list, identifier: str) -> list: """Process all parts of the filing.""" filings_added = [] for filing_type in filing_list: @@ -218,7 +214,7 @@ def _add_filings(con, json_data: dict, filing_list: list, identifier: str, corp_ filing.effective_date = convert_to_pacific_time(filing.header['learEffectiveDate']) if filing_type != 'incorporationApplication': - filing.business = Business.find_by_identifier(identifier, corp_types, con) + filing.business = Business.find_by_identifier(identifier, con=con) else: filing.business = Business.create_corporation(con, json_data) # add the new filing diff --git a/colin-api/src/colin_api/resources/office.py b/colin-api/src/colin_api/resources/office.py index 599bfbf146..e7412969c7 100644 --- a/colin-api/src/colin_api/resources/office.py +++ b/colin-api/src/colin_api/resources/office.py @@ -42,13 +42,12 @@ def get(legal_type: str, identifier: str): return jsonify({'message': 'Identifier required'}), HTTPStatus.NOT_FOUND try: - if legal_type in Business.CORP_TYPE_CONVERSION[Business.LearBusinessTypes.BCOMP.value]: - identifier = identifier[-7:] + identifier = Business.get_colin_identifier(identifier, legal_type) cursor = DB.connection.cursor() offices = {} office_obj_list = Office.get_current(cursor=cursor, identifier=identifier) for office_obj in office_obj_list: - if office_obj.office_type not in offices.keys(): + if office_obj.office_type not in offices.keys(): # pylint: disable=consider-iterating-dictionary offices.update(office_obj.as_dict()) if not offices.keys(): return jsonify( diff --git a/colin-api/src/colin_api/resources/ops.py b/colin-api/src/colin_api/resources/ops.py index d1e649d1cf..110c450c67 100644 --- a/colin-api/src/colin_api/resources/ops.py +++ b/colin-api/src/colin_api/resources/ops.py @@ -40,8 +40,8 @@ def get(): except cx_Oracle.DatabaseError as err: # pylint:disable=c-extension-no-member try: return {'message': 'api is down', 'details': str(err)}, 500 - except Exception as err: # pylint: disable=broad-except; want to catch any outstanding errors - current_app.logger.error(err.with_traceback(None)) + except Exception as er: # pylint: disable=broad-except; want to catch any outstanding errors + current_app.logger.error(er.with_traceback(None)) return {'message': 'api is down'}, 500 # made it here, so all checks passed diff --git a/colin-api/src/colin_api/resources/parties.py b/colin-api/src/colin_api/resources/parties.py index 2bba615053..c1d808d202 100644 --- a/colin-api/src/colin_api/resources/parties.py +++ b/colin-api/src/colin_api/resources/parties.py @@ -42,15 +42,14 @@ def get(legal_type: str, identifier: str): return jsonify({'message': 'Identifier required'}), HTTPStatus.NOT_FOUND try: - if legal_type in Business.CORP_TYPE_CONVERSION[Business.LearBusinessTypes.BCOMP.value]: - identifier = identifier[-7:] + identifier = Business.get_colin_identifier(identifier, legal_type) party_type = request.args.get('partyType', 'Director') cursor = DB.connection.cursor() directors = Party.get_current(cursor=cursor, corp_num=identifier, role_type=party_type) if not directors: return jsonify({'message': f'directors for {identifier} not found'}), HTTPStatus.NOT_FOUND if len(directors) < 3 and legal_type in [Business.TypeCodes.COOP.value, Business.TypeCodes.CCC_COMP.value]: - current_app.logger.error('Less than 3 directors for {}'.format(identifier)) + current_app.logger.error(f'Less than 3 directors for {identifier}') return jsonify({'directors': [x.as_dict() for x in directors]}), HTTPStatus.OK except GenericException as err: # pylint: disable=duplicate-code @@ -75,8 +74,7 @@ class Parties(Resource): def get(legal_type: str, identifier: str): """Return all the parties for a business.""" try: - if legal_type in Business.CORP_TYPE_CONVERSION[Business.LearBusinessTypes.BCOMP.value]: - identifier = identifier[-7:] + identifier = Business.get_colin_identifier(identifier, legal_type) cursor = DB.connection.cursor() parties = Party.get_all_parties(cursor=cursor, corp_num=identifier) diff --git a/colin-api/src/colin_api/resources/share_struct.py b/colin-api/src/colin_api/resources/share_struct.py index b8e94f848f..9bfca19a42 100644 --- a/colin-api/src/colin_api/resources/share_struct.py +++ b/colin-api/src/colin_api/resources/share_struct.py @@ -44,8 +44,7 @@ def get(legal_type: str, identifier: str): try: cursor = DB.connection.cursor() - if legal_type in Business.CORP_TYPE_CONVERSION[Business.LearBusinessTypes.BCOMP.value]: - identifier = identifier[-7:] + identifier = Business.get_colin_identifier(identifier, legal_type) shares = ShareObject.get_all(cursor=cursor, corp_num=identifier) if not shares: return jsonify({'message': f'No share structures found for {identifier}'}), HTTPStatus.NOT_FOUND diff --git a/colin-api/src/colin_api/services/flags.py b/colin-api/src/colin_api/services/flags.py index 2aebd6d213..c2d0c7e858 100644 --- a/colin-api/src/colin_api/services/flags.py +++ b/colin-api/src/colin_api/services/flags.py @@ -38,7 +38,7 @@ def factory(cls, **kwargs): force_polling=kwargs.get('force_polling', False)) -class Flags(): +class Flags(): # pylint: disable=too-few-public-methods """Wrapper around the feature flag system. calls FAIL to FALSE diff --git a/colin-api/src/colin_api/utils/__init__.py b/colin-api/src/colin_api/utils/__init__.py index d5bcb1dc90..a75dc0922e 100644 --- a/colin-api/src/colin_api/utils/__init__.py +++ b/colin-api/src/colin_api/utils/__init__.py @@ -25,7 +25,7 @@ def convert_to_json_date(thedate: datetime.datetime) -> str: try: return thedate.strftime('%Y-%m-%d') except Exception as err: # pylint: disable=broad-except; want to return None in all cases where convert failed - current_app.logger.debug('Tried to convert {date}, but failed: {error}'.format(date=thedate, error=err)) + current_app.logger.debug(f'Tried to convert {thedate}, but failed: {err}') return None @@ -48,7 +48,7 @@ def convert_to_json_datetime(thedate: datetime.datetime) -> str: # return as string return thedate.strftime('%Y-%m-%dT%H:%M:%S-00:00') except Exception as err: # pylint: disable=broad-except; want to return None in all cases where convert failed - current_app.logger.debug('Tried to convert {date}, but failed: {error}'.format(date=thedate, error=err)) + current_app.logger.debug(f'Tried to convert {thedate}, but failed: {err}') return None diff --git a/colin-api/src/colin_api/utils/logging.py b/colin-api/src/colin_api/utils/logging.py index 19fb1d965e..93f08cdf99 100644 --- a/colin-api/src/colin_api/utils/logging.py +++ b/colin-api/src/colin_api/utils/logging.py @@ -23,6 +23,6 @@ def setup_logging(conf): if conf and path.isfile(conf): logging.config.fileConfig(conf) - print('Configure logging, from conf:{}'.format(conf), file=sys.stdout) + print(f'Configure logging, from conf:{conf}', file=sys.stdout) else: - print('Unable to configure logging, attempted conf:{}'.format(conf), file=sys.stderr) + print(f'Unable to configure logging, attempted conf:{conf}', file=sys.stderr)