From d014fe0651bbf22c1fbfb0505ee542f1ef246425 Mon Sep 17 00:00:00 2001 From: Dima K <dima1086@hotmail.com> Date: Mon, 13 May 2024 07:57:30 -0700 Subject: [PATCH] Cancel Transport Permit framework (#1868) * Cancel Transport Permit framework, component updates, store updates * Add Cancel Transport Permit feature flag * Update Fee Summary for Cancel Transport Permit * Add IDs to PPR Reg dropdown to help with cypress tests * Add unit tests for Cancel Transport Permit --- ppr-ui/src/assets/styles/base.scss | 4 + ppr-ui/src/assets/svgs/icon_cancel_permit.svg | 13 + .../ReviewConfirm/HomeLocationReview.vue | 68 ++++- .../RegistrationBarTypeAheadList.vue | 1 + ppr-ui/src/composables/fees/FeeSummary.vue | 3 + .../composables/fees/enums/feeSummaryTypes.ts | 1 + .../fees/factories/useFeeSummary.ts | 3 + .../mhrInformation/useMhrInformation.ts | 24 +- .../mhrInformation/useTransportPermits.ts | 19 +- ppr-ui/src/enums/transportPermits.ts | 1 + .../MhrTransportPermitIF.ts | 1 + .../registration-interfaces.ts | 1 + ppr-ui/src/store/store.ts | 21 ++ ppr-ui/src/utils/feature-flags.ts | 1 + .../views/mhrInformation/MhrInformation.vue | 50 +++- .../mhrInformation/MhrTransportPermit.vue | 264 +++++++++++------- ppr-ui/tests/unit/MhrTransportPermit.spec.ts | 39 ++- .../unit/test-data/mock-transport-permit.ts | 18 +- ppr-ui/tests/unit/utils/helper-functions.ts | 3 +- 19 files changed, 403 insertions(+), 132 deletions(-) create mode 100644 ppr-ui/src/assets/svgs/icon_cancel_permit.svg diff --git a/ppr-ui/src/assets/styles/base.scss b/ppr-ui/src/assets/styles/base.scss index 1cfd52aec..b4c32ae22 100644 --- a/ppr-ui/src/assets/styles/base.scss +++ b/ppr-ui/src/assets/styles/base.scss @@ -156,6 +156,10 @@ a { font-size: 1.0625rem; } +.fs-18 { + font-size: 18px; +} + .fs-21 { font-size: 1.3125rem; } diff --git a/ppr-ui/src/assets/svgs/icon_cancel_permit.svg b/ppr-ui/src/assets/svgs/icon_cancel_permit.svg new file mode 100644 index 000000000..a3b997152 --- /dev/null +++ b/ppr-ui/src/assets/svgs/icon_cancel_permit.svg @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<!-- Generator: Adobe Illustrator 28.5.0, SVG Export Plug-In . SVG Version: 9.03 Build 54727) --> +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + viewBox="0 0 21 22" style="enable-background:new 0 0 21 22;" xml:space="preserve"> +<style type="text/css"> + .st0{fill-rule:evenodd;clip-rule:evenodd;fill:#38598A;fill-opacity:0.98;} +</style> +<path class="st0" d="M3.1,9c0-3.9,3.1-6.5,6.6-6.5c3.4,0,6.6,2.5,6.6,6.5c0,1-0.3,2-0.9,3.2c-2.4,0-4.3,2-4.3,4.4c0,0.2,0,0.4,0,0.6 + c-0.4,0.4-0.9,0.8-1.4,1.2C5.3,14.7,3.1,11.6,3.1,9z M8,8.8c0,0.9,0.7,1.6,1.6,1.6c0.9,0,1.6-0.7,1.6-1.6s-0.7-1.6-1.6-1.6 + C8.7,7.2,8,7.9,8,8.8z"/> +<path class="st0" d="M17.1,13.9l-1.7,1.7l-1.7-1.7l-0.9,0.9l1.7,1.7l-1.7,1.7l0.9,0.9l1.7-1.7l1.7,1.7l0.9-0.9l-1.7-1.7l1.7-1.7 + L17.1,13.9z"/> +</svg> diff --git a/ppr-ui/src/components/mhrRegistration/ReviewConfirm/HomeLocationReview.vue b/ppr-ui/src/components/mhrRegistration/ReviewConfirm/HomeLocationReview.vue index 1c9f9bb1a..8da302894 100644 --- a/ppr-ui/src/components/mhrRegistration/ReviewConfirm/HomeLocationReview.vue +++ b/ppr-ui/src/components/mhrRegistration/ReviewConfirm/HomeLocationReview.vue @@ -15,11 +15,32 @@ > <label class="font-weight-bold pl-2">Location of Home</label> </header> + <div + v-if="isCancelChangeLocationActive" + class="px-8 mt-5 mb-n5" + > + <div class="d-flex align-center"> + <img + width="25" + :src="isPrevTransportPermitLocation + ? require('@/assets/svgs/homelocationicon_reviewscreen.svg') + : require('@/assets/svgs/icon_cancel_permit.svg')" + > + <label class="font-weight-bold pl-2"> + {{ isPrevTransportPermitLocation ? 'Restored Location' : 'Cancelled Location' }} + </label> + </div> + <v-divider + class="border-opacity-15 mt-4" + /> + </div> <div - :class="{ - 'border-error-left': showStepError && !isTransferReview && !isTransportPermitReview && !isMhrCorrection - }" + :class="[ + {'border-error-left': showStepError && !isTransferReview && !isTransportPermitReview && !isMhrCorrection}, + {'cancelled-location-info': isCancelChangeLocationActive && !isPrevTransportPermitLocation}, + {'restored-location-info': isCancelChangeLocationActive && isPrevTransportPermitLocation} + ]" > <section v-if="showStepError && !isTransferReview && !isTransportPermitReview && !isMhrCorrection" @@ -34,16 +55,31 @@ ><span>Return to this step to complete it.</span></router-link> </span> </section> - <section v-if="(!!homeLocationInfo.locationType || hasAddress || isOwnLand !== null)" id="review-home-location-section" class="pt-5 pb-9" > + <v-row + v-if="isCancelChangeLocationActive && isPrevTransportPermitLocation" + noGutters + class="px-8 my-5" + > + <v-col> + <p> + This is the location of the home prior to the transport permit being issued and will be the + registered location of the home. + </p> + </v-col> + </v-row> + <!-- Transport permit details rendered when there is an active permit --> <!-- add top margin to compensate negative bottom margin of the section tag --> <TransportPermitDetails - v-if="hasActiveTransportPermit && !isChangeLocationActive && !isCorrectionReview" + v-if="hasActiveTransportPermit && + !isChangeLocationActive && + !isCorrectionReview && + !isPrevTransportPermitLocation" class="mt-5" /> @@ -235,7 +271,7 @@ <!-- PID --> <template v-if="includesPid"> <!-- PID Entered--> - <template v-if="!getIsManualLocation"> + <template v-if="!isManualLocation"> <v-row noGutters class="px-8 pt-1" @@ -557,6 +593,10 @@ export default defineComponent({ isPadEditable: { type: Boolean, default: false + }, + isPrevTransportPermitLocation: { + type: Boolean, + default: false } }, setup (props) { @@ -574,6 +614,7 @@ export default defineComponent({ getMhrTransportPermit, getMhrOriginalTransportPermit, getMhrOriginalTransportPermitHomeLocation, + getMhrTransportPermitPreviousLocation, getMhrTransportPermitHomeLocation } = storeToRefs(useStore()) @@ -589,12 +630,14 @@ export default defineComponent({ isChangeLocationActive, isAmendLocationActive, isNotManufacturersLot, - isMovingWithinSamePark + isMovingWithinSamePark, + isCancelChangeLocationActive } = useTransportPermits() const { correctionState, isMhrCorrection } = useMhrCorrections() const homeLocationInfo: MhrRegistrationHomeLocationIF = - props.isTransportPermitReview ? getMhrTransportPermit.value.newLocation : getMhrRegistrationLocation.value + props.isPrevTransportPermitLocation ? getMhrTransportPermitPreviousLocation.value : + props.isTransportPermitReview ? getMhrTransportPermit.value.newLocation : getMhrRegistrationLocation.value const localState = reactive({ // transport permit @@ -622,6 +665,9 @@ export default defineComponent({ return [HomeLocationTypes.OTHER_STRATA, HomeLocationTypes.OTHER_TYPE] .includes(homeLocationInfo.otherType) }), + isManualLocation: computed((): boolean => { + return props.isPrevTransportPermitLocation ? !homeLocationInfo.pidNumber : getIsManualLocation.value + }), hasAddress: computed((): boolean => { return !!(homeLocationInfo.address?.street || homeLocationInfo.address?.streetAdditional || @@ -708,7 +754,6 @@ export default defineComponent({ RouteNames, MhrSectVal, getStepValidation, - getIsManualLocation, isMhrManufacturerRegistration, shortPacificDate, getMhrRegistrationLocation, @@ -717,6 +762,7 @@ export default defineComponent({ isNotManufacturersLot, isAmendLocationActive, isChangeLocationActive, + isCancelChangeLocationActive, correctionState, isMhrCorrection, ...toRefs(localState) @@ -742,4 +788,8 @@ export default defineComponent({ .error-text { font-size: 16px; } + +.cancelled-location-info { + opacity: 0.5; +} </style> diff --git a/ppr-ui/src/components/registration/RegistrationBarTypeAheadList.vue b/ppr-ui/src/components/registration/RegistrationBarTypeAheadList.vue index 96cc15139..6377f36fe 100644 --- a/ppr-ui/src/components/registration/RegistrationBarTypeAheadList.vue +++ b/ppr-ui/src/components/registration/RegistrationBarTypeAheadList.vue @@ -72,6 +72,7 @@ </template> <template v-else-if="displayGroup[item.raw.group]"> <v-list-item + :id="`reg-type-item-${item.raw.registrationTypeAPI}`" v-bind="props" class="py-3 registration-list registration-list-item" @click="selectRegistration(item.raw)" diff --git a/ppr-ui/src/composables/fees/FeeSummary.vue b/ppr-ui/src/composables/fees/FeeSummary.vue index 8fa6b37f6..432c86ebb 100644 --- a/ppr-ui/src/composables/fees/FeeSummary.vue +++ b/ppr-ui/src/composables/fees/FeeSummary.vue @@ -311,6 +311,7 @@ export default defineComponent({ [FeeSummaryTypes.MHSEARCH, FeeSummaryTypes.NEW_MHR, FeeSummaryTypes.MHR_TRANSFER, FeeSummaryTypes.MHR_UNIT_NOTE, FeeSummaryTypes.RESIDENTIAL_EXEMPTION, FeeSummaryTypes.NON_RESIDENTIAL_EXEMPTION, FeeSummaryTypes.MHR_TRANSPORT_PERMIT, + FeeSummaryTypes.MHR_TRANSPORT_PERMIT_CANCEL, FeeSummaryTypes.MHR_AMEND_TRANSPORT_PERMIT, FeeSummaryTypes.MHR_STAFF_CORRECTION, FeeSummaryTypes.MHR_CLIENT_CORRECTION, FeeSummaryTypes.MHR_PUBLIC_AMENDMENT ] @@ -448,6 +449,8 @@ export default defineComponent({ return 'Location Change' case FeeSummaryTypes.MHR_AMEND_TRANSPORT_PERMIT: return 'Amend Transport Permit' + case FeeSummaryTypes.MHR_TRANSPORT_PERMIT_CANCEL: + return 'Cancel Transport Permit' case FeeSummaryTypes.MHR_UNIT_NOTE: return UnitNotesInfo[localState.feeSubType].header case FeeSummaryTypes.RESIDENTIAL_EXEMPTION: diff --git a/ppr-ui/src/composables/fees/enums/feeSummaryTypes.ts b/ppr-ui/src/composables/fees/enums/feeSummaryTypes.ts index 9ee2885bb..e257e5b3c 100644 --- a/ppr-ui/src/composables/fees/enums/feeSummaryTypes.ts +++ b/ppr-ui/src/composables/fees/enums/feeSummaryTypes.ts @@ -11,6 +11,7 @@ export enum FeeSummaryTypes { MHR_PUBLIC_AMENDMENT = 'mhr_public_amendment', MHR_TRANSFER = 'mhr_transfer', MHR_TRANSPORT_PERMIT = 'mhr_transport_permit', + MHR_TRANSPORT_PERMIT_CANCEL = 'mhr_transport_permit_cancel', MHR_AMEND_TRANSPORT_PERMIT = 'mhr_amend_transport_permit', MHR_UNIT_NOTE = 'mhr_unit_note', RESIDENTIAL_EXEMPTION = 'residential_exemption', diff --git a/ppr-ui/src/composables/fees/factories/useFeeSummary.ts b/ppr-ui/src/composables/fees/factories/useFeeSummary.ts index 7c49e0415..4c05f9034 100644 --- a/ppr-ui/src/composables/fees/factories/useFeeSummary.ts +++ b/ppr-ui/src/composables/fees/factories/useFeeSummary.ts @@ -127,6 +127,9 @@ export function getFeeSummary ( if (feeType === FeeSummaryTypes.MHR_AMEND_TRANSPORT_PERMIT) { return { ...defaultFeeSummaries.feeDefaultNoFee } } + if (feeType === FeeSummaryTypes.MHR_TRANSPORT_PERMIT_CANCEL) { + return { ...defaultFeeSummaries.feeDefaultNoFee } + } if(feeType === FeeSummaryTypes.MHR_STAFF_CORRECTION) { return { ...defaultFeeSummaries[FeeSummaryDefaults.NO_FEE] } } diff --git a/ppr-ui/src/composables/mhrInformation/useMhrInformation.ts b/ppr-ui/src/composables/mhrInformation/useMhrInformation.ts index 96edb735f..b7e3c1550 100644 --- a/ppr-ui/src/composables/mhrInformation/useMhrInformation.ts +++ b/ppr-ui/src/composables/mhrInformation/useMhrInformation.ts @@ -57,7 +57,9 @@ export const useMhrInformation = () => { setMhrTransferAttentionReference, setMhrTransferConsideration, setMhrAccountSubmittingParty, - setMhrInformationPermitData + setMhrInformationPermitData, + setMhrTransportPermitPreviousLocation, + setTransportPermitChangeAllowed } = useStore() const { // Getters @@ -164,6 +166,12 @@ export const useMhrInformation = () => { // Set Transports Permit Data when it's present if(!!data?.permitStatus) await parseMhrPermitData(data) + // previous location of the Transport Permit (used to cancel the permit) + data?.previousLocation && parsePreviousLocation(data.previousLocation) + + // parse the flag for Transport Permit changes (eg QS can only cancel its own permits) + data?.changePermit && setTransportPermitChangeAllowed(data.changePermit) + // Parse transfer details conditionally. // Some situations call for it being pre-populated from base registration. includeDetails && parseTransferDetails(data) @@ -351,6 +359,20 @@ export const useMhrInformation = () => { setMhrTransferOwnLand(data?.ownLand || null) } + // Parse previous location of home - user for transport permit cancellation + const parsePreviousLocation = (previousLocation: MhrRegistrationHomeLocationIF): void => { + + const otherTypes = [HomeLocationTypes.OTHER_RESERVE, HomeLocationTypes.OTHER_STRATA, HomeLocationTypes.OTHER_TYPE] + + // otherType location is used in UI only + if (otherTypes.includes(previousLocation.locationType)) { + previousLocation.otherType = previousLocation.locationType + previousLocation.locationType = HomeLocationTypes.OTHER_LAND + } + + setMhrTransportPermitPreviousLocation(previousLocation); + } + /** Filing Submission Helpers **/ const parseOwnerGroups = (isDraft: boolean = false): MhrRegistrationHomeOwnerGroupIF[] => { diff --git a/ppr-ui/src/composables/mhrInformation/useTransportPermits.ts b/ppr-ui/src/composables/mhrInformation/useTransportPermits.ts index 51060cafc..b84e83395 100644 --- a/ppr-ui/src/composables/mhrInformation/useTransportPermits.ts +++ b/ppr-ui/src/composables/mhrInformation/useTransportPermits.ts @@ -17,6 +17,7 @@ import { cloneDeep, get, isEqual } from 'lodash' // Global constants const isChangeLocationActive: Ref<boolean> = ref(false) const isAmendLocationActive: Ref<boolean> = ref(false) +const isCancelChangeLocationActive: Ref<boolean> = ref(false) export const useTransportPermits = () => { const { @@ -51,12 +52,18 @@ export const useTransportPermits = () => { getFeatureFlag('mhr-transport-permit-enabled') }) - /** Returns true when staff and the feature flag is enabled **/ + /** Returns true when staff and the feature flag is enabled to amend transport **/ const isAmendChangeLocationEnabled: ComputedRef<boolean> = computed((): boolean => { return (isRoleStaffReg.value || isRoleQualifiedSupplier.value || isRoleStaffSbc.value) && getFeatureFlag('mhr-amend-transport-permit-enabled') }) + /** Returns true when staff and the feature flag is enabled to cancel transport permit**/ + const isCancelChangeLocationEnabled: ComputedRef<boolean> = computed((): boolean => { + return (isRoleStaffReg.value || isRoleQualifiedSupplier.value || isRoleStaffSbc.value) && + getFeatureFlag('mhr-cancel-transport-permit-enabled') + }) + /** Checks if Home's current location is not on Manufacturer's Lot **/ const isNotManufacturersLot: ComputedRef<boolean> = computed((): boolean => getMhrRegistrationLocation.value.locationType !== HomeLocationTypes.LOT @@ -92,6 +99,11 @@ export const useTransportPermits = () => { isAmendLocationActive.value = val } + /** Toggle Amend location change flow **/ + const setCancelLocationChange = (val: boolean) => { + isCancelChangeLocationActive.value = val + } + const setLocationChangeType = (locationChangeType: LocationChangeTypes) => { setMhrTransportPermitLocationChangeType(locationChangeType) } @@ -250,6 +262,7 @@ export const useTransportPermits = () => { const initTransportPermit = (): MhrTransportPermitIF => { isAmendLocationActive.value = false + isCancelChangeLocationActive.value = false return { documentId: '', submittingParty: { @@ -307,6 +320,7 @@ export const useTransportPermits = () => { reserveNumber: '', exceptionPlan: '' } as MhrRegistrationHomeLocationIF, + previousLocation: null, ownLand: null, registrationStatus: '' } @@ -318,8 +332,10 @@ export const useTransportPermits = () => { resetTransportPermit, isChangeLocationActive, isAmendLocationActive, + isCancelChangeLocationActive, isChangeLocationEnabled, isAmendChangeLocationEnabled, + isCancelChangeLocationEnabled, isNotManufacturersLot, isActiveHomeOutsideBc, isMovingWithinSamePark, @@ -331,6 +347,7 @@ export const useTransportPermits = () => { setLocationChange, setLocationChangeType, setAmendLocationChange, + setCancelLocationChange, getUiLocationType, getUiFeeSummaryLocationType, populateLocationInfoForSamePark, diff --git a/ppr-ui/src/enums/transportPermits.ts b/ppr-ui/src/enums/transportPermits.ts index e829dbdee..22ea85866 100644 --- a/ppr-ui/src/enums/transportPermits.ts +++ b/ppr-ui/src/enums/transportPermits.ts @@ -1,5 +1,6 @@ export enum LocationChangeTypes { TRANSPORT_PERMIT = 'TRANSPORT_PERMIT', TRANSPORT_PERMIT_SAME_PARK = 'TRANSPORT_PERMIT_SAME_PARK', + TRANSPORT_PERMIT_CANCEL = 'CANCEL_PERMIT', REGISTERED_LOCATION = 'REGISTERED_LOCATION' } diff --git a/ppr-ui/src/interfaces/mhr-registration-interfaces/MhrTransportPermitIF.ts b/ppr-ui/src/interfaces/mhr-registration-interfaces/MhrTransportPermitIF.ts index 8ebc5d313..74fd46171 100644 --- a/ppr-ui/src/interfaces/mhr-registration-interfaces/MhrTransportPermitIF.ts +++ b/ppr-ui/src/interfaces/mhr-registration-interfaces/MhrTransportPermitIF.ts @@ -8,6 +8,7 @@ export interface MhrTransportPermitIF { submittingParty: SubmittingPartyIF, locationChangeType: LocationChangeTypes, newLocation: MhrRegistrationHomeLocationIF, + previousLocation: MhrRegistrationHomeLocationIF, // used when cancelling the permits ownLand: boolean, landStatusConfirmation?: boolean, amendment?: boolean diff --git a/ppr-ui/src/interfaces/ppr-api-interfaces/registration-interfaces.ts b/ppr-ui/src/interfaces/ppr-api-interfaces/registration-interfaces.ts index af71a2941..fbd845b9f 100644 --- a/ppr-ui/src/interfaces/ppr-api-interfaces/registration-interfaces.ts +++ b/ppr-ui/src/interfaces/ppr-api-interfaces/registration-interfaces.ts @@ -172,6 +172,7 @@ export interface MhRegistrationSummaryIF { lienRegistrationType?: string frozenDocumentType?: string exemptDateTime?: string + changePermit?: boolean // used to determine if QS can cancel MHR Transport Permit permitDateTime?: string permitExpiryDateTime?: string permitRegistrationNumber?: string diff --git a/ppr-ui/src/store/store.ts b/ppr-ui/src/store/store.ts index d10987e8a..c100fcf41 100644 --- a/ppr-ui/src/store/store.ts +++ b/ppr-ui/src/store/store.ts @@ -833,11 +833,20 @@ export const useStore = defineStore('assetsStore', () => { return omit(state.value.mhrOriginalTransportPermit?.newLocation, 'address') }) + const getMhrTransportPermitPreviousLocation = computed((): MhrRegistrationHomeLocationIF => { + return state.value.mhrTransportPermit.previousLocation + }) + // get original status of the registration when working with amendments const getMhrOriginalTransportPermitRegStatus = computed((): string => { return state.value.mhrOriginalTransportPermit.registrationStatus }) + // get a flag to indicate if change to the Transport Permit are allowed + const getTransportPermitChangeAllowed = computed((): boolean => { + return state.value.mhrInformation.changePermit + }) + /** Actions **/ function resetNewRegistration () { state.value.registration.registrationNumber = null @@ -1276,6 +1285,10 @@ export const useStore = defineStore('assetsStore', () => { state.value.mhrInformation[`permit${permitKey}`] = permitData } + function setTransportPermitChangeAllowed (changePermit: boolean) { + state.value.mhrInformation.changePermit = changePermit + } + function setMhrUnitNotes (unitNotes: Array<UnitNoteIF>) { state.value.mhrUnitNotes = unitNotes } @@ -1322,6 +1335,10 @@ export const useStore = defineStore('assetsStore', () => { setUnsavedChanges(true) } + function setMhrTransportPermitPreviousLocation (prevLocation: MhrRegistrationHomeLocationIF) { + state.value.mhrTransportPermit.previousLocation = prevLocation + } + /** Original Transport Permit filing when working with Amendments */ function setMhrOriginalTransportPermit ({ key, value }) { state.value.mhrOriginalTransportPermit[key] = value @@ -1631,7 +1648,9 @@ export const useStore = defineStore('assetsStore', () => { getMhrTransportPermitHomeLocation, getMhrOriginalTransportPermit, getMhrOriginalTransportPermitHomeLocation, + getMhrTransportPermitPreviousLocation, getMhrOriginalTransportPermitRegStatus, + getTransportPermitChangeAllowed, // ACTIONS @@ -1744,7 +1763,9 @@ export const useStore = defineStore('assetsStore', () => { setMhrTransportPermitNewLocation, setMhrTransportPermitNewPad, setMhrTransportPermitNewCivicAddress, + setMhrTransportPermitPreviousLocation, setMhrOriginalTransportPermit, + setTransportPermitChangeAllowed, // MHR Unit Notes setMhrUnitNoteType, diff --git a/ppr-ui/src/utils/feature-flags.ts b/ppr-ui/src/utils/feature-flags.ts index cb322ba2e..4314e62fa 100644 --- a/ppr-ui/src/utils/feature-flags.ts +++ b/ppr-ui/src/utils/feature-flags.ts @@ -19,6 +19,7 @@ export const defaultFlagSet: LDFlagSet = { 'mhr-non-res-exemption-enabled': false, // Enables Non-Residential Exemption for Staff 'mhr-transport-permit-enabled': false, 'mhr-amend-transport-permit-enabled': false, + 'mhr-cancel-transport-permit-enabled': true, 'mhr-user-access-enabled': false, 'sentry-enable': false, // by default, no sentry logs 'banner-text': '' // by default, there is no banner text diff --git a/ppr-ui/src/views/mhrInformation/MhrInformation.vue b/ppr-ui/src/views/mhrInformation/MhrInformation.vue index aa76c916f..8baccd83d 100644 --- a/ppr-ui/src/views/mhrInformation/MhrInformation.vue +++ b/ppr-ui/src/views/mhrInformation/MhrInformation.vue @@ -367,7 +367,7 @@ :validate="validate" :disabledDueToLocation="disableRoleBaseLocationChange" @updateLocationType="validate = false" - @cancelTransportPermitChanges="handleCancelTransportPermitChanges()" + @cancelTransportPermitChanges="handleCancelTransportPermitChanges($event)" /> <HomeLocationReview v-if="showHomeLocationReview" @@ -378,6 +378,14 @@ :hideDefaultHeader="isChangeLocationEnabled" :isPadEditable="transportPermitLocationType === LocationChangeTypes.TRANSPORT_PERMIT_SAME_PARK" /> + + <HomeLocationReview + v-if="isCancelChangeLocationActive" + id="transport-permit-prev-location" + isTransferReview + isPrevTransportPermitLocation + hideDefaultHeader + /> </div> <!-- Home Owners Header --> @@ -407,9 +415,7 @@ class="pl-1" color="primary" :ripple="false" - :disabled="isFrozenMhrDueToAffidavit || isFrozenMhrDueToUnitNote || - ((hasLien && !isLienRegistrationTypeSA) && - (!isRoleStaffReg || isChangeLocationActive || disableRoleBaseTransfer))" + :disabled="isChangeOwnershipBtnDisabled" @click="toggleTypeSelector()" > <span v-if="!showTransferType"> @@ -502,7 +508,7 @@ /> <TransferDetails - v-if="hasUnsavedChanges && !isChangeLocationActive" + v-if="hasUnsavedChanges && !isChangeLocationActive && !isCancelChangeLocationActive" ref="transferDetailsComponent" class="mt-10" :disablePrefill="isFrozenMhrDueToAffidavit" @@ -515,7 +521,10 @@ id="unit-note-component" class="mt-10" :unitNotes="getMhrUnitNotes" - :disabled="!enableHomeOwnerChanges || showTransferType || isChangeLocationActive" + :disabled="!enableHomeOwnerChanges || + showTransferType || + isChangeLocationActive || + isCancelChangeLocationActive" :hasActiveExemption="hasActiveExemption" /> @@ -524,7 +533,7 @@ </section> </v-col> <v-col - v-if="showTransferType || isReviewMode || isChangeLocationActive" + v-if="showTransferType || isReviewMode || isChangeLocationActive || isCancelChangeLocationActive" class="pl-6 pt-5" cols="3" > @@ -533,13 +542,13 @@ :setShowButtons="true" :setBackBtn="showBackBtn" :setCancelBtn="'Cancel'" - :setSaveBtn="isChangeLocationActive ? '' : 'Save and Resume Later'" + :setSaveBtn="(isChangeLocationActive || isCancelChangeLocationActive) ? '' : 'Save and Resume Later'" :setSubmitBtn="reviewConfirmText" :setRightOffset="true" :setShowFeeSummary="true" :setFeeType="feeType" :setErrMsg="transferErrorMsg" - :transferType="isChangeLocationActive + :transferType="(isChangeLocationActive || isCancelChangeLocationActive) ? getUiFeeSummaryLocationType(transportPermitLocationType) : getUiTransferType()" :setIsLoading="submitBtnLoading" @@ -798,6 +807,7 @@ export default defineComponent({ isChangeLocationActive, isChangeLocationEnabled, isAmendLocationActive, + isCancelChangeLocationActive, isTransportPermitDisabled, isRegisteredLocationChange, setLocationChange, @@ -843,6 +853,17 @@ export default defineComponent({ disableRoleBaseLocationChange: false, // disabled state of location change/transport permit btn submitBtnLoading: false, hasTransactionInProgress: false, + isChangeOwnershipBtnDisabled: computed((): boolean => { + const isFrozenMhr = isFrozenMhrDueToAffidavit.value || isFrozenMhrDueToUnitNote.value + + const isTransportPermitDisabled = isChangeLocationActive.value || + isAmendLocationActive.value || isCancelChangeLocationActive.value + + const isRoleBasedTransferDisabled = !isRoleStaffReg.value || localState.disableRoleBaseTransfer + + return isFrozenMhr || isTransportPermitDisabled || + ((hasLien.value && !localState.isLienRegistrationTypeSA) && isRoleBasedTransferDisabled) + }), // Transport Permit showCancelTransportPermitDialog: false, @@ -869,6 +890,8 @@ export default defineComponent({ feeType: computed((): FeeSummaryTypes => { if (isAmendLocationActive.value && isChangeLocationActive.value) { return FeeSummaryTypes.MHR_AMEND_TRANSPORT_PERMIT + } else if (isCancelChangeLocationActive.value) { + return FeeSummaryTypes.MHR_TRANSPORT_PERMIT_CANCEL } else { return isChangeLocationActive.value ? FeeSummaryTypes.MHR_TRANSPORT_PERMIT : FeeSummaryTypes.MHR_TRANSFER } @@ -1399,8 +1422,8 @@ export default defineComponent({ localState.showTransferType = !localState.showTransferType } - const handleCancelTransportPermitChanges = () => { - if (hasUnsavedChanges.value) { + const handleCancelTransportPermitChanges = (showConfirmationDialog = true) => { + if (hasUnsavedChanges.value && showConfirmationDialog) { // show dialog localState.showCancelTransportPermitDialog = true } else { @@ -1467,7 +1490,9 @@ export default defineComponent({ }) /** Inform root level components when there is an MHR action in Progress **/ - watch(() => [localState.showTransferType, isChangeLocationActive.value], (watchedConditions) => { + watch(() => [ + localState.showTransferType, isChangeLocationActive.value, isCancelChangeLocationActive.value + ], (watchedConditions) => { context.emit('actionInProgress', watchedConditions.includes(true)) }, { immediate: true }) @@ -1538,6 +1563,7 @@ export default defineComponent({ isValidTransportPermit, isValidTransportPermitReview, isRegisteredLocationChange, + isCancelChangeLocationActive, isAmendLocationActive, getMhrTransportPermit, setMhrTransportPermit, diff --git a/ppr-ui/src/views/mhrInformation/MhrTransportPermit.vue b/ppr-ui/src/views/mhrInformation/MhrTransportPermit.vue index a64a3a21e..55b2305a9 100644 --- a/ppr-ui/src/views/mhrInformation/MhrTransportPermit.vue +++ b/ppr-ui/src/views/mhrInformation/MhrTransportPermit.vue @@ -24,7 +24,7 @@ > <!-- Active Transport Permit Actions --> <v-btn - v-if="hasActiveTransportPermit && isAmendChangeLocationEnabled" + v-if="hasActiveTransportPermit && isAmendChangeLocationEnabled && !isCancelChangeLocationActive" id="home-location-change-btn" variant="plain" class="" @@ -43,7 +43,7 @@ </v-icon> {{ isChangeLocationActive ? 'Cancel Transport Permit Amendment' : 'Amend Transport Permit' }} <!-- Segmented Menu and Dropdown Cancel Option disabled until Development --> - <template v-if="false"> + <template v-if="isCancelChangeLocationEnabled"> <v-divider v-if="!isChangeLocationActive" class="my-2 px-3" @@ -66,8 +66,14 @@ <!-- Permit actions drop down list --> <v-list> - <v-list-item> - <v-list-item-subtitle class="pa-0"> + <v-list-item + data-test-id="cancel-transport-permit-btn" + :disabled="!getTransportPermitChangeAllowed" + @click="toggleCancelTransportPermit(true)" + > + <v-list-item-subtitle + class="pa-0" + > <v-icon size="small"> mdi-delete </v-icon> @@ -79,6 +85,23 @@ </template> </v-btn> + <v-btn + v-else-if="isCancelChangeLocationActive" + variant="plain" + class="" + color="primary" + data-test-id="undo-transport-permit-cancellation-btn" + :ripple="false" + @click="toggleCancelTransportPermit(false)" + > + <v-icon + size="small" + class="mr-2" + > + mdi-undo + </v-icon> Undo Cancellation + </v-btn> + <!-- Default Transport Permit Actions --> <v-btn v-else-if="!isExemptMhr && !hasActiveTransportPermit" @@ -123,9 +146,16 @@ data-test-id="active-trans-permit" > <template v-if="hasActiveTransportPermit"> - <span class="font-weight-bold">Note</span>: A transport permit has already been issued for this home. The - transport permit location can be only amended by the qualified supplier who issued the permit or by BC - Registries staff. + <span class="font-weight-bold">Note</span>: A transport permit has been issued for this home. The transport + permit location can be only amended or cancelled by the qualified supplier who issued the permit, + Service BC Staff, or BC Registries staff. + <div + v-if="isCancelChangeLocationActive" + data-test-id="cancel-permit-info" + class="mb-4" + > + <br>Cancelling the transport permit will restore the previous registered location for this home. + </div> </template> <template v-else> Transport permits are issued by changing the location on the manufactured home. Transport permits expire 30 days @@ -158,106 +188,119 @@ <v-icon size="18">mdi-open-in-new</v-icon> </a> </p> + </template> - <!-- Help Content --> - <SimpleHelpToggle - class="mt-1" - toggleButtonTitle="Help with Transport Permits" - > - <template #content> - <h3 class="text-center mb-2"> - Help with Transport Permit - </h3> - <div class="pr-15"> - <div class="mt-5"> - <p>A manufactured home cannot be moved without a transport permit.</p> - <p class="mt-6"> - Please note the following conditions and requirements under the Manufactured Home Act and the - Manufactured Home Regulations: - </p> - <p class="mt-6"> - <ol class="ml-5"> - <li> - Unless stated below as an exception, a tax certificate is required confirming that all local taxes - have been paid. A tax certificate can be obtained from the local municipality or rural tax authority - having taxing authority over the manufactured home. Exceptions to obtaining a tax certificate - include: - </li> - <ul class="ml-4 mt-3"> - <li>moving the manufactured home to a different pad within the same park, or</li> - <li class="mt-1"> - moving the manufactured home from locations on a manufacturer or dealer’s lot. - </li> - </ul> - <li class="mt-6"> - This permit expires 30 days after the date of issue. If the manufactured home is not moved before - the transport permit expires, you must report the physical location of the manufactured home within - 3 days of expiry of the permit. - </li> - <li class="mt-2"> - If the home is permanently moved to a different location than what is specified on the transport - permit, you must report the physical location of the manufactured home within 3 days of the move. - </li> - <li class="mt-2"> - This transport permit is valid for one (1) move only. A new transport permit must be obtained for - any subsequent move of the manufactured home. - </li> - <li class="mt-2"> - Upon leaving British Columbia, a manufactured home is exempt from the Manufactured Home Act. The - home must be re-registered under the same number if it re-enters British Columbia. A manufactured - home may not be moved out of British Columbia unless an exemption is issued by the Registrar. + + <!-- Help Content --> + <SimpleHelpToggle + v-if="isChangeLocationActive || isCancelChangeLocationActive" + class="mt-1" + toggleButtonTitle="Help with Transport Permits" + > + <template #content> + <h3 class="text-center mb-2"> + Help with Transport Permit + </h3> + <div class="pr-15"> + <div class="mt-5"> + <p>A manufactured home cannot be moved without a transport permit.</p> + <p class="mt-6"> + Please note the following conditions and requirements under the Manufactured Home Act and the + Manufactured Home Regulations: + </p> + <p class="mt-6"> + <ol class="ml-5"> + <li> + Unless stated below as an exception, a tax certificate is required confirming that all local taxes + have been paid. A tax certificate can be obtained from the local municipality or rural tax authority + having taxing authority over the manufactured home. Exceptions to obtaining a tax certificate + include: + </li> + <ul class="ml-4 mt-3"> + <li>moving the manufactured home to a different pad within the same park, or</li> + <li class="mt-1"> + moving the manufactured home from locations on a manufacturer or dealer’s lot. </li> - </ol> - </p> - <p class="help-note"> - <span>Note: </span> A manufactured home may be subject to routing restrictions in accordance with the - requirements of the Ministry of Transportation and Infrastructure. You are responsible for confirming - any such restrictions and you may visit - <a - class="generic-link" - href="https://onroutebc.gov.bc.ca/#contactus" - target="_blank" - > - onRouteBC - Home (gov.bc.ca) - <v-icon - color="primary" - size="12" - >mdi-open-in-new</v-icon> - </a> - or contact the Provincial Permit Centre for details. - </p> - </div> + </ul> + <li class="mt-6"> + This permit expires 30 days after the date of issue. If the manufactured home is not moved before + the transport permit expires, you must report the physical location of the manufactured home within + 3 days of expiry of the permit. + </li> + <li class="mt-2"> + If the home is permanently moved to a different location than what is specified on the transport + permit, you must report the physical location of the manufactured home within 3 days of the move. + </li> + <li class="mt-2"> + This transport permit is valid for one (1) move only. A new transport permit must be obtained for + any subsequent move of the manufactured home. + </li> + <li class="mt-2"> + Upon leaving British Columbia, a manufactured home is exempt from the Manufactured Home Act. The + home must be re-registered under the same number if it re-enters British Columbia. A manufactured + home may not be moved out of British Columbia unless an exemption is issued by the Registrar. + </li> + </ol> + </p> + <p class="help-note"> + <span>Note: </span> A manufactured home may be subject to routing restrictions in accordance with the + requirements of the Ministry of Transportation and Infrastructure. You are responsible for confirming + any such restrictions and you may visit + <a + class="generic-link" + href="https://onroutebc.gov.bc.ca/#contactus" + target="_blank" + > + onRouteBC - Home (gov.bc.ca) + <v-icon + color="primary" + size="12" + >mdi-open-in-new</v-icon> + </a> + or contact the Provincial Permit Centre for details. + </p> </div> - </template> - </SimpleHelpToggle> + </div> + </template> + </SimpleHelpToggle> - <!-- Document ID --> - <section - v-if="isRoleStaffReg" - id="document-id-section" - class="mt-7" - > - <DocumentId - :content="{ sideLabel: 'Document ID', hintText: 'Enter the 8-digit Document ID number' }" - :documentId="state.transportPermitDocumentId" - :validate="validate" - @setStoreProperty="handleDocumentIdUpdate($event)" - @isValid="setValidation('isDocumentIdValid', $event)" - /> - </section> + <!-- Document ID --> + <section + v-if="isRoleStaffReg && (isChangeLocationActive || isCancelChangeLocationActive)" + id="document-id-section" + class="mt-7" + > + <DocumentId + :content="{ sideLabel: 'Document ID', hintText: 'Enter the 8-digit Document ID number' }" + :documentId="state.transportPermitDocumentId" + :validate="validate" + @setStoreProperty="handleDocumentIdUpdate($event)" + @isValid="setValidation('isDocumentIdValid', $event)" + /> + </section> - <!-- Location Change Type --> - <section - id="location-change-type-section" - class="mt-5" - > - <LocationChange - ref="locationChangeRef" - :validate="validate" - @updateLocationType="emit('updateLocationType')" - /> - </section> - </template> + <div + v-if="isCancelChangeLocationActive" + data-test-id="verify-location-details" + > + <div class="font-weight-bold fs-18 mt-10 mb-1"> + Verify Home Location Details + </div> + <p>Verify the location details. If the restored details are incorrect, please contact BC Registries staff.</p> + </div> + + <!-- Location Change Type --> + <section + v-if="isChangeLocationActive" + id="location-change-type-section" + class="mt-5" + > + <LocationChange + ref="locationChangeRef" + :validate="validate" + @updateLocationType="emit('updateLocationType')" + /> + </section> </div> </template> @@ -290,11 +333,13 @@ const { getMhrTransportPermit, hasLien, isRoleQualifiedSupplier, - getLienRegistrationType + getLienRegistrationType, + getTransportPermitChangeAllowed } = storeToRefs(useStore()) -const { hasActiveTransportPermit, isChangeLocationActive, isAmendLocationActive, +const { hasActiveTransportPermit, isChangeLocationActive, isAmendLocationActive, isCancelChangeLocationActive, setLocationChange, setAmendLocationChange, prefillTransportPermit, setLocationChangeType, - isActivePermitWithinSamePark, isAmendChangeLocationEnabled + isActivePermitWithinSamePark, isAmendChangeLocationEnabled, isCancelChangeLocationEnabled, + setCancelLocationChange } = useTransportPermits() const { isExemptMhr } = useMhrInformation() @@ -343,6 +388,15 @@ const handleDocumentIdUpdate = (documentId: string) => { } } +const toggleCancelTransportPermit = (val: boolean) => { + setLocationChangeType(val ? LocationChangeTypes.TRANSPORT_PERMIT_CANCEL : null) + if (val) { + setCancelLocationChange(val) + } else { + emit('cancelTransportPermitChanges', false) + } +} + </script> <style lang="scss" scoped> diff --git a/ppr-ui/tests/unit/MhrTransportPermit.spec.ts b/ppr-ui/tests/unit/MhrTransportPermit.spec.ts index 4529a96c6..9ce6d5fc5 100644 --- a/ppr-ui/tests/unit/MhrTransportPermit.spec.ts +++ b/ppr-ui/tests/unit/MhrTransportPermit.spec.ts @@ -5,7 +5,7 @@ import { mount } from '@vue/test-utils' import { createComponent, setupActiveTransportPermit, setupMockStaffUser } from './utils' import { calendarDates, shortPacificDate } from '@/utils' import { defaultFlagSet } from '@/utils/feature-flags' -import { mockTransportPermitNewLocation, mockedMhRegistration } from './test-data' +import { mockTransportPermitNewLocation, mockTransportPermitPreviousLocation, mockedMhRegistration } from './test-data' import { useStore } from '@/store/store' @@ -23,7 +23,7 @@ import { } from '@/components/common' import { PartySearch } from '@/components/parties/party' import { TaxCertificate, ConfirmCompletion } from '@/components/mhrTransfers' -import { LocationChange, LocationChangeReview } from '@/components/mhrTransportPermit' +import { LocationChange, LocationChangeReview, TransportPermitDetails } from '@/components/mhrTransportPermit' import { HomeLocationType, HomeCivicAddress, HomeLandOwnership } from '@/components/mhrRegistration' import { HomeLocationReview } from '@/components/mhrRegistration/ReviewConfirm' @@ -773,4 +773,39 @@ describe('Mhr Information Transport Permit', async () => { // transport permit store should have amendment prop expect(store.getMhrTransportPermit.amendment).toBe(true) }) + + it('should render cancel transport permit form and its components (staff)', async () => { + defaultFlagSet['mhr-cancel-transport-permit-enabled'] = true + wrapper.vm.dataLoaded = true + + await setupActiveTransportPermit() + + // set mhr registration location data for it to be prefilled in Cancelled Location section + const regLocation = store.getMhrRegistrationLocation + store.setMhrLocationAllFields({ ...regLocation, ...mockTransportPermitNewLocation }) + await nextTick() + + // expect(wrapper.findByTestId('cancel-location-change-btn').text()).toBe('Cancel Transport Permit') + wrapper.findComponent(MhrTransportPermit).vm.handleCancelTransportPermit(true) + await nextTick() + + expect(wrapper.findByTestId('undo-transport-permit-cancellation-btn').exists()).toBeTruthy() + expect(wrapper.findByTestId('cancel-permit-info').exists()).toBeTruthy() + expect(wrapper.findComponent(DocumentId).exists()).toBe(true) + expect(wrapper.findByTestId('verify-location-details').exists()).toBeTruthy() + + const permitLocationSections = wrapper.findAllComponents(HomeLocationReview) + expect(permitLocationSections.length).toBe(2) + + const cancelledLocationSection = permitLocationSections[0] + expect(cancelledLocationSection.find('label').text()).toContain('Cancelled Location') + + const restoredLocationSection = permitLocationSections[1] + expect(restoredLocationSection.find('label').text()).toContain('Restored Location') + expect(restoredLocationSection.text()).toContain(mockTransportPermitPreviousLocation.address.street) + expect(restoredLocationSection.text()).toContain(mockTransportPermitPreviousLocation.locationType) + + // transport permit details should not exist in Restored Location section + expect(restoredLocationSection.findComponent(TransportPermitDetails).exists()).toBeFalsy() + }) }) diff --git a/ppr-ui/tests/unit/test-data/mock-transport-permit.ts b/ppr-ui/tests/unit/test-data/mock-transport-permit.ts index b36b5262f..6cf10dc25 100644 --- a/ppr-ui/tests/unit/test-data/mock-transport-permit.ts +++ b/ppr-ui/tests/unit/test-data/mock-transport-permit.ts @@ -1,4 +1,4 @@ -import { HomeLocationTypes, MhApiStatusTypes } from "@/enums"; +import { HomeLocationTypes } from "@/enums"; import { MhrRegistrationHomeLocationIF } from "@/interfaces"; export const mockTransportPermitNewLocation: MhrRegistrationHomeLocationIF = { @@ -18,3 +18,19 @@ export const mockTransportPermitNewLocation: MhrRegistrationHomeLocationIF = { taxCertificate: true, taxExpiryDate: "2024-02-06T08:01:00+00:00" } + +export const mockTransportPermitPreviousLocation: MhrRegistrationHomeLocationIF = { + address: { + city: 'VICTORIA', + country: 'CA', + postalCode: 'V1V 1G1', + region: 'BC', + street: '11 SKY VIEW DR', + streetAdditional: '' + }, + leaveProvince: false, + legalDescription: 'THE NORTH WEST 1/4 OF SECTION 8', + locationType: HomeLocationTypes.OTHER_STRATA, + pidNumber: '111222333', + taxCertificate: false +} diff --git a/ppr-ui/tests/unit/utils/helper-functions.ts b/ppr-ui/tests/unit/utils/helper-functions.ts index a70c2a6ee..98050e912 100644 --- a/ppr-ui/tests/unit/utils/helper-functions.ts +++ b/ppr-ui/tests/unit/utils/helper-functions.ts @@ -4,7 +4,7 @@ import { MhApiStatusTypes, ProductCode, RouteNames } from '@/enums' import { createRouterMock, injectRouterMock, RouterMock } from 'vue-router-mock' import { routes } from '@/router' import { SessionStorageKeys } from 'sbc-common-components/src/util/constants' -import { mockTransportPermitNewLocation } from '../test-data' +import { mockTransportPermitNewLocation, mockTransportPermitPreviousLocation } from '../test-data' const store = useStore() @@ -130,4 +130,5 @@ export async function setupActiveTransportPermit (): Promise<void> { await store.setMhrTransportPermit({ key: 'landStatusConfirmation', value: true }) await store.setMhrTransportPermit({ key: 'newLocation', value: mockTransportPermitNewLocation }) await store.setMhrTransportPermit({ key: 'ownLand', value: true }) + await store.setMhrTransportPermitPreviousLocation(mockTransportPermitPreviousLocation) }