Skip to content

Commit

Permalink
18971 Finished some TODOs and incremental work on amalgamating busine…
Browse files Browse the repository at this point in the history
…ss validations (bcgov#596)

* - app version = 5.6.12
- finished stepper validity code
- cleaned up some store code
- misc cleanup
- named and sorted rules

* - added spinner (experimental)

* wip

---------

Co-authored-by: Severin Beauvais <severin.beauvais@gov.bc.ca>
  • Loading branch information
2 people authored and JazzarKarim committed Jan 26, 2024
1 parent 372ee91 commit 61bce6e
Show file tree
Hide file tree
Showing 10 changed files with 165 additions and 81 deletions.
4 changes: 2 additions & 2 deletions 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 package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "business-create-ui",
"version": "5.6.11",
"version": "5.6.12",
"private": true,
"appName": "Create UI",
"sbcName": "SBC Common Components",
Expand Down
47 changes: 34 additions & 13 deletions src/components/Amalgamation/AmalgamatingBusinesses.vue
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,16 @@
</v-card>
</v-expand-transition>

<BusinessTable
class="mt-8"
:class="{ 'invalid-section': getShowErrors && !businessTableValid }"
@valid="businessTableValid=$event"
/>

<!-- snackbar to temporarily show fetch errors -->
<v-snackbar
v-model="snackbar"
timeout="5000"
timeout="3000"
>
{{ snackbarText }}

Expand All @@ -136,12 +142,6 @@
</v-btn>
</template>
</v-snackbar>

<BusinessTable
class="mt-8"
:class="{ 'invalid-section': getShowErrors && !businessTableValid }"
@valid="businessTableValid=$event"
/>
</div>
</template>

Expand Down Expand Up @@ -187,14 +187,17 @@ export default class AmalgamatingBusinesses extends Mixins(CommonMixin) {
isAddingAmalgamatingForeignBusiness = false
async saveAmalgamatingBusiness (businessLookup: BusinessLookupResultIF): Promise<void> {
// Get the auth info, business info, addresses and filings in parallel.
// Return data array; if any call failed, that item will be undefined.
// Show spinner since the network calls below can take a few seconds.
this.$root.$emit('showSpinner', true)
// Get the auth info, business info, addresses and latest filing concurrently.
// Return data array; if any call failed, that item will be null.
const data = await Promise.allSettled([
AuthServices.fetchAuthInfo(businessLookup.identifier),
LegalServices.fetchBusinessInfo(businessLookup.identifier),
LegalServices.fetchAddresses(businessLookup.identifier),
LegalServices.fetchFirstOrOnlyFiling(businessLookup.identifier)
]).then(results => results.map((result: any) => result.value))
]).then(results => results.map((result: any) => result.value || null))
const authInfo = data[0]
const businessInfo = data[1]
Expand All @@ -207,6 +210,10 @@ export default class AmalgamatingBusinesses extends Mixins(CommonMixin) {
if (this.isRoleStaff) {
this.snackbarText = 'Business doesn\'t exist in LEAR.'
this.snackbar = true
// Hide spinner.
this.$root.$emit('showSpinner', false)
return
}
Expand All @@ -222,25 +229,36 @@ export default class AmalgamatingBusinesses extends Mixins(CommonMixin) {
// Close the "Add an Amalgamating Business" panel.
this.isAddingAmalgamatingBusiness = false
// Hide spinner.
this.$root.$emit('showSpinner', false)
return
}
// Check for Legal API fetch issues.
if (!businessInfo || !addresses || !firstFiling) {
this.snackbarText = 'Unable to add that business.'
this.snackbar = true
// Hide spinner.
this.$root.$emit('showSpinner', false)
return
}
// Verify that identifier doesn't already exist.
// Check for duplicate.
if (this.getAmalgamatingBusinesses.find((b: any) => b.identifier === businessInfo.identifier)) {
this.snackbarText = 'Business is already in table.'
this.snackbar = true
// Hide spinner.
this.$root.$emit('showSpinner', false)
return
}
// If there is a state filing and restoration expiry date isn't in the past and the state filing is a
// limited restoration or limited restoration extension, then this business is in limited restoration.
// This business is in limited restoration if there is a state filing and restoration expiry date isn't
// in the past and the state filing is a limited restoration or a limited restoration extension.
const isLimitedRestoration = async (): Promise<boolean> => {
// check for no state filing
if (!businessInfo.stateFiling) return false
Expand Down Expand Up @@ -273,6 +291,9 @@ export default class AmalgamatingBusinesses extends Mixins(CommonMixin) {
// Close the "Add an Amalgamating Business" panel.
this.isAddingAmalgamatingBusiness = false
// Hide spinner.
this.$root.$emit('showSpinner', false)
}
/** Sets validity according to various flags. */
Expand Down
8 changes: 7 additions & 1 deletion src/components/Amalgamation/BusinessStatus.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export default class BusinessStatus extends Vue {
case AmlStatuses.ERROR_LIMITED_RESTORATION:
case AmlStatuses.ERROR_NOT_AFFILIATED:
case AmlStatuses.ERROR_NOT_IN_GOOD_STANDING:
case AmlStatuses.ERROR_ULC_MISMATCH:
return 'mdi-alert'
default:
Expand All @@ -62,6 +63,7 @@ export default class BusinessStatus extends Vue {
case AmlStatuses.ERROR_LIMITED_RESTORATION:
case AmlStatuses.ERROR_NOT_AFFILIATED:
case AmlStatuses.ERROR_NOT_IN_GOOD_STANDING:
case AmlStatuses.ERROR_ULC_MISMATCH:
return 'warning'
default:
Expand All @@ -81,6 +83,7 @@ export default class BusinessStatus extends Vue {
case AmlStatuses.ERROR_LIMITED_RESTORATION:
case AmlStatuses.ERROR_NOT_AFFILIATED:
case AmlStatuses.ERROR_NOT_IN_GOOD_STANDING:
case AmlStatuses.ERROR_ULC_MISMATCH:
return 'Attention Required'
default:
Expand All @@ -99,7 +102,7 @@ export default class BusinessStatus extends Vue {
return 'A foreign corporation cannot be amalgamated except by Registries staff.'
case AmlStatuses.ERROR_FOREIGN_UNLIMITED:
return 'A foreign corporation must not amalgamate with a limited company and continue as ' +
'an unlimited liability company.'
'an Unlimited Liability Company.'
case AmlStatuses.ERROR_FUTURE_EFFECTIVE_FILING:
return 'This business has a future effective filing. It cannot be part of an amalgamation ' +
'until all future effective filings have come into effect.'
Expand All @@ -112,6 +115,9 @@ export default class BusinessStatus extends Vue {
case AmlStatuses.ERROR_NOT_IN_GOOD_STANDING:
return 'This business is not in good standing. This filing cannot be submitted until all ' +
'businesses are in good standing.'
case AmlStatuses.ERROR_ULC_MISMATCH:
return 'A BC Unlimited Liability Company must amalgamate to form a new BC Unlimited Liability ' +
'Company.'
default:
return null // should never happen
Expand Down
5 changes: 3 additions & 2 deletions src/components/common/Stepper.vue
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ import { RegistrationStateIF } from '@/interfaces'
@Component({})
export default class Stepper extends Vue {
@Getter(useStore) getAmalgamatingBusinessesValid!: boolean
@Getter(useStore) getRegistration!: RegistrationStateIF
@Getter(useStore) getShowErrors!: boolean
@Getter(useStore) getSteps!: Array<any>
Expand All @@ -90,8 +91,8 @@ export default class Stepper extends Vue {
/** Returns true if the step route is valid. */
isValid (route: RouteNames): boolean {
switch (route) {
case RouteNames.AMALG_REG_INFORMATION: return false // *** TODO
case RouteNames.AMALG_REG_BUSINESS_INFO: return false // *** TODO
case RouteNames.AMALG_REG_INFORMATION: return this.getAmalgamatingBusinessesValid
case RouteNames.AMALG_REG_BUSINESS_INFO: return this.isDefineCompanyValid
case RouteNames.AMALG_REG_PEOPLE_ROLES: return this.isAddPeopleAndRolesValid
case RouteNames.AMALG_REG_SHARE_STRUCTURE: return this.isCreateShareStructureValid
case RouteNames.AMALG_REG_REVIEW_CONFIRM: return this.isFilingValid
Expand Down
1 change: 1 addition & 0 deletions src/enums/amalgamationEnums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export enum AmlStatuses {
ERROR_LIMITED_RESTORATION,
ERROR_NOT_AFFILIATED,
ERROR_NOT_IN_GOOD_STANDING,
ERROR_ULC_MISMATCH,
}

export enum AmlRoles {
Expand Down
136 changes: 81 additions & 55 deletions src/mixins/amalgamation-mixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,94 +15,120 @@ export default class AmalgamationMixin extends Vue {
@Getter(useStore) isTypeBcCcc!: boolean
@Getter(useStore) isTypeBcUlcCompany!: boolean

// *** TODO: finish this, maybe name them something recognizable...
/** Iterable array of rule functions, sorted by importance. */
readonly rules = [
this.rule1,
this.rule2,
this.rule3,
this.rule4,
this.rule5,
this.rule6,
this.rule7
this.notAffiliated,
this.notInGoodStanding,
this.limitedRestoration,
this.futureEffectiveFiling,
this.foreign,
this.foreignUlc,
this.cccMismatch,
this.ulcMismatch
]

/** True if there a limited company in the table. */
get isAnyLimited (): boolean {
return this.getAmalgamatingBusinesses.some(business =>
(business.type === AmlTypes.LEAR && business.legalType === CorpTypeCd.BC_COMPANY)
)
/** If we don't have an address, assume business is not affiliated (except for staff). */
notAffiliated (business: AmalgamatingBusinessIF): AmlStatuses {
if (business.type === AmlTypes.LEAR && !business.address && !this.isRoleStaff) {
return AmlStatuses.ERROR_NOT_AFFILIATED
}
return null
}

/** True if there an unlimited company in the table in Alberta, Nova Scotia or USA. */
get isAnyUnlimitedAbNsUsa (): boolean {
return this.getAmalgamatingBusinesses.some(business =>
(business.type === AmlTypes.LEAR && business.legalType === CorpTypeCd.BC_COMPANY)
)
/** Disallow if NIGS (except for staff). */
notInGoodStanding (business: AmalgamatingBusinessIF): AmlStatuses {
if (business.type === AmlTypes.LEAR && business.isNotInGoodStanding && !this.isRoleStaff) {
return AmlStatuses.ERROR_NOT_IN_GOOD_STANDING
}
return null
}

// *** TODO
// A BC Company cannot amalgamate with an existing Unlimited Liability Company from Alberta,
// Nova Scotia, or the USA to form a BC Unlimited Liability Company.
/** Disallow if limited restoration (except for staff). */
limitedRestoration (business: AmalgamatingBusinessIF): AmlStatuses {
if (business.type === AmlTypes.LEAR && business.isLimitedRestoration && !this.isRoleStaff) {
return AmlStatuses.ERROR_LIMITED_RESTORATION
}
return null
}

// disallow foreign altogether if not staff
// (could happen if staff added it and regular user resumes draft)
rule1 (business: AmalgamatingBusinessIF): AmlStatuses {
if (business.type === AmlTypes.FOREIGN && !this.isRoleStaff) {
return AmlStatuses.ERROR_FOREIGN
/** Disallow if future effective filing. */
futureEffectiveFiling (business: AmalgamatingBusinessIF): AmlStatuses {
if (business.type === AmlTypes.LEAR && business.isFutureEffective) {
return AmlStatuses.ERROR_FUTURE_EFFECTIVE_FILING
}
return null
}

// disallow foreign into ULC if there is also a limited
rule2 (business: AmalgamatingBusinessIF): AmlStatuses {
if (business.type === AmlTypes.FOREIGN && this.isTypeBcUlcCompany && this.isAnyLimited) {
/**
* Disallow altogether if foreign (except for staff).
* (Could happen if staff added it and regular user resumes draft.)
*/
foreign (business: AmalgamatingBusinessIF): AmlStatuses {
if (business.type === AmlTypes.FOREIGN && !this.isRoleStaff) {
return AmlStatuses.ERROR_FOREIGN
}
return null
}

// if we don't have an address, assume business is not affiliated (non-staff only)
rule3 (business: AmalgamatingBusinessIF): AmlStatuses {
// *** TODO: revert staff check
if (business.type === AmlTypes.LEAR && !business.address /* && !this.isRoleStaff */) {
return AmlStatuses.ERROR_NOT_AFFILIATED
/** Disallow if foreign into ULC if there is also a limited. */
foreignUlc (business: AmalgamatingBusinessIF): AmlStatuses {
if (business.type === AmlTypes.FOREIGN && this.isTypeBcUlcCompany && this.isAnyLimited) {
return AmlStatuses.ERROR_FOREIGN
}
return null
}

// identify CCC mismatch
rule4 (business: AmalgamatingBusinessIF): AmlStatuses {
/** Disallow CCC mismatch. */
cccMismatch (business: AmalgamatingBusinessIF): AmlStatuses {
if (business.type === AmlTypes.LEAR && business.legalType === CorpTypeCd.BC_CCC && !this.isTypeBcCcc) {
return AmlStatuses.ERROR_CCC_MISMATCH
}
return null
}

// disallow limited restoration if not staff
rule5 (business: AmalgamatingBusinessIF): AmlStatuses {
// *** TODO: revert staff check
if (business.type === AmlTypes.LEAR && business.isLimitedRestoration /* && !this.isRoleStaff */) {
return AmlStatuses.ERROR_LIMITED_RESTORATION
/** Disallow ULC mismatch. */
ulcMismatch (business: AmalgamatingBusinessIF): AmlStatuses {
if (
business.type === AmlTypes.LEAR &&
business.legalType === CorpTypeCd.BC_ULC_COMPANY &&
!this.isTypeBcUlcCompany
) {
return AmlStatuses.ERROR_ULC_MISMATCH
}
return null
}

// disallow NIGS if not staff
rule6 (business: AmalgamatingBusinessIF): AmlStatuses {
// *** TODO: revert staff check
if (business.type === AmlTypes.LEAR && business.isNotInGoodStanding /* && !this.isRoleStaff */) {
return AmlStatuses.ERROR_NOT_IN_GOOD_STANDING
}
return null
// TODO: cannot add foreign ULC if there is a BC company and ted is ULC

// TODO: cannot add BC company if there is a foreign ULC and ted is ULC

//
// HELPERS
//

/** True if there a foreign company in the table. */
get isAnyForeign (): boolean {
return this.getAmalgamatingBusinesses.some(business => (business.type === AmlTypes.FOREIGN))
}

// check for future effective filing
rule7 (business: AmalgamatingBusinessIF): AmlStatuses {
// *** TODO: revert staff check
if (business.type === AmlTypes.LEAR && business.isFutureEffective /* && !this.isRoleStaff */) {
return AmlStatuses.ERROR_FUTURE_EFFECTIVE_FILING
}
return null
/** True if there a CCC in the table. */
get isAnyCcc (): boolean {
return this.getAmalgamatingBusinesses.some(business =>
(business.type === AmlTypes.LEAR && business.legalType === CorpTypeCd.BC_CCC)
)
}

/** True if there a limited company in the table. */
get isAnyLimited (): boolean {
return this.getAmalgamatingBusinesses.some(business =>
(business.type === AmlTypes.LEAR && business.legalType === CorpTypeCd.BC_COMPANY)
)
}

/** True if there is an unlimited company in the table. */
get isAnyUnlimited (): boolean {
return this.getAmalgamatingBusinesses.some(business =>
(business.type === AmlTypes.LEAR && business.legalType === CorpTypeCd.BC_ULC_COMPANY)
)
}
}
Loading

0 comments on commit 61bce6e

Please sign in to comment.