-
Notifications
You must be signed in to change notification settings - Fork 52
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
19209 Pre-populate TING business + error handling #609
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
<template> | ||
<v-dialog | ||
v-model="dialog" | ||
width="45rem" | ||
persistent | ||
:attach="attach" | ||
content-class="technical-error-dialog" | ||
> | ||
<v-card> | ||
<v-card-title>Error</v-card-title> | ||
|
||
<v-card-text> | ||
<p class="font-15"> | ||
We could not process your action due to a technical issue. Try again in a few minutes. | ||
</p> | ||
|
||
<template v-if="!isRoleStaff"> | ||
<p class="font-15"> | ||
If this error persists, please contact BC Registries staff: | ||
</p> | ||
<ContactInfo class="mt-5" /> | ||
</template> | ||
</v-card-text> | ||
|
||
<v-divider class="my-0" /> | ||
|
||
<v-card-actions> | ||
<v-spacer /> | ||
<v-btn | ||
id="dialog-close-button" | ||
color="primary" | ||
text | ||
@click="close()" | ||
> | ||
Close | ||
</v-btn> | ||
</v-card-actions> | ||
</v-card> | ||
</v-dialog> | ||
</template> | ||
|
||
<script lang="ts"> | ||
import { Component, Prop, Emit, Vue } from 'vue-property-decorator' | ||
import { Getter } from 'pinia-class' | ||
import { ContactInfo } from '@/components/common' | ||
import { useRootStore } from '@/stores' | ||
|
||
@Component({ | ||
components: { ContactInfo } | ||
}) | ||
export default class TechnicalErrorDialog extends Vue { | ||
// Getter to check if logged in user is Staff. | ||
@Getter(useRootStore) isRoleStaff!: boolean | ||
|
||
/** Prop to display the dialog. */ | ||
@Prop({ default: false }) readonly dialog!: boolean | ||
|
||
/** Prop to provide attachment selector. */ | ||
@Prop({ default: '' }) readonly attach!: string | ||
|
||
// Pass click event to parent. | ||
@Emit() close () {} | ||
} | ||
</script> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
export enum AmlRoles { | ||
AMALGAMATING = 'amalgamating', | ||
HOLDING = 'holding' | ||
} | ||
|
||
export enum AmlTypes { | ||
LEAR = 'lear', | ||
FOREIGN = 'foreign' | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -155,6 +155,7 @@ export default class LegalServices { | |
if (isDraft) { | ||
url += '?draft=true' | ||
} | ||
|
||
return axios.post(url, { filing }) | ||
.then(response => { | ||
const filing = response?.data?.filing | ||
|
@@ -168,13 +169,23 @@ export default class LegalServices { | |
} | ||
|
||
/** | ||
* Creates (posts) a draft (temporary) business record. | ||
* Must be logged in to use this. | ||
* Throws an exception on error. | ||
* Creates (posts) a draft business record, which is used to bootstrap a new business. | ||
* @param businessRequest the object body of the request | ||
* @returns the filing object associated with the temporary business | ||
*/ | ||
static async createBusiness (businessRequest: any): Promise<any> { | ||
static async createDraftBusiness (businessRequest: any): Promise<any> { | ||
const url = `businesses?draft=true` | ||
|
||
return axios.post(url, businessRequest) | ||
.then(response => { | ||
const filing = response?.data?.filing | ||
if (!filing) { | ||
// eslint-disable-next-line no-console | ||
console.log('createDraftBusiness() error - invalid response =', response) | ||
throw new Error('Invalid filing') | ||
} | ||
return filing | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This does 2 things:
|
||
}) | ||
} | ||
|
||
/** | ||
|
@@ -190,6 +201,7 @@ export default class LegalServices { | |
if (isDraft) { | ||
url += '?draft=true' | ||
} | ||
|
||
return axios.put(url, { filing }) | ||
.then(response => { | ||
const filing = response?.data?.filing | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,11 @@ | ||
<template> | ||
<div id="amalgamation-selection"> | ||
<TechnicalErrorDialog | ||
:dialog="showErrorDialog" | ||
attach="#amalgamation-selection" | ||
@close="showErrorDialog = false" | ||
/> | ||
|
||
<!-- Main Body --> | ||
<v-container class="view-container"> | ||
<v-row> | ||
|
@@ -145,22 +151,29 @@ import { Action, Getter } from 'pinia-class' | |
import { Component, Vue } from 'vue-property-decorator' | ||
import { CorpTypeCd } from '@bcrs-shared-components/corp-type-module' | ||
import { AmalgamationTypes, FilingTypes } from '@bcrs-shared-components/enums' | ||
import { Routes } from '@/enums' | ||
import { AmlRoles, AmlTypes, Routes } from '@/enums' | ||
import { LegalServices } from '@/services' | ||
import { navigate } from '@/utils' | ||
import { TechnicalErrorDialog } from '@/components/dialogs' | ||
|
||
@Component({}) | ||
@Component({ | ||
components: { | ||
TechnicalErrorDialog | ||
} | ||
}) | ||
export default class AmalgamationSelection extends Vue { | ||
@Getter(useConfigurationStore) getCreateUrl!: string | ||
@Getter(useBusinessStore) getIdentifier!: string | ||
@Getter(useBusinessStore) getLegalType!: string | ||
@Getter(useBusinessStore) getLegalType!: CorpTypeCd | ||
@Getter(useBusinessStore) isBComp!: boolean | ||
@Getter(useBusinessStore) isBcCompany!: boolean | ||
@Getter(useBusinessStore) isCcc!: boolean | ||
@Getter(useBusinessStore) isUlc!: boolean | ||
|
||
@Action(useRootStore) setStartingAmalgamationSpinner!: (x: boolean) => void | ||
|
||
showErrorDialog = false | ||
|
||
/** Called when component is created. */ | ||
created (): void { | ||
const filingId = +this.$route.params.filingId // id param of this selection panel route, must be 0 | ||
|
@@ -171,63 +184,77 @@ export default class AmalgamationSelection extends Vue { | |
} | ||
} | ||
|
||
/** Get the amalmagated company result name depending on the type. */ | ||
/** The amalmagated company result name depending on the type. */ | ||
getRegularAmalgamationText (): string { | ||
if (this.isBComp || this.isBcCompany) return 'BC limited company' | ||
if (this.isCcc) return 'BC community contribution company' | ||
if (this.isUlc) return 'BC unlimited liability company' | ||
return 'Unknown' | ||
} | ||
|
||
/** Start Regular Long-form button pressed. */ | ||
/** Called when Start Regular Long-form button is clicked. */ | ||
async startRegularAmalgamation (): Promise<any> { | ||
const legalType = this.getLegalType as CorpTypeCd | ||
|
||
// Create a draft amalgamation and redirect to Create UI | ||
// Create a draft amalgamation application then redirect to Create UI. | ||
try { | ||
// show spinner since this is a network call | ||
this.setStartingAmalgamationSpinner(true) | ||
const accountId = +JSON.parse(sessionStorage.getItem('CURRENT_ACCOUNT'))?.id || 0 | ||
const businessId = await this.createBusinessAA(accountId, legalType, AmalgamationTypes.REGULAR) | ||
const businessId = await this.createBusinessAA(AmalgamationTypes.REGULAR) | ||
const amalgamationUrl = `${this.getCreateUrl}?id=${businessId}` | ||
navigate(amalgamationUrl) | ||
return | ||
} catch (error) { | ||
console.log('Error: unable to amalgamate now =', error) | ||
this.setStartingAmalgamationSpinner(false) | ||
throw new Error('Unable to Amalgamate Now ' + error) | ||
this.showErrorDialog = true | ||
} | ||
} | ||
|
||
/** | ||
* Create a draft amalgamation application based on selected business type. | ||
* @param accountId Account ID of logged in user. | ||
* @param legalType The legal type of the amalgamated business | ||
* Creates a draft amalgamation application. | ||
* @param type the type of amalgamation to create | ||
* @returns the business identifier of the newly created amalgamation application | ||
*/ | ||
async createBusinessAA (accountId: number, legalType: CorpTypeCd, type: AmalgamationTypes): Promise<string> { | ||
const businessRequest = { | ||
private async createBusinessAA (type: AmalgamationTypes): Promise<string> { | ||
const accountId = +JSON.parse(sessionStorage.getItem('CURRENT_ACCOUNT'))?.id || 0 | ||
const legalType = this.getLegalType | ||
|
||
const draftAmalgamationApplication = { | ||
filing: { | ||
header: { | ||
name: FilingTypes.AMALGAMATION_APPLICATION, | ||
accountId: accountId | ||
accountId | ||
}, | ||
business: { | ||
legalType: legalType | ||
legalType | ||
}, | ||
amalgamationApplication: { | ||
nameRequest: { | ||
legalType: legalType | ||
legalType | ||
}, | ||
type: type | ||
type | ||
} | ||
} | ||
} as any | ||
|
||
const createBusinessResponse = | ||
await LegalServices.createBusiness(businessRequest).catch(error => { | ||
throw new Error('Unable to create new Amalgamation Draft ' + error) | ||
}) | ||
// if this is a regular amalgamation, pre-populate the current business as a TING | ||
if (type === AmalgamationTypes.REGULAR) { | ||
draftAmalgamationApplication.filing.amalgamationApplication.amalgamatingBusinesses = [ | ||
{ | ||
type: AmlTypes.LEAR, | ||
role: AmlRoles.AMALGAMATING, | ||
identifier: this.getIdentifier | ||
} | ||
] | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should be able to extend this for short-form amalgamations to add the holding/primary company. |
||
|
||
// create the draft business record | ||
// (throws an exception on error, which startRegularAmalgamation() will handle) | ||
const filing = await LegalServices.createDraftBusiness(draftAmalgamationApplication) | ||
|
||
return createBusinessResponse.data?.filing?.business?.identifier as string | ||
// validate and return the identifier | ||
const identifier = filing?.business?.identifier as string | ||
if (!identifier) throw new Error('Invalid business identifier') | ||
return identifier | ||
} | ||
} | ||
</script> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import Vue from 'vue' | ||
import Vuetify from 'vuetify' | ||
import { mount } from '@vue/test-utils' | ||
import { createPinia, setActivePinia } from 'pinia' | ||
import { useRootStore } from '@/stores' | ||
import TechnicalErrorDialog from '@/components/dialogs/TechnicalErrorDialog.vue' | ||
import { ContactInfo } from '@/components/common' | ||
|
||
Vue.use(Vuetify) | ||
|
||
const vuetify = new Vuetify({}) | ||
setActivePinia(createPinia()) | ||
const rootStore = useRootStore() | ||
|
||
describe('TechnicalErrorDialog', () => { | ||
it('displays everything for normal users', () => { | ||
// init store | ||
rootStore.keycloakRoles = [''] | ||
|
||
const wrapper = mount(TechnicalErrorDialog, { propsData: { dialog: true }, vuetify }) | ||
|
||
expect(wrapper.find('.v-card__title').text()).toBe('Error') | ||
expect(wrapper.find('.v-card__text').text()) | ||
.toContain('We could not process your action due to a technical issue.') | ||
expect(wrapper.find('.v-card__text').text()) | ||
.toContain('If this error persists, please contact BC Registries staff:') | ||
expect(wrapper.findComponent(ContactInfo).exists()).toBe(true) | ||
expect(wrapper.find('.v-card__actions').text()).toBe('Close') | ||
|
||
wrapper.destroy() | ||
}) | ||
|
||
it('does not display contact info for staff users', () => { | ||
// init store | ||
rootStore.keycloakRoles = ['staff'] | ||
|
||
const wrapper = mount(TechnicalErrorDialog, { propsData: { dialog: true }, vuetify }) | ||
|
||
expect(wrapper.findComponent(ContactInfo).exists()).toBe(false) | ||
|
||
wrapper.destroy() | ||
}) | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As per store function.