diff --git a/frontend/package.json b/frontend/package.json index 206696fc..c8d92ab6 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -15,13 +15,13 @@ "@vitejs/plugin-legacy": "^1.6.2", "@vuelidate/core": "^2.0.0-alpha.27", "@vuelidate/validators": "^2.0.0-alpha.23", + "@vuepic/vue-datepicker": "^3.2.0", "axios": "^0.23.0", "dayjs": "^1.10.7", "keycloak-js": "^15.0.2", "pinia": "next", "vue": "^3.2.13", - "vue-router": "4", - "vue3-date-time-picker": "2.8.0" + "vue-router": "4" }, "devDependencies": { "@vitejs/plugin-vue": "^1.9.0", diff --git a/frontend/src/components/coverage/enrollment/NameSearch.vue b/frontend/src/components/coverage/enrollment/NameSearch.vue index 77892af9..14d57222 100644 --- a/frontend/src/components/coverage/enrollment/NameSearch.vue +++ b/frontend/src/components/coverage/enrollment/NameSearch.vue @@ -39,7 +39,7 @@ import GenderRadioButtonGroup from '../../ui/GenderRadioButtonGroup.vue' import useVuelidate from '@vuelidate/core' import dayjs from 'dayjs' import { API_DATE_FORMAT } from '../../../util/constants' -import { validateDOB, validateFirstName, validateSecondName, validateSurname, VALIDATE_DOB_MESSAGE, VALIDATE_FIRST_NAME_MESSAGE, VALIDATE_SECOND_NAME_MESSAGE, VALIDATE_SURNAME_MESSAGE } from '../../../util/validators' +import { validateDOB, validateMinimumDate, validateFirstName, validateSecondName, validateSurname, VALIDATE_DOB_MESSAGE, VALIDATE_MINIMUM_DATE_MESSAGE, VALIDATE_FIRST_NAME_MESSAGE, VALIDATE_SECOND_NAME_MESSAGE, VALIDATE_SURNAME_MESSAGE } from '../../../util/validators' import { required, helpers, maxLength } from '@vuelidate/validators' import { useAlertStore } from '../../../stores/alert' @@ -118,6 +118,7 @@ export default { dateOfBirth: { required, validateDOB: helpers.withMessage(VALIDATE_DOB_MESSAGE, validateDOB), + validateMinimumDate: helpers.withMessage(VALIDATE_MINIMUM_DATE_MESSAGE, validateMinimumDate), }, gender: { required, diff --git a/frontend/src/components/coverage/enrollment/ResidentDetails.vue b/frontend/src/components/coverage/enrollment/ResidentDetails.vue index 921e6ded..4e5868dd 100644 --- a/frontend/src/components/coverage/enrollment/ResidentDetails.vue +++ b/frontend/src/components/coverage/enrollment/ResidentDetails.vue @@ -147,6 +147,7 @@ import { validatePostalCode, validateAddress, validateOptionalAddress, + validateMinimumDate, validateMailingAddressForVisaResident, VALIDATE_ADDRESS_LINE1_REQUIRED_MESSAGE, VALIDATE_ADDRESS_LINE1_MESSAGE, @@ -158,6 +159,7 @@ import { VALIDATE_DEPARTMENT_NUMBER_MESSAGE, VALIDATE_TELEPHONE_MESSAGE, VALIDATE_POSTAL_CODE_MESSAGE, + VALIDATE_MINIMUM_DATE_MESSAGE, } from '../../../util/validators' import { required, requiredIf, helpers, maxLength } from '@vuelidate/validators' import dayjs from 'dayjs' @@ -321,17 +323,29 @@ export default { groupMemberNumber: { validateGroupMemberNumber: helpers.withMessage(VALIDATE_GROUP_MEMBER_NUMBER_MESSAGE, validateGroupMemberNumber), }, - visaIssueDate: { required }, + visaIssueDate: { + required, + validateMinimumDate: helpers.withMessage(VALIDATE_MINIMUM_DATE_MESSAGE, validateMinimumDate), + }, departmentNumber: { validateDepartmentNumber: helpers.withMessage(VALIDATE_DEPARTMENT_NUMBER_MESSAGE, validateDepartmentNumber), }, - visaExpiryDate: { required }, - residenceDate: { required }, + visaExpiryDate: { + required, + validateMinimumDate: helpers.withMessage(VALIDATE_MINIMUM_DATE_MESSAGE, validateMinimumDate), + }, + residenceDate: { + required, + validateMinimumDate: helpers.withMessage(VALIDATE_MINIMUM_DATE_MESSAGE, validateMinimumDate), + }, coverageEffectiveDate: { required }, telephone: { validateTelephone: helpers.withMessage(VALIDATE_TELEPHONE_MESSAGE, validateTelephone), }, - coverageCancellationDate: { required }, + coverageCancellationDate: { + required, + validateMinimumDate: helpers.withMessage(VALIDATE_MINIMUM_DATE_MESSAGE, validateMinimumDate), + }, address1: { required, maxLength: maxLength(25), diff --git a/frontend/src/components/coverage/enrollment/ResidentDetailsWithoutPHN.vue b/frontend/src/components/coverage/enrollment/ResidentDetailsWithoutPHN.vue index a04f3099..08ad67ad 100644 --- a/frontend/src/components/coverage/enrollment/ResidentDetailsWithoutPHN.vue +++ b/frontend/src/components/coverage/enrollment/ResidentDetailsWithoutPHN.vue @@ -159,6 +159,7 @@ import { validateSecondName, validateSurname, validateMailingAddressForVisaResident, + validateMinimumDate, VALIDATE_FIRST_NAME_MESSAGE, VALIDATE_SECOND_NAME_MESSAGE, VALIDATE_SURNAME_MESSAGE, @@ -173,6 +174,7 @@ import { VALIDATE_DOB_MESSAGE, VALIDATE_TELEPHONE_MESSAGE, VALIDATE_POSTAL_CODE_MESSAGE, + VALIDATE_MINIMUM_DATE_MESSAGE, } from '../../../util/validators' import { required, requiredIf, helpers, maxLength } from '@vuelidate/validators' import dayjs from 'dayjs' @@ -345,6 +347,7 @@ export default { dateOfBirth: { required, validateDOB: helpers.withMessage(VALIDATE_DOB_MESSAGE, validateDOB), + validateMinimumDate: helpers.withMessage(VALIDATE_MINIMUM_DATE_MESSAGE, validateMinimumDate), }, gender: { required, @@ -357,17 +360,32 @@ export default { groupMemberNumber: { validateGroupMemberNumber: helpers.withMessage(VALIDATE_GROUP_MEMBER_NUMBER_MESSAGE, validateGroupMemberNumber), }, - permitIssueDate: { required }, + permitIssueDate: { + required, + validateMinimumDate: helpers.withMessage(VALIDATE_MINIMUM_DATE_MESSAGE, validateMinimumDate), + }, departmentNumber: { validateDepartmentNumber: helpers.withMessage(VALIDATE_DEPARTMENT_NUMBER_MESSAGE, validateDepartmentNumber), }, - permitExpiryDate: { required }, - residenceDate: { required }, - coverageEffectiveDate: { required }, + permitExpiryDate: { + required, + validateMinimumDate: helpers.withMessage(VALIDATE_MINIMUM_DATE_MESSAGE, validateMinimumDate), + }, + residenceDate: { + required, + validateMinimumDate: helpers.withMessage(VALIDATE_MINIMUM_DATE_MESSAGE, validateMinimumDate), + }, + coverageEffectiveDate: { + required, + validateMinimumDate: helpers.withMessage(VALIDATE_MINIMUM_DATE_MESSAGE, validateMinimumDate), + }, telephone: { validateTelephone: helpers.withMessage(VALIDATE_TELEPHONE_MESSAGE, validateTelephone), }, - coverageCancellationDate: { required }, + coverageCancellationDate: { + required, + validateMinimumDate: helpers.withMessage(VALIDATE_MINIMUM_DATE_MESSAGE, validateMinimumDate), + }, address1: { required, maxLength: maxLength(25), diff --git a/frontend/src/components/ui/AppDateInput.vue b/frontend/src/components/ui/AppDateInput.vue index df1fadad..604619fe 100644 --- a/frontend/src/components/ui/AppDateInput.vue +++ b/frontend/src/components/ui/AppDateInput.vue @@ -1,72 +1,62 @@ \ No newline at end of file + diff --git a/frontend/src/util/validators.js b/frontend/src/util/validators.js index 190a20bd..e2084e45 100644 --- a/frontend/src/util/validators.js +++ b/frontend/src/util/validators.js @@ -91,6 +91,38 @@ export function validateDOB(dateOfBirth) { return true } +/** + * Validates that the Date is not earlier than '1900-01-01' . + */ +export function validateMinimumDate(dateInput) { + if (!helpers.req(dateInput)) { + return true + } + return !dayjs(dateInput).isBefore('1900-01-01') +} + +/** + * Validates that the EffectiveDate is not earlier than '1900-01-01' . + */ +export function validateMinimumEffectiveDate(dateInput) { + if (!helpers.req(dateInput)) { + return true + } + const adjustedEffectiveDate = new Date(this.coverageEffectiveDate.year, this.coverageEffectiveDate.month, 1) + return validateMinimumDate(adjustedEffectiveDate) +} + +/** + * Validates that the Cancel Date is not earlier than '1900-01-01' . + */ +export function validateMinimumCancelDate(dateInput) { + if (!helpers.req(dateInput)) { + return true + } + const adjustedCancelDate = new Date(this.cancelDate.year, this.cancelDate.month + 1, 0) + return validateMinimumDate(adjustedCancelDate) +} + /** * Validate Group Member Number. It can be up to nine (9) characters. Any alpha or numeric characters are allowed, except for |^ \ & which are invalid. */ @@ -292,6 +324,7 @@ export const VALIDATE_FIRST_NAME_MESSAGE = 'First Name is invalid' export const VALIDATE_SECOND_NAME_MESSAGE = 'Second Name is invalid' export const VALIDATE_CITY_MESSAGE = 'City is invalid' export const VALIDATE_DOB_MESSAGE = 'Date of Birth must not be in the future' +export const VALIDATE_MINIMUM_DATE_MESSAGE = 'Date must be on or after 19000101' export const VALIDATE_PHN_MESSAGE = 'PHN format is invalid' export const VALIDATE_CONTRACT_NUMBER_MESSAGE = 'MSP Contract Number is invalid' export const VALIDATE_GROUP_NUMBER_MESSAGE = 'Group Number is invalid' diff --git a/frontend/src/views/eligibility/CheckEligibility.vue b/frontend/src/views/eligibility/CheckEligibility.vue index 5e9a6566..d985d606 100644 --- a/frontend/src/views/eligibility/CheckEligibility.vue +++ b/frontend/src/views/eligibility/CheckEligibility.vue @@ -50,7 +50,7 @@ import AppCard from '../../components/ui/AppCard.vue' import EligibilityService from '../../services/EligibilityService' import useVuelidate from '@vuelidate/core' -import { validatePHN, VALIDATE_PHN_MESSAGE } from '../../util/validators' +import { validatePHN, validateMinimumDate, VALIDATE_PHN_MESSAGE, VALIDATE_MINIMUM_DATE_MESSAGE } from '../../util/validators' import { required, helpers } from '@vuelidate/validators' import { API_DATE_FORMAT, COVERAGE_END_REASONS } from '../../util/constants' import dayjs from 'dayjs' @@ -147,7 +147,10 @@ export default { required, validatePHN: helpers.withMessage(VALIDATE_PHN_MESSAGE, validatePHN), }, - eligibilityDate: { required }, + eligibilityDate: { + required, + validateMinimumDate: helpers.withMessage(VALIDATE_MINIMUM_DATE_MESSAGE, validateMinimumDate), + }, } }, } diff --git a/frontend/src/views/eligibility/CoverageStatusCheck.vue b/frontend/src/views/eligibility/CoverageStatusCheck.vue index 78db0f4b..e82ce0d9 100644 --- a/frontend/src/views/eligibility/CoverageStatusCheck.vue +++ b/frontend/src/views/eligibility/CoverageStatusCheck.vue @@ -97,7 +97,7 @@ import AppCard from '../../components/ui/AppCard.vue' import AppCheckbox from '../../components/ui/AppCheckbox.vue' import EligibilityService from '../../services/EligibilityService' import useVuelidate from '@vuelidate/core' -import { validateDOB, validatePHN, VALIDATE_DOB_MESSAGE, VALIDATE_PHN_MESSAGE } from '../../util/validators' +import { validateDOB, validateMinimumDate, validatePHN, VALIDATE_DOB_MESSAGE, VALIDATE_MINIMUM_DATE_MESSAGE, VALIDATE_PHN_MESSAGE } from '../../util/validators' import { API_DATE_FORMAT, COVERAGE_END_REASONS } from '../../util/constants' import { required, helpers } from '@vuelidate/validators' import dayjs from 'dayjs' @@ -275,8 +275,12 @@ export default { dateOfBirth: { required, validateDOB: helpers.withMessage(VALIDATE_DOB_MESSAGE, validateDOB), + validateMinimumDate: helpers.withMessage(VALIDATE_MINIMUM_DATE_MESSAGE, validateMinimumDate), + }, + dateOfService: { + required, + validateMinimumDate: helpers.withMessage(VALIDATE_MINIMUM_DATE_MESSAGE, validateMinimumDate), }, - dateOfService: { required }, } }, } diff --git a/frontend/src/views/groupmember/AddDependent.vue b/frontend/src/views/groupmember/AddDependent.vue index 880e5ffe..fce86ade 100644 --- a/frontend/src/views/groupmember/AddDependent.vue +++ b/frontend/src/views/groupmember/AddDependent.vue @@ -55,7 +55,7 @@ import YesNoRadioButtonGroup from '../../components/ui/YesNoRadioButtonGroup.vue import useVuelidate from '@vuelidate/core' import { helpers, required, requiredIf } from '@vuelidate/validators' import dayjs from 'dayjs' -import { VALIDATE_GROUP_NUMBER_MESSAGE, VALIDATE_PHN_MESSAGE, validateGroupNumber, validatePHN } from '../../util/validators' +import { VALIDATE_GROUP_NUMBER_MESSAGE, VALIDATE_PHN_MESSAGE, VALIDATE_MINIMUM_DATE_MESSAGE, validateGroupNumber, validatePHN, validateMinimumDate, validateMinimumEffectiveDate } from '../../util/validators' import { API_DATE_FORMAT, RELATIONSHIPS } from '../../util/constants' import GroupMemberService from '../../services/GroupMemberService' import { useAlertStore } from '../../stores/alert' @@ -165,7 +165,10 @@ export default { required, validateGroupNumber: helpers.withMessage(VALIDATE_GROUP_NUMBER_MESSAGE, validateGroupNumber), }, - coverageEffectiveDate: { required }, + coverageEffectiveDate: { + required, + validateMinimumEffectiveDate: helpers.withMessage(VALIDATE_MINIMUM_DATE_MESSAGE, validateMinimumEffectiveDate), + }, phn: { required, validatePHN: helpers.withMessage(VALIDATE_PHN_MESSAGE, validatePHN), @@ -182,6 +185,7 @@ export default { requiredIfIsStudent: requiredIf(() => { return this.isStudent === 'Y' }), + validateMinimumDate: helpers.withMessage(VALIDATE_MINIMUM_DATE_MESSAGE, validateMinimumDate), }, } }, diff --git a/frontend/src/views/groupmember/AddGroupMember.vue b/frontend/src/views/groupmember/AddGroupMember.vue index c8e7de0a..147d3ce7 100644 --- a/frontend/src/views/groupmember/AddGroupMember.vue +++ b/frontend/src/views/groupmember/AddGroupMember.vue @@ -126,6 +126,7 @@ import { validateOptionalAddress, validateDepartmentNumber, validateGroupMemberNumber, + validateMinimumEffectiveDate, VALIDATE_ADDRESS_LINE1_REQUIRED_MESSAGE, VALIDATE_ADDRESS_LINE1_MESSAGE, VALIDATE_ADDRESS_LINE2_MESSAGE, @@ -137,6 +138,7 @@ import { VALIDATE_PHN_MESSAGE, VALIDATE_POSTAL_CODE_MESSAGE, VALIDATE_TELEPHONE_MESSAGE, + VALIDATE_MINIMUM_DATE_MESSAGE, } from '../../util/validators' import GroupMemberService from '../../services/GroupMemberService' import { useAlertStore } from '../../stores/alert' @@ -311,7 +313,10 @@ export default { departmentNumber: { validateDepartmentNumber: helpers.withMessage(VALIDATE_DEPARTMENT_NUMBER_MESSAGE, validateDepartmentNumber), }, - coverageEffectiveDate: { required }, + coverageEffectiveDate: { + required, + validateMinimumEffectiveDate: helpers.withMessage(VALIDATE_MINIMUM_DATE_MESSAGE, validateMinimumEffectiveDate), + }, telephone: { validateTelephone: helpers.withMessage(VALIDATE_TELEPHONE_MESSAGE, validateTelephone), }, diff --git a/frontend/src/views/groupmember/CancelDependent.vue b/frontend/src/views/groupmember/CancelDependent.vue index 717ff898..c067ea55 100644 --- a/frontend/src/views/groupmember/CancelDependent.vue +++ b/frontend/src/views/groupmember/CancelDependent.vue @@ -47,7 +47,7 @@