Skip to content

Commit

Permalink
Examiner - UI: Host details expansion (bcgov#457)
Browse files Browse the repository at this point in the history
* add host utils, types and enums to base web

* initial expansion

* bump version

* fix
  • Loading branch information
deetz99 authored Jan 15, 2025
1 parent e40d05f commit e1c43b2
Show file tree
Hide file tree
Showing 34 changed files with 689 additions and 244 deletions.
16 changes: 16 additions & 0 deletions strr-base-web/app/enums/document-upload-type.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
export enum DocumentUploadType {
BC_DRIVERS_LICENSE = 'BC_DRIVERS_LICENSE',
BCSC = 'BCSC',
COMBINED_BCSC_LICENSE = 'COMBINED_BCSC_LICENSE',
PROPERTY_ASSESSMENT_NOTICE = 'PROPERTY_ASSESSMENT_NOTICE',
SPEC_TAX_CONFIRMATION = 'SPEC_TAX_CONFIRMATION',
HOG_DECLARATION = 'HOG_DECLARATION',
ICBC_CERTIFICATE_OF_INSURANCE = 'ICBC_CERTIFICATE_OF_INSURANCE',
HOME_INSURANCE_SUMMARY = 'HOME_INSURANCE_SUMMARY',
PROPERTY_TAX_NOTICE = 'PROPERTY_TAX_NOTICE',
UTILITY_BILL = 'UTILITY_BILL',
GOVT_OR_CROWN_CORP_OFFICIAL_NOTICE = 'GOVT_OR_CROWN_CORP_OFFICIAL_NOTICE',
FRACTIONAL_OWNERSHIP_AGREEMENT = 'FRACTIONAL_OWNERSHIP_AGREEMENT',
STRATA_HOTEL_DOCUMENTATION = 'STRATA_HOTEL_DOCUMENTATION',
TENANCY_AGREEMENT = 'TENANCY_AGREEMENT',
RENT_RECEIPT_OR_BANK_STATEMENT = 'RENT_RECEIPT_OR_BANK_STATEMENT',
LOCAL_GOVT_BUSINESS_LICENSE = 'LOCAL_GOVT_BUSINESS_LICENSE',
OTHERS = 'OTHERS'
}
9 changes: 9 additions & 0 deletions strr-base-web/app/enums/host/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export * from './owner-role'
export * from './owner-type'
export * from './ownership-type'
export * from './pr-exemption-other-provider'
export * from './pr-exemption-reason'
export * from './property-type'
export * from './rental-unit-setup-types'
export * from './rental-unit-type'
export * from './residence-type'
5 changes: 5 additions & 0 deletions strr-base-web/app/enums/host/owner-role.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export enum OwnerRole {
HOST = 'HOST',
CO_HOST = 'CO_HOST',
PROPERTY_MANAGER = 'PROPERTY_MANAGER'
}
4 changes: 4 additions & 0 deletions strr-base-web/app/enums/host/owner-type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export enum OwnerType {
INDIVIDUAL = 'INDIVIDUAL',
BUSINESS = 'BUSINESS'
}
6 changes: 6 additions & 0 deletions strr-base-web/app/enums/host/ownership-type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export enum OwnershipType {
RENT = 'RENT',
OWN = 'OWN',
CO_OWN = 'CO_OWN',
OTHER = 'OTHER'
}
8 changes: 8 additions & 0 deletions strr-base-web/app/enums/host/pr-exemption-other-provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export enum PrExemptionOtherProvider {
TIMESHARE = 'TIMESHARE',
FRACTIONAL_OWNERSHIP = 'FRACTIONAL_OWNERSHIP',
HOME_EXCHANGE = 'HOME_EXCHANGE',
LODGE_OPERATOR = 'LODGE_OPERATOR',
EDUCATIONAL_INSTITUTION = 'EDUCATIONAL_INSTITUTION',
STRATA_GUEST_SUITE = 'STRATA_GUEST_SUITE'
}
5 changes: 5 additions & 0 deletions strr-base-web/app/enums/host/pr-exemption-reason.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export enum PrExemptionReason {
STRATA_HOTEL = 'STRATA_HOTEL',
FARM_LAND = 'FARM_LAND',
FRACTIONAL_OWNERSHIP = 'FRACTIONAL_OWNERSHIP',
}
12 changes: 12 additions & 0 deletions strr-base-web/app/enums/host/property-type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export enum PropertyType {
SECONDARY_SUITE = 'SECONDARY_SUITE',
ACCESSORY_DWELLING = 'ACCESSORY_DWELLING',
TOWN_HOME = 'TOWN_HOME',
MULTI_UNIT_HOUSING = 'MULTI_UNIT_HOUSING',
CONDO_OR_APT = 'CONDO_OR_APT',
STRATA_HOTEL = 'STRATA_HOTEL',
SINGLE_FAMILY_HOME = 'SINGLE_FAMILY_HOME',
RECREATIONAL = 'RECREATIONAL',
BED_AND_BREAKFAST = 'BED_AND_BREAKFAST',
FLOAT_HOME = 'FLOAT_HOME'
}
5 changes: 5 additions & 0 deletions strr-base-web/app/enums/host/rental-unit-setup-types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export enum RentalUnitSetupType {
WHOLE_PRINCIPAL_RESIDENCE = 'WHOLE_PRINCIPAL_RESIDENCE', // The whole Host Principal Residence
UNIT_ON_PR_PROPERTY = 'UNIT_ON_PR_PROPERTY', // A whole unit on the same property as the Host Principal Residence (e.g., basement suite)
UNIT_NOT_ON_PR_PROPERTY = 'UNIT_NOT_ON_PR_PROPERTY' // Not on the same property as the Host Principal Residence
}
4 changes: 4 additions & 0 deletions strr-base-web/app/enums/host/rental-unit-type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export enum RentalUnitType {
ENTIRE_HOME = 'ENTIRE_HOME',
SHARED_ACCOMMODATION = 'SHARED_ACCOMMODATION'
}
4 changes: 4 additions & 0 deletions strr-base-web/app/enums/host/residence-type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export enum ResidenceType {
SAME_UNIT = 'SAME_UNIT',
ANOTHER_UNIT = 'ANOTHER_UNIT'
}
1 change: 1 addition & 0 deletions strr-base-web/app/enums/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './host'
75 changes: 75 additions & 0 deletions strr-base-web/app/interfaces/host/host-api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
export interface ApiPartyWithAddress extends ApiParty {
mailingAddress: ApiAddress
}

export interface ApiHostContactPerson extends ApiPartyWithAddress {
contactType: OwnerType
dateOfBirth?: string
socialInsuranceNumber?: string
businessLegalName?: string
businessNumber?: string
}

export interface ApiHostContactBusiness extends ApiHostContactPerson {
businessLegalName: string
businessNumber: string
}

export interface ApiPropertyManagerBusiness {
legalName: string
businessNumber?: string
mailingAddress: ApiAddress
primaryContact: ApiParty
secondaryContact?: ApiParty
}

export interface ApiPropertyManager {
initiatedByPropertyManager: boolean
propertyManagerType: OwnerType
business?: ApiPropertyManagerBusiness // required if OwnerType.BUSINESS
contact?: ApiPartyWithAddress // required if OwnerType.INDIVIDUAL
}

export interface ApiUnitDetails {
parcelIdentifier?: string
businessLicense?: string
businessLicenseExpiryDate?: string
propertyType: PropertyType | undefined
ownershipType: OwnershipType | undefined
rentalUnitSpaceType: RentalUnitType | undefined
hostResidence: ResidenceType | undefined
isUnitOnPrincipalResidenceProperty: boolean | undefined
numberOfRoomsForRent: number | undefined
prExemptReason?: PrExemptionReason
}

export interface ApiUnitAddress extends ApiBaseAddress {
nickname: string
streetName: string,
streetNumber: string,
unitNumber: string
}

export interface ApiHostApplication {
registrationType: ApplicationType
primaryContact: ApiHostContactPerson | ApiHostContactBusiness
secondaryContact?: ApiHostContactPerson | ApiHostContactBusiness
unitDetails: ApiUnitDetails
unitAddress: ApiUnitAddress
propertyManager?: ApiPropertyManager,
strRequirements?: PropertyRequirements
documents: ApiDocument[]
listingDetails: string[]
}

export interface HostApplicationPayload {
// Draft applications will not have all fields defined yet
registration: Partial<ApiHostApplication>
}

export interface HostApplicationResp extends HostApplicationPayload {
header: ApplicationHeader
}

export interface HostRegistrationResp extends ApiHostApplication, ApiExtraRegistrationDetails {
}
11 changes: 11 additions & 0 deletions strr-base-web/app/interfaces/host/host-owner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export interface HostOwner extends Contact {
ownerType: OwnerType
preferredName?: string
mailingAddress: ConnectAddress
businessLegalName: string
businessNumber: string
dateOfBirth: string
role: OwnerRole | undefined,
isCompParty: boolean
taxNumber: string
}
9 changes: 9 additions & 0 deletions strr-base-web/app/interfaces/host/host-property.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export interface HostPropertyAddress extends ConnectAddress {
nickname: string
unitNumber: string
}

export interface HostProperty extends ApiUnitDetails {
address: HostPropertyAddress
listingDetails: { url: string }[]
}
23 changes: 23 additions & 0 deletions strr-base-web/app/interfaces/host/host-ui.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// export interface HostPropertyAddress extends ConnectAddress {
// nickname: string
// unitNumber: string
// }

export interface UiBlInfo {
businessLicense: string
businessLicenseExpiryDate: string
}

export interface UiUnitDetails {
parcelIdentifier?: string
propertyType: PropertyType | undefined
ownershipType: OwnershipType | undefined
numberOfRoomsForRent: number | undefined
rentalUnitSetupType: RentalUnitSetupType | undefined
typeOfSpace: RentalUnitType | undefined
}

export interface UiHostProperty extends UiUnitDetails {
address: HostPropertyAddress
listingDetails: { url: string }[]
}
7 changes: 7 additions & 0 deletions strr-base-web/app/interfaces/host/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export * from './host-api'
export * from './host-owner'
export * from './host-property'
export * from './host-ui'
export * from './principal-residence-requirements'
export * from './property-requirements'
export * from './property-requirements-error'
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface PrRequirements {
isPropertyPrExempt: boolean
prExemptionReason: PrExemptionReason | undefined
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type { FetchError } from 'ofetch'
export interface PropertyRequirementsError {
error?: FetchError
type: 'fetch' | 'unknown' // TODO: handle other error types
}
7 changes: 7 additions & 0 deletions strr-base-web/app/interfaces/host/property-requirements.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export interface PropertyRequirements {
isBusinessLicenceRequired: boolean
isPrincipalResidenceRequired: boolean
isStrProhibited: boolean
isStraaExempt: boolean | null
organizationNm: string
}
1 change: 1 addition & 0 deletions strr-base-web/app/interfaces/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './host'
144 changes: 144 additions & 0 deletions strr-base-web/app/utils/host/formatting.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
export function formatOwnerHostAPI (owner: HostOwner): ApiHostContactPerson | ApiHostContactBusiness {
return {
...formatParty(owner),
contactType: owner.ownerType,
mailingAddress: formatAddress(owner.mailingAddress),
...(owner.dateOfBirth ? { dateOfBirth: owner.dateOfBirth } : {}),
...(owner.taxNumber ? { socialInsuranceNumber: owner.taxNumber } : {}),
...(owner.businessLegalName ? { businessLegalName: owner.businessLegalName } : {}),
...(owner.businessNumber ? { businessNumber: owner.businessNumber } : {})
}
}

export function formatOwnerHostUI (
owner: ApiHostContactPerson | ApiHostContactBusiness,
isCompParty: boolean,
isCoHost?: boolean
): HostOwner {
return {
...formatPartyUI(owner),
ownerType: owner.contactType,
dateOfBirth: owner.dateOfBirth || '',
taxNumber: owner.socialInsuranceNumber || '',
mailingAddress: formatAddressUI(owner.mailingAddress),
businessLegalName: owner.businessLegalName || '',
businessNumber: owner.businessNumber || '',
role: isCoHost ? OwnerRole.CO_HOST : OwnerRole.HOST,
isCompParty
}
}

export function formatOwnerPropertyManagerAPI (owner: HostOwner): ApiPropertyManager {
return {
initiatedByPropertyManager: owner.isCompParty,
propertyManagerType: owner.ownerType,
...(owner.ownerType === OwnerType.INDIVIDUAL
? {
contact: {
...formatParty(owner),
mailingAddress: formatAddress(owner.mailingAddress)
}
}
: {
business: {
legalName: owner.businessLegalName,
...(owner.businessNumber ? { businessNumber: owner.businessNumber } : {}),
mailingAddress: formatAddress(owner.mailingAddress),
primaryContact: { ...formatParty(owner) }
}
}
)
}
}

export function formatOwnerPropertyManagerUI (owner: ApiPropertyManager): HostOwner {
return {
ownerType: owner.propertyManagerType,
...formatPartyUI((owner.contact || owner.business?.primaryContact) as ApiParty),
mailingAddress: formatAddressUI((owner.contact?.mailingAddress || owner.business?.mailingAddress) as ApiAddress),
businessLegalName: owner.business?.legalName || '',
businessNumber: owner.business?.businessNumber || '',
dateOfBirth: '',
taxNumber: '',
role: OwnerRole.PROPERTY_MANAGER,
isCompParty: owner.initiatedByPropertyManager
}
}

export function formatHostUnitDetailsAPI (
unitDetails: UiUnitDetails,
blInfo: UiBlInfo,
prReqs: PrRequirements
): ApiUnitDetails {
return {
propertyType: unitDetails.propertyType,
ownershipType: unitDetails.ownershipType,
numberOfRoomsForRent: unitDetails.numberOfRoomsForRent,
isUnitOnPrincipalResidenceProperty: unitDetails.rentalUnitSetupType === undefined
? undefined
: unitDetails.rentalUnitSetupType !== RentalUnitSetupType.UNIT_NOT_ON_PR_PROPERTY,
hostResidence: unitDetails.rentalUnitSetupType === undefined
? undefined
: unitDetails.rentalUnitSetupType === RentalUnitSetupType.WHOLE_PRINCIPAL_RESIDENCE
? ResidenceType.SAME_UNIT
: ResidenceType.ANOTHER_UNIT,
rentalUnitSpaceType: unitDetails.typeOfSpace,
...(unitDetails.parcelIdentifier ? { parcelIdentifier: unitDetails.parcelIdentifier } : {}),
...(blInfo.businessLicense ? { businessLicense: blInfo.businessLicense } : {}),
...(blInfo.businessLicenseExpiryDate ? { businessLicenseExpiryDate: blInfo.businessLicenseExpiryDate } : {}),
...(prReqs.isPropertyPrExempt && prReqs.prExemptionReason ? { prExemptReason: prReqs.prExemptionReason } : {})
}
}

export function formatHostUnitDetailsUI (unitDetails: ApiUnitDetails): UiUnitDetails {
const rentalSetupType = unitDetails.isUnitOnPrincipalResidenceProperty === undefined
? undefined
: unitDetails.isUnitOnPrincipalResidenceProperty
? unitDetails.hostResidence === ResidenceType.SAME_UNIT
? RentalUnitSetupType.WHOLE_PRINCIPAL_RESIDENCE
: RentalUnitSetupType.UNIT_ON_PR_PROPERTY
: RentalUnitSetupType.UNIT_NOT_ON_PR_PROPERTY
return {
propertyType: unitDetails.propertyType,
ownershipType: unitDetails.ownershipType,
numberOfRoomsForRent: unitDetails.numberOfRoomsForRent,
rentalUnitSetupType: rentalSetupType,
typeOfSpace: unitDetails.rentalUnitSpaceType,
...(unitDetails.parcelIdentifier ? { parcelIdentifier: unitDetails.parcelIdentifier } : {})
}
}

export function formatHostUnitDetailsBlInfoUI (unitDetails: ApiUnitDetails): UiBlInfo {
return {
businessLicense: unitDetails.businessLicense || '',
businessLicenseExpiryDate: unitDetails.businessLicenseExpiryDate || ''
}
}

export function formatHostUnitAddressApi (unitAddress: HostPropertyAddress): ApiUnitAddress {
const baseAddress = formatAddress(unitAddress)
delete baseAddress.address // including this passes API validation, but causes a failure in the registration creation
return {
...baseAddress,
nickname: unitAddress.nickname || '',
streetName: unitAddress.streetName || '',
streetNumber: unitAddress.streetNumber || '',
unitNumber: unitAddress.unitNumber || ''
}
}

export function formatHostUnitAddressUI (unitAddress: ApiUnitAddress): HostPropertyAddress {
const baseAddress = formatAddressUI(unitAddress)
const street = baseAddress.street
? baseAddress.street
: `${unitAddress.unitNumber ? unitAddress.unitNumber + '-' : ''}` +
`${unitAddress.streetNumber || ''} ${unitAddress.streetName}`.trim()
return {
...baseAddress,
nickname: unitAddress.nickname || '',
streetName: unitAddress.streetName || '',
streetNumber: unitAddress.streetNumber || '',
unitNumber: unitAddress.unitNumber || '',
street
}
}
1 change: 1 addition & 0 deletions strr-base-web/app/utils/host/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './formatting'
1 change: 1 addition & 0 deletions strr-base-web/app/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './connect-validation'
export * from './host'
Loading

0 comments on commit e1c43b2

Please sign in to comment.