Skip to content

Commit

Permalink
Updates to Residential Exemption with Lien (#1621)
Browse files Browse the repository at this point in the history
* Add Lien Msg for Res Exemptions
* Refactor and add LienAlert component for Transfers and Exemptions
  • Loading branch information
dimak1 authored Nov 20, 2023
1 parent bc59834 commit 41c5051
Show file tree
Hide file tree
Showing 15 changed files with 286 additions and 65 deletions.
4 changes: 4 additions & 0 deletions ppr-ui/src/assets/styles/theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ $BCgovAGold2: #fff8ef;
$BCgovAGold3: #ffe0bc;
$BCgovAGold4: #ffd4a2;

// Warning Colors
$warning: #FCBA19;
$backgroundWarning: #FFF7E3;

// Error Colors
$BCgovInputError: #ff5252;
$error: #D3272C;
Expand Down
140 changes: 140 additions & 0 deletions ppr-ui/src/components/common/LienAlert.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
<template>
<!-- Lien Information -->
<v-row id="lien-information" no-gutters class="pt-10">
<v-card
id="important-message"
class="rounded-0 px-8 py-5"
:class="lienInfo.class"
outlined
>
<v-icon v-if="lienInfo.class === 'error'" color="error" class="float-left mr-2 mt-n1">
mdi-alert
</v-icon>
<p :class="lienInfo.class === 'warning' ? 'mb-0' : 'mb-0 pl-8'">
<strong>Important:</strong> {{ lienInfo.msg }}
</p>
</v-card>

<v-col class="mt-5">
<v-btn
outlined
color="primary"
class="mt-2 px-6"
:ripple="false"
data-test-id="lien-search-btn"
@click="quickMhrSearch(mhrNumber)"
>
<v-icon class="pr-1">mdi-magnify</v-icon>
Conduct a Combined MHR and PPR Search for MHR Number
<strong>{{ mhrNumber }}</strong>
</v-btn>
<v-divider class="mx-0 mt-10 mb-6" />
</v-col>
</v-row>
</template>

<script lang="ts">
import { useRouter } from 'vue2-helpers/vue-router'
import { useMhrInformation } from '@/composables'
import { APIMHRMapSearchTypes, APISearchTypes, RouteNames, UIMHRSearchTypes } from '@/enums'
import { useStore } from '@/store/store'
import { mhrSearch } from '@/utils'
import { storeToRefs } from 'pinia'
import {
computed,
defineComponent,
reactive,
toRefs
} from 'vue-demi'
export default defineComponent({
name: 'LienAlert',
props: {
setEndDate: { type: String }
},
emits: ['isLoading'],
setup (props, { emit }) {
const router = useRouter()
const {
setSearchedType,
setManufacturedHomeSearchResults
} = useStore()
const {
getMhrInformation
} = storeToRefs(useStore())
const {
getLienInfo
} = useMhrInformation()
const localState = reactive({
mhrNumber: getMhrInformation.value.mhrNumber,
lienInfo: computed(() => getLienInfo())
})
const quickMhrSearch = async (mhrNumber: string): Promise<void> => {
emit('isLoading', true)
// Search for current Manufactured Home Registration Number
const results = await mhrSearch({
type: APISearchTypes.MHR_NUMBER,
criteria: { value: mhrNumber },
clientReferenceId: ''
}, '')
emit('isLoading', false)
if (results) {
// Set search type to satisfy UI requirements
await setSearchedType({
searchTypeUI: UIMHRSearchTypes.MHRMHR_NUMBER,
searchTypeAPI: APIMHRMapSearchTypes.MHRMHR_NUMBER
})
// There is only 1 result for a mhr number search
// Include lien info by default
results.results[0].includeLienInfo = true
await setManufacturedHomeSearchResults(results)
await router.replace({
name: RouteNames.MHRSEARCH
})
} else {
console.error('Error: MHR_NUMBER expected, but not found.')
}
}
return {
quickMhrSearch,
...toRefs(localState)
}
}
})
</script>

<style lang="scss" scoped>
@import '@/assets/styles/theme.scss';
#important-message {
&.warning {
background-color: $backgroundWarning !important;
border-color: $warning;
}
&.error {
background-color: $backgroundError !important;
border-color: $error;
}
p {
line-height: 22px;
font-size: $px-14;
letter-spacing: 0.01rem;
color: $gray7;
}
}
</style>
1 change: 1 addition & 0 deletions ppr-ui/src/components/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ export { default as PartyReview } from './PartyReview.vue'
export { default as FormCard } from './FormCard.vue'
export { default as OrgNameLookup } from './OrgNameLookup.vue'
export { default as ReviewCard } from './ReviewCard.vue'
export { default as LienAlert } from './LienAlert.vue'
40 changes: 36 additions & 4 deletions ppr-ui/src/components/tables/common/TableRow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -400,12 +400,35 @@
<v-list-item
v-if="isExemptionEnabled && !hasChildResExemption(item) &&
![HomeLocationTypes.HOME_PARK, HomeLocationTypes.LOT].includes(item.locationType)"
@click="openExemption(UnitNoteDocTypes.RESIDENTIAL_EXEMPTION_ORDER, item)"
@click="hasLienForQS || hasLockedForQS
? null
: openExemption(UnitNoteDocTypes.RESIDENTIAL_EXEMPTION_ORDER, item)"
data-test-id="res-exemption-btn"
>
<v-list-item-subtitle>
<img alt="exemption-icon" class="ml-0 icon-small" src="@/assets/svgs/ic_exemption.svg" />
<span class="ml-1">Residential Exemption</span>
<v-tooltip
v-if="hasLienForQS || hasLockedForQS"
left
nudge-left="18"
content-class="left-tooltip pa-5"
transition="fade-transition"
>
<template v-slot:activator="{ on }">
<span v-on="on" class="disabled-text">
<img alt="exemption-icon" class="ml-0 icon-small" src="@/assets/svgs/ic_exemption.svg" />
Residential Exemption tooltip
</span>
</template>
{{ hasLienForQS
? 'There is a lien on this home preventing an exemption to be filed.'
: `There is a lock on this home preventing an exemption to be filed.
If you require further information please contact BC Registries staff.`
}}
</v-tooltip>
<span v-else>
<img alt="exemption-icon" class="ml-0 icon-small" src="@/assets/svgs/ic_exemption.svg" />
Residential Exemption
</span>
</v-list-item-subtitle>
</v-list-item>
<v-list-item
Expand Down Expand Up @@ -579,7 +602,15 @@ export default defineComponent({
enableOpenEdit: computed(() => {
return (isRoleQualifiedSupplier.value || isRoleStaffReg.value || isRoleStaff.value) &&
!isRoleStaffSbc.value && !isRoleStaffBcol.value
})
}),
hasLienForQS: computed(() =>
isRoleQualifiedSupplier.value &&
localState.item.lienRegistrationType &&
localState.item.lienRegistrationType !== APIRegistrationTypes.SECURITY_AGREEMENT
),
hasLockedForQS: computed(() =>
hasLockedState(localState.item) && isRoleQualifiedSupplier.value
)
})
const deleteDraft = (item: DraftResultIF): void => {
Expand Down Expand Up @@ -904,6 +935,7 @@ export default defineComponent({
isRenewalDisabled,
isRepairersLienAmendDisabled,
isRoleStaffReg,
isRoleQualifiedSupplier,
isExemptionEnabled,
hasChildResExemption,
hasRenewal,
Expand Down
7 changes: 5 additions & 2 deletions ppr-ui/src/composables/mhrInformation/useMhrInfoValidation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
MhrRegistrationHomeOwnerIF
} from '@/interfaces'
import { computed } from 'vue-demi'
import { useHomeOwners, useTransferOwners } from '@/composables'
import { useHomeOwners, useMhrInformation, useTransferOwners } from '@/composables'
import { ActionTypes } from '@/enums'
import { storeToRefs } from 'pinia'

Expand All @@ -21,6 +21,9 @@ export const useMhrInfoValidation = (validationState: mhrInfoValidationStateIF)
const {
isTransferDueToDeath
} = useTransferOwners()
const {
getLienInfo
} = useMhrInformation()

/** Set specified flag */
const setValidation = (propertyKey: string, isValid: boolean): void => {
Expand Down Expand Up @@ -52,7 +55,7 @@ export const useMhrInfoValidation = (validationState: mhrInfoValidationStateIF)
validationState.isValidTransferType &&
validationState.isValidTransferOwners &&
(isTransferDueToDeath.value || validationState.isTransferDetailsValid) &&
!hasLien.value
(!hasLien.value || getLienInfo().isSubmissionAllowed)
)
})

Expand Down
39 changes: 36 additions & 3 deletions ppr-ui/src/composables/mhrInformation/useMhrInformation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
} from '@/interfaces'
import { useStore } from '@/store/store'
import {
APIRegistrationTypes,
ActionTypes,
ApiHomeTenancyTypes,
ApiTransferTypes,
Expand All @@ -21,10 +22,10 @@ import {
} from '@/enums'
import { fetchMhRegistration, normalizeObject, parseAccountToSubmittingParty } from '@/utils'
import { cloneDeep } from 'lodash'
import { useHomeOwners, useTransferOwners } from '@/composables'
import { useExemptions, useHomeOwners, useTransferOwners } from '@/composables'
import { computed, reactive, toRefs } from 'vue-demi'
import { storeToRefs } from 'pinia'
import { QSLockedStateUnitNoteTypes } from '@/resources'
import { LienMessages, QSLockedStateUnitNoteTypes } from '@/resources'

export const useMhrInformation = () => {
const {
Expand Down Expand Up @@ -60,7 +61,8 @@ export const useMhrInformation = () => {
getMhrTransferHomeOwnerGroups,
getMhrTransferCurrentHomeOwnerGroups,
getMhrTransferDocumentId,
getMhrTransferType
getMhrTransferType,
getLienRegistrationType
} = storeToRefs(useStore())

const {
Expand All @@ -71,6 +73,8 @@ export const useMhrInformation = () => {
getCurrentOwnerGroupIdByOwnerId
} = useTransferOwners()

const { getActiveExemption } = useExemptions()

/** Local State for custom computed properties. **/
const localState = reactive({
isFrozenMhr: computed((): boolean => {
Expand Down Expand Up @@ -190,6 +194,34 @@ export const useMhrInformation = () => {
)]
}

// Get information about the lien to help with styling and functionality
const getLienInfo = (): { class: string, msg: string, isSubmissionAllowed: boolean } => {
const hasActiveExemption = !!getActiveExemption()
const isLienRegistrationTypeSA = getLienRegistrationType.value === APIRegistrationTypes.SECURITY_AGREEMENT

if (isRoleStaffReg.value || (isRoleQualifiedSupplier.value && isLienRegistrationTypeSA)) {
return {
class: 'warning',
msg: LienMessages.defaultWarning,
isSubmissionAllowed: true
}
} else if (isRoleQualifiedSupplier.value) {
return {
class: 'error',
msg: LienMessages.QSError,
isSubmissionAllowed: false
}
} else if (isRoleQualifiedSupplier.value &&
hasActiveExemption &&
isLienRegistrationTypeSA) {
return {
class: 'warning',
msg: LienMessages.exemptionsWarning,
isSubmissionAllowed: true
}
}
}

/** Draft Filings **/
/**
* Parse a draft MHR Information into State.
Expand Down Expand Up @@ -371,6 +403,7 @@ export const useMhrInformation = () => {
parseMhrInformation,
initDraftMhrInformation,
parseSubmittingPartyInfo,
getLienInfo,
...toRefs(localState)
}
}
1 change: 1 addition & 0 deletions ppr-ui/src/resources/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ export * from './contactInformationContent'
export * from './userAccessOrgLookup'
export * from './userAccessRequirements'
export * from './exemptions'
export * from './lienMessages'
6 changes: 6 additions & 0 deletions ppr-ui/src/resources/lienMessages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/* eslint-disable max-len */
export const LienMessages = {
defaultWarning: 'There is a lien pertaining to this home. You can view liens against the manufactured home in the Personal Property Registry by conducting a combined Manufactured Home Registry and PPR search.',
QSError: 'There is at least one lien pertaining to this manufactured home that may be preventing some changes to this home. Any liens preventing changes must be either discharged or have prescribed conditions met before making changes. If prescribed conditions have been met, changes cannot be completed online and must be registered by BC Registries staff. You can view liens against the manufactured home in the PPR by conducting a combined Manufactured Home Registry and PPR search.',
exemptionsWarning: 'There is a PPSA (Personal Property Security Act) security interest pertaining to this manufactured home. You must have consent of each Secured Party in the agreement to continue. You can view liens against the manufactured home in the Personal Property Registry by conducting a combined Manufactured Home Registry and PPR search.'
}
4 changes: 4 additions & 0 deletions ppr-ui/src/store/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,9 @@ export const useStore = defineStore('assetsStore', () => {
// Current state is to verify the property exists. Future state may be more granular dependent on type.
return !!state.value.mhrInformation.lienRegistrationType
})
const getLienRegistrationType = computed<string>(() => {
return state.value.mhrInformation.lienRegistrationType
})
const getMhrUnitNotes: ComputedRef<Array<UnitNoteIF | CancelUnitNoteIF>> =
computed<Array<UnitNoteIF | CancelUnitNoteIF>>(() => {
return state.value.mhrUnitNotes
Expand Down Expand Up @@ -1365,6 +1368,7 @@ export const useStore = defineStore('assetsStore', () => {

// Lien-related getter
hasLien,
getLienRegistrationType,

// Mhr Info Validation State
getMhrInfoValidation,
Expand Down
Loading

0 comments on commit 41c5051

Please sign in to comment.