diff --git a/.env.example b/.env.example index d1f6212d..999efc07 100644 --- a/.env.example +++ b/.env.example @@ -6,7 +6,10 @@ VUE_APP_POD_NAMESPACE="local" VUE_APP_REGISTRY_URL="https://dev.bcros.ca/dashboard" VUE_APP_REGISTRY_HOME_URL="https://dev.bcregistry.gov.bc.ca/" VUE_APP_AUTH_WEB_URL="https://dev.account.bcregistry.gov.bc.ca/" +VUE_APP_BUSINESSES_URL="https://dev.account.bcregistry.gov.bc.ca/" VUE_APP_BCONLINE_URL="https://d1.bconline.gov.bc.ca/" +VUE_APP_BUSINESS_EDIT_URL="https://dev.edit.business.bcregistry.gov.bc.ca" +VUE_APP_BUSINESS_CREATE_URL="https://dev.create.business.bcregistry.gov.bc.ca" # old dashboard VUE_APP_DASHBOARD_URL="https://dev.business.bcregistry.gov.bc.ca/" @@ -19,7 +22,6 @@ VUE_APP_LEGAL_API_URL="https://legal-api-dev.apps.silver.devops.gov.bc.ca" VUE_APP_LEGAL_API_VERSION_2="/api/v2" VUE_APP_STATUS_API_URL="https://status-api-dev.apps.silver.devops.gov.bc.ca" VUE_APP_STATUS_API_VERSION="/api/v1" -VUE_APP_BUSINESS_EDIT_URL="https://dev.edit.business.bcregistry.gov.bc.ca" #vaults launchdarkly # this is here to help CI pass and as this is already public it is OK to leave it here (dev value) diff --git a/cypress/e2e/components/todos/draft.cy.ts b/cypress/e2e/components/todos/draft.cy.ts index b3e577d6..fdbb507e 100644 --- a/cypress/e2e/components/todos/draft.cy.ts +++ b/cypress/e2e/components/todos/draft.cy.ts @@ -1,3 +1,5 @@ +import { DraftFilingIncorporationApplicationNumbered } from '../../../fixtures/filings/draft/incorporation-applicaton' + context('TODOs -> Draft Filing', () => { it('Test draft filing to-do item - base case (draft with no error)', () => { cy.visitBusinessDashFor('businessInfo/ben/active.json', undefined, false, false, 'draft/changeOfRegistration.json') @@ -107,4 +109,86 @@ context('TODOs -> Draft Filing', () => { .contains('BC Registries is missing information about this business') cy.get('[data-cy="todoItemActions-conversion"]').find('button').should('not.exist') }) + + // Action: delete a draft + it('Delete Draft button is working)', () => { + cy.visitBusinessDashFor('businessInfo/ben/active.json', undefined, false, false, 'draft/changeOfRegistration.json') + + cy.get('[data-cy="popover-button"]').click() + .get('[data-cy="menu-button-0"]').click() + .get('[data-cy="bcros-dialog-confirm"]').should('exist').as('dialog') + + // click to delete the draft - when error: show error dialog and click to close + cy.intercept('DELETE', '**/businesses/*/filings/*', { statusCode: 401, body: {} }).as('deleteDraft') + .get('@dialog') + .find('[data-cy="bcros-dialog-btn"]') + .eq(0).click() + .wait('@deleteDraft') + .get('[data-cy="bcros-dialog-deleteError"]').should('exist').as('errorDialog') + .find('[data-cy="bcros-dialog-btn"]').should('exist').click() + .wait(1000) + .get('@errorDialog').should('not.exist') + + // intercept the DELETE request and reload requests + cy.intercept('DELETE', '**/api/v2/businesses/*/filings/*', { statusCode: 200, body: {} }).as('deleteDraft') + cy.intercept('GET', '**/api/v2/businesses/**/tasks*').as('getTasks') + cy.intercept('GET', '**/api/v2/businesses/**/filings*').as('getFilings') + + cy.get('[data-cy="popover-button"]').click() + .get('[data-cy="menu-button-0"]').click() + .get('[data-cy="bcros-dialog-confirm"]') + .find('[data-cy="bcros-dialog-btn"]') + .eq(0).click() + .wait('@deleteDraft') + .wait('@getTasks') + .wait('@getFilings') + }) + + // Action: resume - redirect to old dashboard + it('Resume a draft filing in the old dashboard', () => { + cy.visitBusinessDashFor('businessInfo/cp/active.json', undefined, false, false, 'draft/incompletePayment.json') + cy.fixture('todos/draft/incompletePayment.json').then((afrMockResponse) => { + const identifier = afrMockResponse.tasks[0].task.filing.business.identifier + const filingId = afrMockResponse.tasks[0].task.filing.header.filingId + const arYear = afrMockResponse.tasks[0].task.filing.header.ARFilingYear + cy.intercept('GET', '**/annual-report?**').as('getAnnualReportFiling') + cy.get('[data-cy^="todoItemActions-"]') + .click() + .wait('@getAnnualReportFiling') + .its('request.url') + .should('include', `/${identifier}/annual-report?accountid=1&filingId=${filingId}&arFilingYear=${arYear}`) + }) + }) + + // Action: resume - redirect to create ui (dev.create.business.bcregistry.gov.bc.ca) + it('Resume a draft filing in Create UI', () => { + cy.visitTempBusinessDash(DraftFilingIncorporationApplicationNumbered, false) + + const identifier = DraftFilingIncorporationApplicationNumbered.filing.business.identifier + + // https://dev.create.business.bcregistry.gov.bc.ca/amalg-reg-information?accountid=3040&id=ThU9aP7BCV + cy.intercept('GET', '**/incorporation-define-company**').as('getIncorporationApplication') + cy.get('[data-cy^="todoItemActions-"]') + .click() + .wait('@getIncorporationApplication') + .its('request.url') + .should('include', '/incorporation-define-company') + .should('include', `id=${identifier}`) + }) + + // Action: resume - redirect to edit ui (dev.edit.business.bcregistry.gov.bc.ca) + it('Resume a draft filing in Edit UI', () => { + cy.visitBusinessDashFor('businessInfo/sp/active.json', undefined, false, false, 'draft/changeOfRegistration.json') + cy.fixture('todos/draft/changeOfRegistration.json').then((afrMockResponse) => { + const identifier = afrMockResponse.tasks[0].task.filing.business.identifier + const filingId = afrMockResponse.tasks[0].task.filing.header.filingId + cy.intercept('GET', '**/change/**').as('getChangeOfRegistrationFiling') + cy.get('[data-cy^="todoItemActions-"]') + .click() + .wait('@getChangeOfRegistrationFiling') + .its('request.url') + .should('include', `/${identifier}/change/`) + .should('include', `change-id=${filingId}`) + }) + }) }) diff --git a/cypress/e2e/components/todos/pending.cy.ts b/cypress/e2e/components/todos/pending.cy.ts index 061fefce..8a588b96 100644 --- a/cypress/e2e/components/todos/pending.cy.ts +++ b/cypress/e2e/components/todos/pending.cy.ts @@ -86,4 +86,18 @@ context('TODOs -> Pending Filing', () => { .should('exist') .should('have.text', 'Change Payment Type') }) + + it('Cancel Payment button is working', () => { + cy.visitBusinessDashFor('businessInfo/ben/active.json', undefined, false, false, 'pendingPayment.json') + + cy.get('[data-cy="popover-button"]').click() + .get('[data-cy="menu-button-0"]').click() + .get('[data-cy="bcros-dialog-confirm"]').should('exist').as('dialog') + + // intercept the PATCH request and reload requests + cy.intercept('PATCH', '**/api/v2/businesses/*/filings/*', { statusCode: 200, body: {} }).as('cancelPayment') + cy.get('[data-cy="bcros-dialog-btn"]') + .eq(0).click() + .wait('@cancelPayment') + }) }) diff --git a/cypress/fixtures/todos/draft/changeOfRegistration.json b/cypress/fixtures/todos/draft/changeOfRegistration.json index 592ddb5c..5e3b19c6 100644 --- a/cypress/fixtures/todos/draft/changeOfRegistration.json +++ b/cypress/fixtures/todos/draft/changeOfRegistration.json @@ -7,13 +7,13 @@ "filing": { "business": { "foundingDate": "2023-11-28T23:55:58.822929+00:00", - "identifier": "FM1060265", + "identifier": "FM1060270", "legalName": "HRVOJE2 FEKETE2, HRVOJE FEKETE, et al", "legalType": "GP" }, "changeOfRegistration": { "business": { - "identifier": "FM1060265" + "identifier": "FM1060270" }, "contactPoint": { "email": "hrvoje.fekete+gov.bc.test1@gmail.com", @@ -185,4 +185,4 @@ } } ] -} \ No newline at end of file +} diff --git a/devops/vaults.env b/devops/vaults.env index 4f651631..4ee97671 100644 --- a/devops/vaults.env +++ b/devops/vaults.env @@ -12,6 +12,8 @@ VUE_APP_DASHBOARD_URL="op://web-url/$APP_ENV/business/DASHBOARD_URL" VUE_APP_REGISTRY_URL="op://web-url/$APP_ENV/registry/REGISTRY_URL" VUE_APP_REGISTRY_HOME_URL="op://web-url/$APP_ENV/registry/REGISTRY_HOME_URL" VUE_APP_AUTH_WEB_URL="op://web-url/$APP_ENV/auth-web/AUTH_WEB_URL" +VUE_APP_BUSINESSES_URL="op://web-url/$APP_ENV/business/BUSINESSES_URL" +VUE_APP_BUSINESS_CREATE_URL="op://web-url/$APP_ENV/business-create/BUSINESS_CREATE_URL" # vaults API VUE_APP_PAY_API_URL="op://API/$APP_ENV/pay-api/PAY_API_URL" diff --git a/nuxt.config.ts b/nuxt.config.ts index aaf6e8a6..8a254aaf 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -50,7 +50,9 @@ export default defineNuxtConfig({ addressCompleteKey: process.env.VUE_APP_ADDRESS_COMPLETE_KEY, authApiURL: `${process.env.VUE_APP_AUTH_API_URL || ''}${process.env.VUE_APP_AUTH_API_VERSION || ''}`, authWebURL: process.env.VUE_APP_AUTH_WEB_URL || '', + businessesURL: process.env.VUE_APP_BUSINESSES_URL || '', dashboardOldUrl: process.env.VUE_APP_DASHBOARD_URL || '', + createURL: process.env.VUE_APP_BUSINESS_CREATE_URL || '', kcURL: process.env.VUE_APP_KEYCLOAK_AUTH_URL || '', kcRealm: process.env.VUE_APP_KEYCLOAK_REALM || '', kcClient: process.env.VUE_APP_KEYCLOAK_CLIENTID || '', diff --git a/src/components/bcros/todo/Item.vue b/src/components/bcros/todo/Item.vue index 4ac5c354..9edef97a 100644 --- a/src/components/bcros/todo/Item.vue +++ b/src/components/bcros/todo/Item.vue @@ -4,15 +4,18 @@ import { filingTypeToName } from '~/utils/todo/task-filing/helper' const t = useNuxtApp().$i18n.t const todosStore = useBcrosTodos() -const business = useBcrosBusiness() +const { currentBusiness, currentBusinessIdentifier } = storeToRefs(useBcrosBusiness()) const { bootstrapIdentifier } = storeToRefs(useBcrosBusinessBootstrap()) +const runtimeConfig = useRuntimeConfig() +const { redirect } = useBcrosNavigate() const showConfirmDialog = ref(false) const hasDeleteError = ref(false) const hasCancelPaymentError = ref(false) const confirmDialog = ref(null) -defineEmits(['expand']) +const emit = defineEmits(['expand', 'reload']) + const prop = defineProps({ item: { type: Object as PropType, required: true }, expanded: { type: Boolean, required: true } @@ -77,7 +80,7 @@ const handleClick = (button: ActionButtonI) => { } if (button.openDialog) { - const businessId = business.currentBusinessIdentifier + const businessId = currentBusinessIdentifier.value if (prop.item.status === FilingStatusE.DRAFT) { // open the dialog for confirming deleting a draft filing (for existing businesses) @@ -107,31 +110,68 @@ const useErrorStyle = (item: TodoItemI): boolean => { } /** Delete a draft; if refreshDashboard is set to true, refresh the page to reload data */ -const deleteDraft = async (_refreshDashboard = true): Promise => { - /* eslint-disable no-console */ - console.log('Delete a draft') - - // TO-DO: implement this function in ticket #22638; delete draft and handle errors - await Promise.resolve() +const deleteDraft = async (refreshDashboard = true): Promise => { + const id = currentBusinessIdentifier.value || bootstrapIdentifier.value + const url = `${runtimeConfig.public.legalApiURL}/businesses/${id}/filings/${prop.item.filingId}` + + await useBcrosFetch(url, { method: 'DELETE' }).then(({ error }) => { + showConfirmDialog.value = false + if (error.value) { + console.error('Error deleting a draft: ', error.value) + hasDeleteError.value = true + if (error.value.data.errors) { deleteErrors.value = error.value.data.errors } + if (error.value.data.warnings) { deleteWarnings.value = error.value.data.warnings } + } else if (refreshDashboard) { + emit('reload') + } + }) } +/** Delete an application draft and redirect */ const deleteApplication = async (): Promise => { - await deleteDraft(false) - - /* eslint-disable no-console */ - console.log('Redirecting after deleting an application') - // TO-DO: implement this function in ticket #22638 - // go to My Business Registry page if it is a name request - // otherwise go to BCROS home page + await deleteDraft(false).then(() => { + // do not redirect if there is an error, + // this logic does not exist in the old codebase. + if (hasDeleteError.value) { return } + + // N.B.: in '.env.example', authWebURL and businessesURL are the same + if (prop.item.nameRequest) { + // go to My Business Registry page + redirect(runtimeConfig.public.authWebURL) + } else { + // go to BCROS home page + redirect(runtimeConfig.public.businessesURL) + } + }) } /** Cancel the payment and set the filing status to draft; reload the page; handle errors if exist */ const cancelPaymentAndSetToDraft = async (_refreshDashboard = true): Promise => { - /* eslint-disable no-console */ - console.log('Cancel the payment and set the filing status to draft') + const url = + `${runtimeConfig.public.legalApiURL}/businesses/${currentBusinessIdentifier.value}/filings/${prop.item.filingId}` + + await useBcrosFetch(url, { method: 'PATCH' }).then(({ error }) => { + showConfirmDialog.value = false + if (error.value) { + console.error('Error cancelling a payment: ', error.value) + hasCancelPaymentError.value = true + } else { + emit('reload') + } + }) +} + +/** Clear the error flag, errors and warning array for deleting a draft */ +const clearDeleteErrors = (): void => { + hasDeleteError.value = false + deleteErrors.value = [] + deleteWarnings.value = [] +} - // TO-DO: implement this function in ticket #22638; delete draft and handle errors - await Promise.resolve() +/** Clear the error flag and errors array for cancelling a payment */ +const clearCancelPaymentErrors = (): void => { + hasCancelPaymentError.value = false + cancelPaymentErrors.value = [] } @@ -151,14 +191,14 @@ const cancelPaymentAndSetToDraft = async (_refreshDashboard = true): Promise
diff --git a/src/components/bcros/todo/List.vue b/src/components/bcros/todo/List.vue index 9f829bee..34bbc7e2 100644 --- a/src/components/bcros/todo/List.vue +++ b/src/components/bcros/todo/List.vue @@ -1,6 +1,8 @@