diff --git a/package-lock.json b/package-lock.json index b70c9e3e..e812ec95 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "business-edit-ui", - "version": "4.5.3", + "version": "4.5.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "business-edit-ui", - "version": "4.5.3", + "version": "4.5.4", "dependencies": { "@babel/compat-data": "^7.21.5", "@bcrs-shared-components/action-chip": "1.1.5", diff --git a/package.json b/package.json index 8bf66b45..c9d70f1b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "business-edit-ui", - "version": "4.5.3", + "version": "4.5.4", "private": true, "appName": "Edit UI", "sbcName": "SBC Common Components", diff --git a/src/components/common/YourCompany/ChangeBusinessType.vue b/src/components/common/YourCompany/ChangeBusinessType.vue index 87273bd9..e3a7a686 100644 --- a/src/components/common/YourCompany/ChangeBusinessType.vue +++ b/src/components/common/YourCompany/ChangeBusinessType.vue @@ -100,8 +100,9 @@ @@ -112,6 +113,7 @@

@@ -119,6 +121,17 @@

+
+

+ An alteration of business type Name Request is required to make this change. After the name is approved, + you can then select 'change' beside the company name to update it. +

+
+

Businesses can only be altered to specific types. If the business type you want is @@ -145,7 +158,7 @@ id="done-btn" large color="primary" - :disabled="!confirmArticles || minimumThreeDirectorError" + :disabled="disableDoneButton" @click="submitTypeChange()" > Done @@ -169,7 +182,10 @@ cols="2" class="mt-n2" > -

+
()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/) return VALID_FORMAT.test(value) } @Watch('validate') - private onValidate (): void { + onValidate (): void { this.$refs.correctNrForm.validate() } /** Watch for form submission and emit results. */ @Watch('formType') - private async onSubmit (): Promise { + async onSubmit (): Promise { // this component should only see correct-new-nr form type if (this.formType === CorrectNameOptions.CORRECT_NEW_NR) { try { @@ -199,14 +202,11 @@ export default class CorrectNameRequest extends Mixins(CommonMixin, NameRequestM this.applicantEmail ) - if (this.getEntityType !== nr.legalType) { + if (this.isNameRequestInvalid(nr)) { // Invalid NR type, inform parent the process is done and prompt confirm dialog this.emitIsSaved() - const dialogContent = `

This ${GetCorpFullDescription(nr.entity_type_cd)} ` + - `Name Request does not match the current business type ` + - `${GetCorpFullDescription(this.getEntityType)}.\n\n` + - `The Name Request type must match the business type before you can continue.

` + const dialogContent = this.nameRequestErrorText(nr) await this.showConfirmDialog( this.$refs.confirm, 'Name Request Type Does Not Match Business Type', @@ -215,6 +215,11 @@ export default class CorrectNameRequest extends Mixins(CommonMixin, NameRequestM ) } else { this.parseNameRequest(nr) + // Set our entity type, if it's a conversion request + if (nr.request_action_cd === NrRequestActionCodes.CONVERSION) { + this.setEntityType(nr.legalType) + this.setEntityTypeChangedByName(true) + } this.emitIsSaved(true) } } catch { @@ -225,11 +230,39 @@ export default class CorrectNameRequest extends Mixins(CommonMixin, NameRequestM } } + /* Checks name request type or if it's an invalid conversion name request. */ + isNameRequestInvalid (nr: NrResponseIF): boolean { + const isNameEntityTypeDifferent = this.getEntityType !== nr.legalType + const entityTypeOptions = this.getResource?.changeData?.entityTypeOptions + const isValidConversionNameRequest = nr.request_action_cd === NrRequestActionCodes.CONVERSION && + entityTypeOptions?.some(options => options.value === nr.legalType) + return (isNameEntityTypeDifferent && !isValidConversionNameRequest) + } + + /* Generate content of error depending on name request type. */ + nameRequestErrorText (nr: NrResponseIF): string { + const isConversionOrAlterationNameRequest = nr.request_action_cd === NrRequestActionCodes.CONVERSION + let dialogContent = '' + if (isConversionOrAlterationNameRequest) { + dialogContent = `

This alteration name request from ` + + `${GetCorpFullDescription(nr.entity_type_cd)} to ${GetCorpFullDescription(nr.legalType)} ` + + `does not match the current business type ` + + `${GetCorpFullDescription(this.getEntityType)}.\n\n` + + `The Name Request type must match the business type before you can continue.

` + } else { + dialogContent = `

This ${GetCorpFullDescription(nr.entity_type_cd)} ` + + `Name Request does not match the current business type ` + + `${GetCorpFullDescription(this.getEntityType)}.\n\n` + + `The Name Request type must match the business type before you can continue.

` + } + return dialogContent + } + /** * Parse and Set the Name Request date to Store. * @param nr The name request data */ - private parseNameRequest (nr: NrResponseIF): void { + parseNameRequest (nr: NrResponseIF): void { const nrCorrection: NrCorrectionIF = { legalType: nr.legalType, nrNumber: this.nameRequestNumber, @@ -251,7 +284,7 @@ export default class CorrectNameRequest extends Mixins(CommonMixin, NameRequestM /** Inform parent the process is complete. */ @Emit('isSaved') - private emitIsSaved (isSaved = false): boolean { + emitIsSaved (isSaved = false): boolean { if (!isSaved) this.$refs.correctNrForm.resetValidation() return isSaved } @@ -262,7 +295,7 @@ export default class CorrectNameRequest extends Mixins(CommonMixin, NameRequestM @Watch('applicantPhone') @Watch('applicantEmail') @Emit('isValid') - private emitValid (): boolean { + emitValid (): boolean { return this.isFormValid } } diff --git a/src/components/common/YourCompany/EntityName.vue b/src/components/common/YourCompany/EntityName.vue index 412afedd..5b17ac19 100644 --- a/src/components/common/YourCompany/EntityName.vue +++ b/src/components/common/YourCompany/EntityName.vue @@ -286,12 +286,15 @@ export default class EntityName extends Mixins(NameRequestMixin) { @Getter(useStore) isNumberedCompany!: boolean @Getter(useStore) isSpecialResolutionFiling!: boolean @Getter(useStore) isNameChangedByType!: boolean + @Getter(useStore) isEntityTypeChangedByName!: boolean // store actions @Action(useStore) setBusinessInformation!: ActionBindingIF @Action(useStore) setEditingCompanyName!: ActionBindingIF @Action(useStore) setNameRequest!: ActionBindingIF @Action(useStore) setValidComponent!: ActionBindingIF + @Action(useStore) setEntityType!: ActionBindingIF + @Action(useStore) setEntityTypeChangedByName!: ActionBindingIF // Returns true if the undo button should be displayed. This is the case when the company name has changed, // or the business name has changed during an alteration, firm change, or special resolution filing, @@ -404,6 +407,11 @@ export default class EntityName extends Mixins(NameRequestMixin) { nrNumber: this.getEntitySnapshot.businessInfo.nrNumber }) + if (this.isEntityTypeChangedByName) { + this.setEntityType(this.getEntitySnapshot.businessInfo.legalType) + this.setEntityTypeChangedByName(false) + } + // reset flag this.hasCompanyNameChanged = false } diff --git a/src/interfaces/store-interfaces/state-interfaces/tombstone-interface.ts b/src/interfaces/store-interfaces/state-interfaces/tombstone-interface.ts index 7cb370bd..567c7d20 100644 --- a/src/interfaces/store-interfaces/state-interfaces/tombstone-interface.ts +++ b/src/interfaces/store-interfaces/state-interfaces/tombstone-interface.ts @@ -21,4 +21,5 @@ export interface TombStoneIF { transactionalFolioNumber: string userEmail?: string nameChangedByType: boolean + entityTypeChangedByName: boolean } diff --git a/src/store/state/state-model.ts b/src/store/state/state-model.ts index 4db66baa..ed79aff9 100644 --- a/src/store/state/state-model.ts +++ b/src/store/state/state-model.ts @@ -22,7 +22,8 @@ export const stateModel: StateModelIF = { haveUnsavedChanges: false, folioNumber: '', transactionalFolioNumber: '', - nameChangedByType: false + nameChangedByType: false, + entityTypeChangedByName: false }, completingParty: null, newAlteration: { diff --git a/src/store/store.ts b/src/store/store.ts index 6709890a..b3f0d14f 100644 --- a/src/store/store.ts +++ b/src/store/store.ts @@ -827,6 +827,11 @@ export const useStore = defineStore('store', { return this.stateModel.tombstone.nameChangedByType }, + /** Whether business type has changed by name change. */ + isEntityTypeChangedByName (): boolean { + return this.stateModel.tombstone.entityTypeChangedByName + }, + /** Whether business type has changed. */ hasBusinessTypeChanged (): boolean { const currentEntityType = this.getEntityType @@ -1298,6 +1303,9 @@ export const useStore = defineStore('store', { setEntityType (entityType: CorpTypeCd) { this.stateModel.tombstone.entityType = entityType }, + setEntityTypeChangedByName (entityTypeChangedByName: boolean) { + this.stateModel.tombstone.entityTypeChangedByName = entityTypeChangedByName + }, setBusinessId (businessId) { this.stateModel.tombstone.businessId = businessId }, diff --git a/tests/unit/ChangeBusinessType.spec.ts b/tests/unit/ChangeBusinessType.spec.ts index 24944cd1..ff21c2ec 100644 --- a/tests/unit/ChangeBusinessType.spec.ts +++ b/tests/unit/ChangeBusinessType.spec.ts @@ -4,7 +4,8 @@ import { mount } from '@vue/test-utils' import ChangeBusinessType from '@/components/common/YourCompany/ChangeBusinessType.vue' import { createPinia, setActivePinia } from 'pinia' import { useStore } from '@/store/store' -import { CorpTypeCd, FilingTypes } from '@/enums' +import { CorpTypeCd, FilingTypes, RoleTypes } from '@/enums' +import { EntitySnapshotIF, OrgPersonIF } from '@/interfaces' const vuetify = new Vuetify({}) @@ -97,4 +98,126 @@ describe('Change Business Type component', () => { wrapper.destroy() }) + + it('should have actions hidden when entityTypeChangedByName is enabled', () => { + store.stateModel.tombstone.entityTypeChangedByName = true + store.stateModel.tombstone.filingType = FilingTypes.ALTERATION + + const wrapper = mount(ChangeBusinessType, { vuetify }) + + expect(wrapper.find('.actions').exists()).toBe(false) + }) + + it('should update name if numbered and switching between certain types', async () => { + store.stateModel.entitySnapshot = { + businessInfo: { + legalType: CorpTypeCd.BC_COMPANY, + legalName: '1234567 LTD.' + } + } as EntitySnapshotIF + store.stateModel.nameRequest.legalName = '1234567 LTD.' + store.stateModel.tombstone.entityType = CorpTypeCd.BC_ULC_COMPANY + const wrapper: any = mount(ChangeBusinessType, { vuetify }) + wrapper.vm.selectedEntityType = CorpTypeCd.BC_ULC_COMPANY + wrapper.vm.submitTypeChange() + + expect(store.stateModel.nameRequest.legalName).toBe('1234567 UNLIMITED LIABILITY COMPANY') + + store.stateModel.entitySnapshot.businessInfo.legalType = CorpTypeCd.BC_COMPANY + store.stateModel.entitySnapshot.businessInfo.legalName = '1234567 LTD.' + store.stateModel.nameRequest.legalName = '1234567 LTD.' + store.stateModel.tombstone.entityType = CorpTypeCd.BC_CCC + wrapper.vm.selectedEntityType = CorpTypeCd.BC_CCC + wrapper.vm.submitTypeChange() + + expect(store.stateModel.nameRequest.legalName).toBe('1234567 COMMUNITY CONTRIBUTION COMPANY') + + store.stateModel.entitySnapshot.businessInfo.legalType = CorpTypeCd.BC_ULC_COMPANY + store.stateModel.entitySnapshot.businessInfo.legalName = '1234567 COMMUNITY CONTRIBUTION COMPANY' + store.stateModel.nameRequest.legalName = '1234567 COMMUNITY CONTRIBUTION COMPANY' + wrapper.vm.selectedEntityType = CorpTypeCd.BC_COMPANY + wrapper.vm.submitTypeChange() + + expect(store.stateModel.nameRequest.legalName).toBe('1234567 LTD.') + + store.stateModel.entitySnapshot.businessInfo.legalType = CorpTypeCd.BC_ULC_COMPANY + store.stateModel.entitySnapshot.businessInfo.legalName = '1234567 UNLIMITED LIABILITY COMPANY' + store.stateModel.nameRequest.legalName = '1234567 UNLIMITED LIABILITY COMPANY' + wrapper.vm.selectedEntityType = CorpTypeCd.BENEFIT_COMPANY + wrapper.vm.submitTypeChange() + + expect(store.stateModel.nameRequest.legalName).toBe('1234567 LTD.') + }) + + it('should have name request required error for business type change', async () => { + store.stateModel.tombstone.filingType = FilingTypes.ALTERATION + store.stateModel.entitySnapshot = { + businessInfo: { + legalName: 'HELLO LTD.' + } + } as EntitySnapshotIF + store.stateModel.tombstone.entityType = CorpTypeCd.BC_CCC + + const wrapper: any = mount(ChangeBusinessType, { vuetify }) + wrapper.vm.isEditingType = true + await Vue.nextTick() + + expect(wrapper.find('#name-request-required-error').exists()).toBe(true) + + store.stateModel.tombstone.entityType = CorpTypeCd.BC_ULC_COMPANY + await Vue.nextTick() + + expect(wrapper.find('#name-request-required-error').exists()).toBe(true) + + store.stateModel.tombstone.entityType = CorpTypeCd.BC_COMPANY + store.stateModel.entitySnapshot = { + businessInfo: { + legalType: CorpTypeCd.BC_ULC_COMPANY + } + } as EntitySnapshotIF + await Vue.nextTick() + + expect(wrapper.find('#name-request-required-error').exists()).toBe(true) + }) + + it('should show error for less than 2 directors for CCC test', async () => { + store.stateModel.tombstone.entityType = CorpTypeCd.BC_CCC + store.stateModel.tombstone.filingType = FilingTypes.ALTERATION + store.stateModel.peopleAndRoles.orgPeople = [ + { + roles: [ + { roleType: RoleTypes.DIRECTOR } + ] + } + ] as OrgPersonIF[] + + const wrapper = mount(ChangeBusinessType, { vuetify }) + wrapper.setData({ isEditingType: true }) + + await Vue.nextTick() + + expect(wrapper.find('#minimum-three-director-error').exists()).toBe(true) + + store.stateModel.peopleAndRoles.orgPeople = [ + { + roles: [ + { roleType: RoleTypes.DIRECTOR } + ] + }, + { + roles: [ + { roleType: RoleTypes.DIRECTOR } + ] + }, + { + roles: [ + { roleType: RoleTypes.DIRECTOR } + ] + } + ] as OrgPersonIF[] + + await Vue.nextTick() + + expect(wrapper.find('#minimum-three-director-error').exists()).toBe(false) + }) })