Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
173 commits
Select commit Hold shift + click to select a range
11a0552
32960 business emailer - special resolution updates (#4557)
kialj876 Jul 8, 2026
d787438
34021 - Convert to legislation datetime and update tests (#4558)
meawong Jul 8, 2026
de7c52a
34076 - Bump legal-api and emailer versions (#4559)
meawong Jul 8, 2026
124611d
34080 - Remove Active CCO Validation and clean up code (#4561)
meawong Jul 8, 2026
d216916
32961 emailer - update restoration emails (#4560)
kialj876 Jul 9, 2026
2dbd569
34037 - Refresh Data Dev (#4554)
Rajandeep98 Jul 9, 2026
34078b9
32962 Emailer - correction updates (#4563)
kialj876 Jul 10, 2026
d6c6ec6
32963-dissolution-email-templates
Jul 14, 2026
abf93d1
33940-api-completing-party-incorporation
Jul 14, 2026
85c5b3f
33940-api-completing-party-incorporation
Jul 14, 2026
8a1727b
32963-dissolution-email-templates
Jul 14, 2026
7acbaf9
32963-dissolution-email-templates
Jul 14, 2026
37765ba
32963-dissolution-email-templates
Jul 14, 2026
00aaddb
34219-bump-legal-api-emailer-versions
Jul 14, 2026
9232a7a
Merge pull request #4572 from mruff-aeq/34219-bump-legal-api-emailer-…
mruff-aeq Jul 14, 2026
8559353
34222 - Dump with updated schema name (#4571)
Rajandeep98 Jul 14, 2026
5a2a97a
34121 move court order into separate table (#4567)
vysakh-menon-aot Jul 14, 2026
0d83f9c
32963-dissolution-email-templates
Jul 15, 2026
2e42182
Merge pull request #4569 from mruff-aeq/32963-dissolution-email-templ…
mruff-aeq Jul 15, 2026
4765a33
33940-api-completing-party-incorporation
Jul 15, 2026
ab63e41
34201 schema update (#4574)
kialj876 Jul 15, 2026
deecf50
34201 - Point model deps to hotfix branch (#4577)
kialj876 Jul 15, 2026
326b444
34199 Addition of delta restore script for tracking table dump (#4568)
argush3 Jul 15, 2026
13ac271
34037 - Add Package for Utilities (#4579)
Rajandeep98 Jul 15, 2026
d76efa7
34037 add package data tool utilities (#4580)
Rajandeep98 Jul 15, 2026
6b3d207
33940-api-completing-party-incorporation
Jul 16, 2026
ebfc503
Merge pull request #4570 from mruff-aeq/33940-api-completing-party-in…
mruff-aeq Jul 16, 2026
f376ca4
34121 update ref to use court order table (#4573)
vysakh-menon-aot Jul 16, 2026
55f3140
update db migration to use database owner role (#4582)
vysakh-menon-aot Jul 16, 2026
cc7d4be
API updates to maintain client documents in the DRS.
doug-lovett Jul 16, 2026
f1e072d
API updates to maintain client documents in the DRS.
doug-lovett Jul 16, 2026
2ef1fc5
update model to use database owner role (migration) (#4584)
vysakh-menon-aot Jul 16, 2026
f1355e1
API updates to maintain client documents in the DRS.
doug-lovett Jul 16, 2026
e1efe5b
34218 Emailer - firm name on filing notification bug fix (#4581)
kialj876 Jul 17, 2026
aa9647f
set role inside transaction (#4586)
vysakh-menon-aot Jul 17, 2026
1d91732
update model to set role inside transaction (#4588)
vysakh-menon-aot Jul 17, 2026
ee26c38
34199 Update delta restore script to support merging of specific tabl…
argush3 Jul 17, 2026
260e8c2
34037 add package data tool utilities (#4585)
Rajandeep98 Jul 17, 2026
dc6d0d8
32963-dissolution-ux-fixes
Jul 17, 2026
b8262d2
32963-dissolution-coop-documents
Jul 17, 2026
de86cea
32963-dissolution-ux-fixes
Jul 17, 2026
32e492f
32963-dissolution-ux-fixes
Jul 17, 2026
1641115
Revert "32963-dissolution-ux-fixes"
Jul 17, 2026
958967c
34297 Add delta restore script docs (#4591)
argush3 Jul 20, 2026
725155d
34299-special-resolution-drs-reporttype
Jul 20, 2026
7634c76
Try to resolve spec linter issue.
doug-lovett Jul 20, 2026
5f47a9e
32963-dissolution-ux-fixes
Jul 20, 2026
3c82729
Merge pull request #4589 from mruff-aeq/32963-dissolution-ux-fixes
mruff-aeq Jul 20, 2026
4977332
Merge pull request #4592 from mruff-aeq/34299-special-resolution-drs-…
mruff-aeq Jul 20, 2026
2993ee7
Merge pull request #4583 from doug-lovett/34142-api-client-docs-drs-s…
doug-lovett Jul 20, 2026
de9fca8
33970 model - update schema (#4590)
kialj876 Jul 21, 2026
ed7a945
33970 API - schema update (#4596)
kialj876 Jul 22, 2026
36d2067
33279 Integrate transpose address changes into COLIN extract and tran…
argush3 Jul 22, 2026
a909607
34200-consent-continuation-out-output
Jul 23, 2026
725d580
34265 emailer cco co (#4603)
kialj876 Jul 23, 2026
ed98c3d
34037 - Incorporate Refresh Flow (#4578)
Rajandeep98 Jul 23, 2026
aa56aaa
33970 API - fix validation on initial new business (#4605)
kialj876 Jul 24, 2026
99fae5a
34200-consent-continuation-out-output
Jul 24, 2026
a748388
34258 model update (#4609)
vysakh-menon-aot Jul 24, 2026
a8a3e5a
34200-consent-continuation-out-output
Jul 24, 2026
1b86d00
Merge pull request #4610 from mruff-aeq/34200-consent-continuation-ou…
mruff-aeq Jul 24, 2026
ba769f5
34349 - update to remove court oder columns from filings table (#4600)
ketaki-deodhar Jul 24, 2026
43b882f
34258 court order endpoints (#4614)
vysakh-menon-aot Jul 27, 2026
dc77bbf
34389 model update for extended correction (#4617)
vysakh-menon-aot Jul 27, 2026
68675d3
34391 - Update Common Validation for Pdfs (#4616)
meawong Jul 27, 2026
8e64812
34391 - Fix ff name for drs-upload (#4626)
meawong Jul 27, 2026
7390e99
34180 - Update Filer from Minio to Drs (#4618)
meawong Jul 27, 2026
7c01f3f
34300-static-report-drs-fetch
Jul 28, 2026
a6095c3
34300-static-report-drs-fetch
Jul 28, 2026
c0d1422
34265 Emailer - CCO text ux tweak (#4619)
kialj876 Jul 28, 2026
dc6afe8
34300-static-report-drs-fetch
Jul 28, 2026
9b193ee
Merge pull request #4627 from mruff-aeq/34300-static-report-drs-fetch
mruff-aeq Jul 28, 2026
39046ed
34400-guard-remaining-minio-call-sites
Jul 28, 2026
979b033
34392 - Transpose Address Fix (#4615)
Rajandeep98 Jul 28, 2026
adc707f
34389 add court order metadata (#4629)
vysakh-menon-aot Jul 28, 2026
08c5c0f
34054 - add new table demigrated filings (#4613)
ketaki-deodhar Jul 28, 2026
095adf0
Merge pull request #4628 from mruff-aeq/34400-guard-remaining-minio-c…
mruff-aeq Jul 28, 2026
ce8760a
34389 update to include court order metadata (#4634)
vysakh-menon-aot Jul 29, 2026
9ece42d
34402 - chore update versions for release (#4636)
kialj876 Jul 29, 2026
51818ad
3379 - Add trim strings to modify_filing_json and addunit tests (#4635)
meawong Jul 29, 2026
8755336
34389 schema update (#4638)
vysakh-menon-aot Jul 29, 2026
e056350
34389 model version update (#4637)
vysakh-menon-aot Jul 29, 2026
5d6a5c1
34382 Update data migration auth flows to support SAF re-engagement f…
argush3 Jul 29, 2026
153ae93
34408 - Extract Data Validation (#4630)
Rajandeep98 Jul 30, 2026
c445ca3
34389 court order update (#4640)
vysakh-menon-aot Jul 30, 2026
5a61c61
34424-affidavit-drs-stamp-config
Jul 30, 2026
364c9a8
34424-affidavit-drs-stamp-config
Jul 30, 2026
ae58c8c
Merge pull request #4642 from mruff-aeq/34424-affidavit-drs-stamp-config
mruff-aeq Jul 30, 2026
9977c07
API ledger client document url updates
doug-lovett Aug 1, 2026
a433cdd
34401 Filer - publish to drs for updating documents (#4644)
kialj876 Aug 4, 2026
12c616e
34264 - Cont In Authorization Template Changes (#4643)
meawong Aug 4, 2026
45aab30
Minor updates from review.
doug-lovett Aug 4, 2026
25b6fe2
Minor updates from review.
doug-lovett Aug 4, 2026
845b067
Merge pull request #4648 from doug-lovett/34436-api-minio-drs-ledger-…
doug-lovett Aug 5, 2026
19fb5ed
model version bump
benjamin-bc-gov Aug 5, 2026
4445649
updated poetry lock
benjamin-bc-gov Aug 5, 2026
555f8f7
bump version
benjamin-bc-gov Aug 5, 2026
e16d25b
34273 allow correction of appointmentDate of a director (#4671)
vysakh-menon-aot Aug 5, 2026
c024324
34354-noa-ccc-bca-text
Aug 6, 2026
e6c0b2a
Merge pull request #4676 from benjamin-bc-gov/32906_model_bump
benjamin-bc-gov Aug 6, 2026
30688a9
Merge pull request #4678 from mruff-aeq/34354-noa-ccc-bca-text
mruff-aeq Aug 6, 2026
b42a145
34263 - Liqudation Notification Changes (#4677)
meawong Aug 6, 2026
2eeefb6
34489 - chore udpate version for release 30.3 (#4680)
meawong Aug 7, 2026
4839f62
bump version after model merge (#4679)
benjamin-bc-gov Aug 7, 2026
f235750
34354-noa-bca-statement
Aug 10, 2026
81c49b3
Merge pull request #4688 from mruff-aeq/34354-noa-bca-statement
mruff-aeq Aug 10, 2026
a3d597f
34481 validation for newLegalType and resolutionDates (new format) (#…
vysakh-menon-aot Aug 10, 2026
7bba08b
34457-coop-ar-report-types
Aug 10, 2026
fa42d11
Merge pull request #4689 from mruff-aeq/34457-coop-ar-report-types
mruff-aeq Aug 10, 2026
357b20a
34465 Colin API - auth info endpoint (#4687)
kialj876 Aug 10, 2026
211e60a
remove minio code
benjamin-bc-gov Aug 11, 2026
1f5a765
34496 - Update min year validation for AGM Location Change (#4691)
meawong Aug 11, 2026
3f8ffa6
34482 validate continuation_in in correction (#4690)
vysakh-menon-aot Aug 11, 2026
5f07a97
made chnages to test files
benjamin-bc-gov Aug 11, 2026
3a92ee7
updated test cases
benjamin-bc-gov Aug 12, 2026
714e7c6
version bump
benjamin-bc-gov Aug 12, 2026
ddb73ff
removed dead code
benjamin-bc-gov Aug 12, 2026
b4ae18a
33654 - account linking key forwarding for auth and pay (#4682)
ochiu Aug 12, 2026
5720560
34541_noa-ccc-bca-italic
Aug 13, 2026
c8a4229
34483 validation of continuationOut and amalgamationOut in correction…
vysakh-menon-aot Aug 13, 2026
81c448e
Merge pull request #4695 from mruff-aeq/34541_noa-ccc-bca-italic
mruff-aeq Aug 13, 2026
f4ca1bd
Merge remote-tracking branch 'origin/main' into 34181_minio_removal
benjamin-bc-gov Aug 13, 2026
d401e20
30642-public-filing-dissolution-date
Aug 14, 2026
4a47778
34530 new endpoint to get extended business data (#4696)
vysakh-menon-aot Aug 14, 2026
2fbfc78
344267 - Add Early AR Filed Registrar Notation (#4699)
meawong Aug 14, 2026
70641d6
mino refffrence removed
benjamin-bc-gov Aug 14, 2026
d92bb06
updated if logic to edge cases
benjamin-bc-gov Aug 14, 2026
75af83d
Merge pull request #4700 from mruff-aeq/30642-public-filing-dissoluti…
mruff-aeq Aug 14, 2026
129ee5d
34465 Colin API - auth info status tweak (#4697)
kialj876 Aug 14, 2026
0c1642b
Merge pull request #4694 from benjamin-bc-gov/34181_minio_removal
benjamin-bc-gov Aug 14, 2026
4f55849
34267 - Remove extra guards for historical, draft and pending (#4701)
meawong Aug 14, 2026
618371f
add nr validation
benjamin-bc-gov Aug 17, 2026
ae1b7db
add test cases
benjamin-bc-gov Aug 17, 2026
4e6f6b5
updated validation logic
benjamin-bc-gov Aug 17, 2026
5071d88
34514 - return entities with 0001 founding date (#4698)
JazzarKarim Aug 17, 2026
110284e
fixed linting
benjamin-bc-gov Aug 17, 2026
485d927
34514 - refresh legal api lock file to pick up business model changes…
JazzarKarim Aug 17, 2026
5655ff6
updated test cases
benjamin-bc-gov Aug 18, 2026
8ae1f6f
34537 include amalgamation data in extended endpoint (#4702)
vysakh-menon-aot Aug 18, 2026
9ff8e56
Merge pull request #4703 from benjamin-bc-gov/32831_nr_duplicate
benjamin-bc-gov Aug 18, 2026
b24454e
Temp Changes for testing in Prod (#4693)
Rajandeep98 Aug 18, 2026
b770ccf
34507 Emailer - appoint/cease/change address receiver (#4708)
kialj876 Aug 19, 2026
9c7ce17
34055 (#4681)
ketaki-deodhar Aug 19, 2026
0864d0e
fix/admin-dissolution-firm-ledger
Aug 19, 2026
288399d
Merge pull request #4710 from mruff-aeq/fix/admin-dissolution-firm-le…
mruff-aeq Aug 19, 2026
371af97
bumped business filer
benjamin-bc-gov Aug 19, 2026
55044b8
Merge pull request #4712 from benjamin-bc-gov/34611_filler-_bump
benjamin-bc-gov Aug 19, 2026
33a0622
34484 validate amalgamation in correction (#4709)
vysakh-menon-aot Aug 19, 2026
8cca516
34088 Colin API - business snapshot endpoint (#4711)
kialj876 Aug 20, 2026
90bc7dd
34236 Emailer - involuntary dissolution (#4707)
kialj876 Aug 20, 2026
06233db
34531 schema updates for correction (#4714)
vysakh-menon-aot Aug 20, 2026
b2d16b2
34651-bump-registry-schemas-2.18.81
Aug 20, 2026
9ebbf2f
Merge pull request #4715 from mruff-aeq/34651-bump-registry-schemas-2…
mruff-aeq Aug 20, 2026
c9e2f7e
34553-firms-completing-party-client-skip
Aug 20, 2026
cfd0469
34531 schema and model changes for correction (#4717)
vysakh-menon-aot Aug 21, 2026
fef8d6a
34553-firms-completing-party-client-skip
Aug 21, 2026
284042b
34531 include ting id in the business extended response (#4720)
vysakh-menon-aot Aug 21, 2026
6547599
Merge pull request #4719 from mruff-aeq/34553-firms-completing-party-…
mruff-aeq Aug 21, 2026
33c0907
fixed bug download bug
benjamin-bc-gov Aug 20, 2026
eb5ee40
wrote test for the fix
benjamin-bc-gov Aug 20, 2026
4eb76e6
version bumped
benjamin-bc-gov Aug 20, 2026
d3c1415
fixed lint
benjamin-bc-gov Aug 20, 2026
6b3b1c3
made PR changes
benjamin-bc-gov Aug 20, 2026
f98e2b4
Merge pull request #4713 from benjamin-bc-gov/34460_error_downloading
benjamin-bc-gov Aug 24, 2026
71fbd53
34088 chore - update schema for amalg (#4721)
kialj876 Aug 24, 2026
efc4d60
34088 legal api colin snap proxy and validation (#4718)
kialj876 Aug 24, 2026
67cda83
32036 - Amalgamation Certificate: display home jurisdiction for XPRO/…
meawong Aug 24, 2026
0bc8928
34578 - AGM Extension Year must be After Incorporation Year (#4727)
meawong Aug 25, 2026
d10e2cc
34641 script schema updates (#4728)
Rajandeep98 Aug 25, 2026
3b5d6fb
34236 Emailer - inv diss ux (#4725)
kialj876 Aug 25, 2026
04bdcdb
34086 Business Model - amalgamating businesses, colin_identifier (#4723)
kialj876 Aug 25, 2026
ccbe5fd
34485 court orders validation in correction (#4726)
vysakh-menon-aot Aug 25, 2026
5c2c2bf
Add support for Libraries (LIB) migration
dimak1 Aug 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,6 @@ jobs/sftp-*/archive
# ruff
**/.ruff_cache

# Delta restore run artifacts
data-tool/scripts/generated/delta_restore/

2 changes: 2 additions & 0 deletions colin-api/src/colin_api/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"""Model imports."""

from .address import Address
from .business import Business
from .business_snapshot import BusinessSnapshot
from .cont_out import ContOut
from .corp_involved import CorpInvolved
from .corp_name import CorpName
Expand Down
61 changes: 61 additions & 0 deletions colin-api/src/colin_api/models/business.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,13 @@ class CorpStateTypes(Enum):
TypeCodes.ULC_CONTINUE_IN.value,
TypeCodes.CCC_CONTINUE_IN.value]

# Corp types that auth may sync auth info (including the corp password) for.
# These are the COLIN businesses that can be affiliated in the business registry
# dashboard while not loaded in LEAR.
AUTH_INFO_TYPES = [TypeCodes.BC_COMP.value,
TypeCodes.ULC_COMP.value,
TypeCodes.CCC_COMP.value]

NUMBERED_CORP_NAME_SUFFIX = {
TypeCodes.BCOMP.value: 'B.C. LTD.',
TypeCodes.BC_COMP.value: 'B.C. LTD.',
Expand Down Expand Up @@ -116,6 +123,16 @@ class CorpStateTypes(Enum):
def __init__(self):
"""Initialize with all values None."""

@property
def lear_state(self) -> str:
"""Return the LEAR-style business state: only op-state ACT is active, everything else is historical.

Same rule as the tombstone migration (data-tool tombstone_utils) and the search
importers - keyed off CORP_OP_STATE.OP_STATE_TYP_CD (ACT/HIS), not the
fine-grained corp state code.
"""
return 'ACTIVE' if self.corp_state_class == 'ACT' else 'HISTORICAL'

def as_dict(self) -> Dict:
"""Return dict version of self."""
return {
Expand Down Expand Up @@ -374,6 +391,50 @@ def find_by_identifier(cls, # pylint: disable=too-many-statements
# pass through exception to caller
raise err

@classmethod
def get_auth_info(cls, identifier: str) -> Dict:
"""Return the info needed by auth to create/refresh an entity for a COLIN business.

The response contains the corporation password, so callers must be service
authenticated and must never log the result or pass it on to a browser.
Restricted to the corp types that can be affiliated while not loaded in LEAR.
"""
# auth holds the prefixed identifier, COLIN stores the bare corp num. BC/ULC/CC all
# use the BC prefix, so it can be stripped without knowing the legal type first.
if identifier.startswith('BC'):
identifier = identifier[2:]

# acquire a single session from the pool and reuse it for both lookups
con = DB.connection
business = cls.find_by_identifier(identifier, corp_types=cls.AUTH_INFO_TYPES, con=con)

cursor = con.cursor()
cursor.execute(
"""
select corp_password
from CORPORATION
where corp_num=:corp_num
""",
corp_num=identifier
)
result = cursor.fetchone()
pass_code = result[0] if result else None

return {
'identifier': business.corp_num,
'legalName': business.corp_name,
'legalType': business.corp_type,
# LEAR-style state, not COLIN's free-text status description - auth stores it
# verbatim and the dashboard filters on ACTIVE/HISTORICAL
'status': business.lear_state,
'goodStanding': business.good_standing,
'businessNumber': business.business_number,
# find_by_identifier returns the COLIN 'True'/'False' string; normalize for callers
'adminFreeze': business.admin_freeze == 'True',
'email': business.email,
'passCode': pass_code
}

@classmethod
def create_corporation(cls, con, filing_info: Dict):
"""Insert a new business from an incorporation filing."""
Expand Down
199 changes: 199 additions & 0 deletions colin-api/src/colin_api/models/business_snapshot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
# Copyright © 2026 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.
"""Snapshot of a COLIN business, normalized to LEAR structure."""
from __future__ import annotations

from datetime import datetime, timezone
from typing import Dict, Optional

import pycountry
from flask import current_app

from colin_api.exceptions import PartiesNotFoundException
from colin_api.models.business import Business
from colin_api.models.corp_party import Party
from colin_api.models.office import Office
from colin_api.models.shares import ShareObject
from colin_api.resources.db import DB


class BusinessSnapshot: # pylint: disable=too-few-public-methods
"""Builds the LEAR-structured snapshot dict for a COLIN business."""

# snapshot offices are limited to the two the amalgamation flow prepopulates
OFFICE_TYPES = ('registeredOffice', 'recordsOffice')

@classmethod
def get_snapshot(cls, orig_identifier: str) -> Dict:
"""Return the business/parties/offices/shareClasses/resolutions snapshot."""
identifier = orig_identifier
if identifier.startswith('BC'):
identifier = identifier[2:]

con = DB.connection
business = Business.find_by_identifier(identifier, con=con)
cursor = con.cursor()

try:
parties = Party.get_current(cursor, identifier)
except PartiesNotFoundException:
# no current directors on file is bad data but not an error state here
parties = []

offices = Office.convert_obj_list(Office.get_current(cursor, identifier)) or {}

# mirror the /sharestructure resource: current structure is the one with no end event
share_structs = ShareObject.get_all(cursor, identifier) or []
share_struct = next((x for x in share_structs if not x.end_event_id), None)
share_classes = share_struct.to_dict()['shareClasses'] if share_struct else []

resolutions = Business.get_resolutions(cursor, identifier)

return {
'business': cls._business_dict(business, orig_identifier, cursor),
'parties': [cls._normalize_party(party) for party in parties],
'offices': {
office_type: cls._normalize_office(office)
for office_type, office in offices.items() if office_type in cls.OFFICE_TYPES
},
'shareClasses': [cls._normalize_share_class(share_class) for share_class in share_classes],
'resolutions': [{'date': date} for date in resolutions],
}

@classmethod
def _business_dict(cls, business: Business, orig_identifier: str, cursor) -> Dict:
"""Return the business section in the shape of LEAR's slim business json."""
return {
'identifier': orig_identifier,
'legalName': business.corp_name,
'legalType': business.corp_type,
'state': business.lear_state,
# tri-state: None when COLIN can't compute good standing for the corp
'goodStanding': business.good_standing,
# find_by_identifier returns the COLIN 'True'/'False' string
'adminFreeze': business.admin_freeze == 'True',
'foundingDate': cls._to_iso_datetime(business.founding_date),
'taxId': business.business_number,
'hasFutureEffectiveFiling': cls._has_future_effective_filing(cursor, business.corp_num),
}

@staticmethod
def _has_future_effective_filing(cursor, corp_num: str) -> bool:
"""Return whether any filing has an effective date still in the future."""
current_date = datetime.now(timezone.utc).strftime('%Y-%m-%d')
cursor.execute(
"""
select count(*)
from event join filing on event.event_id = filing.event_id
where event.corp_num=:corp_num
and filing.effective_dt > TO_DATE(:current_date, 'YYYY-mm-dd')
""",
corp_num=corp_num,
current_date=current_date
)
return cursor.fetchone()[0] > 0

@classmethod
def _normalize_party(cls, party: Party) -> Dict:
"""Return a party in the structure of LEAR's /parties items."""
raw = party.as_dict()
return {
'officer': {**raw['officer'], 'id': raw['id'], 'email': None},
'deliveryAddress': cls._normalize_address(raw['deliveryAddress']),
'mailingAddress': cls._normalize_address(raw['mailingAddress']),
'roles': raw['roles'] or [],
}

@classmethod
def _normalize_office(cls, office: Dict) -> Dict:
"""Return an office's addresses in LEAR structure."""
return {
'deliveryAddress': cls._normalize_address(office.get('deliveryAddress')),
'mailingAddress': cls._normalize_address(office.get('mailingAddress')),
}

@classmethod
def _normalize_address(cls, address: Optional[Dict]) -> Optional[Dict]:
"""Return an Address.as_dict in the structure of LEAR's address json."""
if not address:
return None
return {
'id': address.get('addressId'),
'streetAddress': address.get('streetAddress'),
'streetAddressAdditional': address.get('streetAddressAdditional'),
'addressCity': address.get('addressCity'),
'addressRegion': address.get('addressRegion'),
'addressCountry': cls._country_to_alpha2(address.get('addressCountry')),
'postalCode': address.get('postalCode'),
'deliveryInstructions': address.get('deliveryInstructions'),
}

@classmethod
def _normalize_share_class(cls, share_class: Dict) -> Dict:
"""Return a share class in the structure of LEAR's /share-classes items."""
return {
'id': share_class['id'],
'name': share_class['name'],
# COLIN never stores a priority - the class id preserves creation order
'priority': share_class['displayOrder'],
'hasMaximumShares': share_class['hasMaximumShares'],
'maxNumberOfShares': cls._to_int(share_class['maxNumberOfShares']),
'hasParValue': share_class['hasParValue'],
'parValue': float(share_class['parValue']) if share_class['parValue'] is not None else None,
'currency': share_class['currency'],
'currencyAdditional': share_class['currencyAdditional'],
'hasRightsOrRestrictions': share_class['hasRightsOrRestrictions'],
'series': [cls._normalize_share_series(series) for series in share_class['series']],
}

@classmethod
def _normalize_share_series(cls, series: Dict) -> Dict:
"""Return a share series in the structure of LEAR's series json."""
return {
'id': series['id'],
'name': series['name'],
'priority': series['displayOrder'],
'hasMaximumShares': series['hasMaximumShares'],
'maxNumberOfShares': cls._to_int(series['maxNumberOfShares']),
'hasRightsOrRestrictions': series['hasRightsOrRestrictions'],
}

_country_cache: Dict[str, str] = {}

@classmethod
def _country_to_alpha2(cls, country: Optional[str]) -> Optional[str]:
"""Map COLIN's country description to the alpha-2 code LEAR stores."""
if not country:
return country
if len(country) == 2: # already a code
return country
if country not in cls._country_cache:
try:
cls._country_cache[country] = pycountry.countries.search_fuzzy(country)[0].alpha_2
except LookupError:
current_app.logger.error('Could not map COLIN country %s to an alpha-2 code', country)
cls._country_cache[country] = country
return cls._country_cache[country]

@staticmethod
def _to_int(value) -> Optional[int]:
"""Coerce an Oracle NUMBER to int, preserving None."""
return int(value) if value is not None else None

@staticmethod
def _to_iso_datetime(value: Optional[str]) -> Optional[str]:
"""Rewrite convert_to_json_datetime's '-00:00' suffix to the ISO '+00:00' LEAR uses."""
if value and value.endswith('-00:00'):
return value[:-6] + '+00:00'
return value
2 changes: 1 addition & 1 deletion colin-api/src/colin_api/models/filing.py
Original file line number Diff line number Diff line change
Expand Up @@ -1298,7 +1298,7 @@ def get_future_effective_filings(cls, business: Business) -> List:
"""Get the list of all future effective filings for a business."""
try:
future_effective_filings = []
current_date = datetime.datetime.utcnow().strftime('%Y-%m-%d')
current_date = datetime.datetime.now(datetime.timezone.utc).strftime('%Y-%m-%d')
cursor = DB.connection.cursor()
cursor.execute(
"""
Expand Down
3 changes: 3 additions & 0 deletions colin-api/src/colin_api/models/shares.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class ShareClass(Share): # pylint: disable=too-many-instance-attributes;

# pylint: disable=too-few-public-methods
currency_type = None
other_currency = None
has_par_value = None
par_value_amt = None
series = None
Expand All @@ -77,6 +78,7 @@ def to_dict(self):
'maxNumberOfShares': self.max_number_shares,
'parValue': self.par_value_amt,
'currency': self.currency_type,
'currencyAdditional': self.other_currency,
'hasMaximumShares': self.has_max_shares == 'N' or False,
'hasParValue': self.has_par_value == 'Y' or False,
'hasRightsOrRestrictions': self.has_special_rights == 'Y' or False,
Expand Down Expand Up @@ -140,6 +142,7 @@ def _get_share_classes(cls, cursor, event_id, corp_num):
row = dict(zip([x[0].lower() for x in description], row))
share_class = ShareClass()
share_class.currency_type = row['currency_typ_cd']
share_class.other_currency = row['other_currency']
share_class.has_max_shares = row['max_share_ind']
share_class.has_special_rights = row['spec_rights_ind']
share_class.has_par_value = row['par_value_ind']
Expand Down
Loading
Loading