Skip to content

Commit

Permalink
Initial changes for adding in displayName for legalName changes (SP/GP).
Browse files Browse the repository at this point in the history
Minor fix

Small tweak, code complexity

Fix unit test

re-do feature flag

Fix LD flags

Remove updating business name in entities table, we no longer use this field. It comes from LEAR. Rewire loadBusiness to query lear, compute the business name off of LEAR's results

15603 - Initial changes for adding in displayName for legalName changes (SP/GP). (bcgov#2690)

* Initial changes for adding in displayName for legalName changes (SP/GP).

* Minor fix

* Small tweak, code complexity

* Fix unit test

* re-do feature flag

* Fix LD flags
  • Loading branch information
seeker25 committed Jan 25, 2024
1 parent ea5d9f0 commit c24d261
Show file tree
Hide file tree
Showing 17 changed files with 107 additions and 90 deletions.
2 changes: 1 addition & 1 deletion auth-api/src/auth_api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@
from auth_api.extensions import mail
from auth_api.models import db, ma
from auth_api.resources import endpoints
from auth_api.services.flags import flags
from auth_api.utils.cache import cache
from auth_api.utils.run_version import get_run_version
from auth_api.utils.util_logging import setup_logging
from auth_api.services import flags

setup_logging(os.path.join(_Config.PROJECT_ROOT, 'logging.conf')) # important to do this first

Expand Down
6 changes: 6 additions & 0 deletions auth-api/src/auth_api/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,12 @@ class _Config: # pylint: disable=too-few-public-methods
LEGAL_API_VERSION_2 = os.getenv('LEGAL_API_VERSION_2', '')

LEAR_AFFILIATION_DETAILS_URL = f'{LEGAL_API_URL + LEGAL_API_VERSION_2}/businesses/search'

# Temporary until legal names is implemented.
LEGAL_API_ALTERNATE_URL = os.getenv('LEGAL_API_ALTERNATE_URL', '')
# Temporary until legal names is implemented.
LEAR_ALTERNATE_AFFILIATION_DETAILS_URL = f'{LEGAL_API_ALTERNATE_URL + LEGAL_API_VERSION_2}/businesses/search'

NAMEX_AFFILIATION_DETAILS_URL = f'{NAMEX_API_URL}/requests/search'

# NATS Config
Expand Down
11 changes: 0 additions & 11 deletions auth-api/src/auth_api/models/affiliation.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,9 @@
from __future__ import annotations
from typing import List

from flask import current_app
from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.orm import contains_eager, relationship

from auth_api.utils.enums import CorpType

from .base_model import VersionedModel
from .db import db
from .entity import Entity as EntityModel
Expand Down Expand Up @@ -53,14 +50,6 @@ def filter_environment(cls, environment: str):
query = query.filter(Affiliation.environment.is_(None))
return query

@property
def affiliation_details_url(self) -> str:
"""The url of the source service containing the affiliations full data."""
if self.entity.corp_type_code == CorpType.NR.value:
return current_app.config.get('NAMEX_AFFILIATION_DETAILS_URL')
# only have LEAR and NAMEX affiliations
return current_app.config.get('LEAR_AFFILIATION_DETAILS_URL')

@classmethod
def find_affiliation_by_org_and_entity_ids(cls, org_id, entity_id, environment) -> Affiliation:
"""Return an affiliation for the provided org and entity ids."""
Expand Down
2 changes: 0 additions & 2 deletions auth-api/src/auth_api/services/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,3 @@
from .user import User
from .user_settings import UserSettings
from .flags import Flags

flags = Flags()
38 changes: 31 additions & 7 deletions auth-api/src/auth_api/services/affiliation.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
from auth_api.models.membership import Membership as MembershipModel
from auth_api.schemas import AffiliationSchema
from auth_api.services.entity import Entity as EntityService
from auth_api.services.flags import flags
from auth_api.services.org import Org as OrgService
from auth_api.services.user import User as UserService
from auth_api.utils.enums import ActivityAction, CorpType, NRActionCodes, NRNameStatus, NRStatus
Expand Down Expand Up @@ -392,12 +393,23 @@ def fix_stale_affiliations(org_id: int, entity_details: Dict, environment: str =

current_app.logger.debug('>fix_stale_affiliations')

@staticmethod
def _affiliation_details_url(affiliation: AffiliationModel) -> str:
"""Determine url to call for affiliation details."""
# only have LEAR and NAMEX affiliations
if affiliation.entity.corp_type_code == CorpType.NR.value:
return current_app.config.get('NAMEX_AFFILIATION_DETAILS_URL')
# Temporary until legal names is implemented.
if flags.is_on('enable-alternate-names-mbr', default=False):
return current_app.config.get('LEAR_ALTERNATE_AFFILIATION_DETAILS_URL')
return current_app.config.get('LEAR_AFFILIATION_DETAILS_URL')

@staticmethod
async def get_affiliation_details(affiliations: List[AffiliationModel]) -> List:
"""Return affiliation details by calling the source api."""
url_identifiers = {} # i.e. turns into { url: [identifiers...] }
for affiliation in affiliations:
url = affiliation.affiliation_details_url
url = Affiliation._affiliation_details_url(affiliation)
url_identifiers.setdefault(url, [affiliation.entity.business_identifier])\
.append(affiliation.entity.business_identifier)

Expand Down Expand Up @@ -428,8 +440,7 @@ def sort_key(item):
raise ServiceUnavailableException('Failed to get affiliation details') from err

@staticmethod
def _combine_affiliation_details(details):
"""Parse affiliation details responses and combine draft entities with NRs if applicable."""
def _group_details(details):
name_requests = {}
businesses = []
drafts = []
Expand All @@ -450,17 +461,24 @@ def _combine_affiliation_details(details):
drafts = [
{'draftType': CorpType.RTMP.value if draft['legalType'] in draft_reg_types
else CorpType.TMP.value, **draft} for draft in data[drafts_key]]
return name_requests, businesses, drafts

@staticmethod
def _update_draft_type_for_amalgamation_nr(business):
if business.get('draftType', None) \
and business['nameRequest']['request_action_cd'] == NRActionCodes.AMALGAMATE.value:
business['draftType'] = CorpType.ATMP.value
return business

@staticmethod
def _combine_nrs(name_requests, businesses, drafts):
# combine NRs
for business in drafts + businesses:
# Only drafts have nrNumber coming back from legal-api.
if 'nrNumber' in business and (nr_num := business['nrNumber']):
if business['nrNumber'] in name_requests:
business['nameRequest'] = name_requests[nr_num]['nameRequest']
# Update the draft type if the draft NR request is for amalgamation
if business.get('draftType', None) \
and business['nameRequest']['request_action_cd'] == NRActionCodes.AMALGAMATE.value:
business['draftType'] = CorpType.ATMP.value
business = Affiliation._update_draft_type_for_amalgamation_nr(business)
# Remove the business if the draft associated to the NR is consumed.
if business['nameRequest']['stateCd'] == NRStatus.CONSUMED.value:
drafts.remove(business)
Expand All @@ -471,6 +489,12 @@ def _combine_affiliation_details(details):

return [name_request for nr_num, name_request in name_requests.items()] + drafts + businesses

@staticmethod
def _combine_affiliation_details(details):
"""Parse affiliation details responses and combine draft entities with NRs if applicable."""
name_requests, businesses, drafts = Affiliation._group_details(details)
return Affiliation._combine_nrs(name_requests, businesses, drafts)

@staticmethod
def _get_nr_details(nr_number: str):
"""Return NR details by calling legal-api."""
Expand Down
33 changes: 19 additions & 14 deletions auth-api/src/auth_api/services/flags.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright © 2019 Province of British Columbia
# Copyright © 2022 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.
Expand All @@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""Manage the Feature Flags initialization, setup and service."""
import logging
from flask import current_app
from ldclient import get as ldclient_get, set_config as ldclient_set_config # noqa: I001
from ldclient.config import Config # noqa: I005
Expand Down Expand Up @@ -48,24 +49,18 @@ def init_app(self, app):

if self.sdk_key or app.env != 'production':

if app.env == 'production':
config = Config(sdk_key=self.sdk_key)
else:
if app.env == 'testing':
factory = Files.new_data_source(paths=['flags.json'], auto_update=True)
config = Config(sdk_key=self.sdk_key,
update_processor_class=factory,
send_events=False)
else:
config = Config(sdk_key=self.sdk_key)

ldclient_set_config(config)
client = ldclient_get()

app.extensions['featureflags'] = client
app.teardown_appcontext(self.teardown)

def teardown(self, exception): # pylint: disable=unused-argument; flask method signature
"""Destroy all objects created by this extension."""
client = current_app.extensions['featureflags']
client.close()

def _get_client(self):
try:
Expand All @@ -75,6 +70,7 @@ def _get_client(self):
self.init_app(current_app)
client = current_app.extensions['featureflags']
except KeyError:
logging.warning("Couldn\'t retrieve launch darkly client from extensions.")
client = None

return client
Expand All @@ -89,24 +85,33 @@ def _user_as_key(user: User):
.set('firstName', user.firstname)\
.set('lastName', user.lastname).build()

def is_on(self, flag: str, user: User = None) -> bool:
def is_on(self, flag: str, default: bool = False, user: User = None) -> bool:
"""Assert that the flag is set for this user."""
client = self._get_client()

if not client:
return default

if user:
flag_user = self._user_as_key(user)
else:
flag_user = self._get_anonymous_user()

return bool(client.variation(flag, flag_user, None))
return bool(client.variation(flag, flag_user, default))

def value(self, flag: str, user: User = None) -> bool:
def value(self, flag: str, default=None, user: User = None):
"""Retrieve the value of the (flag, user) tuple."""
client = self._get_client()

if not client:
return default

if user:
flag_user = self._user_as_key(user)
else:
flag_user = self._get_anonymous_user()

return client.variation(flag, flag_user, None)
return client.variation(flag, flag_user, default)


flags = Flags()
6 changes: 3 additions & 3 deletions auth-api/tests/unit/services/test_flags.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def setup():
"""Initialize app with dev env for testing."""
global app
app = Flask(__name__)
app.env = 'development'
app.env = 'testing'


def test_flags_constructor_no_app(setup):
Expand Down Expand Up @@ -152,8 +152,8 @@ def test_flags_read_flag_values_unique_user(setup, test_name, flag_name, expecte
with app.app_context():
flags = Flags()
flags.init_app(app)
val = flags.value(flag_name, user)
flag_on = flags.is_on(flag_name, user)
val = flags.value(flag_name, user=user)
flag_on = flags.is_on(flag_name, user=user, default=False)

assert val == expected
assert flag_on
4 changes: 2 additions & 2 deletions auth-web/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion auth-web/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "auth-web",
"version": "2.4.59",
"version": "2.4.61",
"appName": "Auth Web",
"sbcName": "SBC Common Components",
"private": true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ import { mapActions } from 'pinia'
},
methods: {
...mapActions(useBusinessStore, [
'updateBusinessName',
'updateFolioNumber'
])
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -708,12 +708,6 @@ export default defineComponent({
if (addResponse?.status !== StatusCodes.CREATED) {
emit('unknown-error')
}
// try to update business name
const businessResponse = await businessStore.updateBusinessName(businessIdentifier.value)
// check if update didn't succeed
if (businessResponse?.status !== StatusCodes.OK) {
emit('unknown-error')
}
// let parent know that add was successful
emit('add-success', businessIdentifier.value)
} catch (exception) {
Expand Down
9 changes: 9 additions & 0 deletions auth-web/src/models/affiliation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,22 @@ export interface AffiliationFilter {
actions?: string
}

export interface AlternateNames {
entityType?: string
identifier?: string
nameRegisteredDate?: string
nameStartDate?: string
operatingName?: string
}

export interface AffiliationResponse {
identifier?: string
draftType?: CorpTypes
legalType?: CorpTypes
businessNumber?: string
name?: string
legalName?: string
alternateNames?: AlternateNames[]
contacts?: Contact[]
corpType?: CorpType
corpSubType?: CorpType
Expand Down
13 changes: 5 additions & 8 deletions auth-web/src/models/business.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { AffiliationInviteInfo, AlternateNames } from '@/models/affiliation'
import { AmalgamationTypes, FilingTypes, NrRequestActionCodes, NrRequestTypeCodes } from '@bcrs-shared-components/enums'
import { CorpTypes, LearFilingTypes, NrTargetTypes } from '@/util/constants'
import { AffiliationInviteInfo } from '@/models/affiliation'
import { Contact } from './contact'

export interface LoginPayload {
Expand Down Expand Up @@ -57,11 +57,6 @@ export interface Businesses {
entities: Business[]
}

export interface UpdateBusinessNamePayload {
businessIdentifier: string
name: string
}

// see https://github.com/bcgov/business-schemas/blob/master/src/registry_schemas/schemas/name_request.json
export interface NameRequest {
actions?: Array<Action>
Expand Down Expand Up @@ -145,7 +140,9 @@ export interface PasscodeResetLoad {
}

export interface LearBusiness {
identifier: string,
legalName: string,
identifier: string
legalName: string
legalType: string
alternateNames: AlternateNames[]
taxId?: string
}
6 changes: 1 addition & 5 deletions auth-web/src/services/business.services.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { BNRequest, ResubmitBNRequest } from '@/models/request-tracker'
import { Business, BusinessRequest, FolioNumberload, PasscodeResetLoad, UpdateBusinessNamePayload } from '@/models/business'
import { Business, BusinessRequest, FolioNumberload, PasscodeResetLoad } from '@/models/business'
import { AxiosResponse } from 'axios'
import CommonUtils from '@/util/common-util'
import ConfigHelper from '@/util/config-helper'
Expand Down Expand Up @@ -51,10 +51,6 @@ export default class BusinessService {
return axios.patch(`${ConfigHelper.getAuthAPIUrl()}/entities/${folioNumber.businessIdentifier}`, folioNumber)
}

static async updateBusinessName (updatePayload: UpdateBusinessNamePayload): Promise<AxiosResponse<any>> {
return axios.patch(`${ConfigHelper.getAuthAPIUrl()}/entities/${updatePayload.businessIdentifier}`, updatePayload)
}

static async resetBusinessPasscode (passcodeResetLoad: PasscodeResetLoad): Promise<AxiosResponse<any>> {
return axios.patch(`${ConfigHelper.getAuthAPIUrl()}/entities/${passcodeResetLoad.businessIdentifier}`,
{
Expand Down
Loading

0 comments on commit c24d261

Please sign in to comment.