diff --git a/libs/application/template-api-modules/src/lib/modules/templates/health-insurance-declaration/health-insurance-declaration.service.ts b/libs/application/template-api-modules/src/lib/modules/templates/health-insurance-declaration/health-insurance-declaration.service.ts index 2c3cab1c7cd3..1184c0a5a367 100644 --- a/libs/application/template-api-modules/src/lib/modules/templates/health-insurance-declaration/health-insurance-declaration.service.ts +++ b/libs/application/template-api-modules/src/lib/modules/templates/health-insurance-declaration/health-insurance-declaration.service.ts @@ -1,4 +1,8 @@ -import { ApplicationTypes } from '@island.is/application/types' +import { + ApplicantChildCustodyInformation, + ApplicationTypes, + NationalRegistrySpouse, +} from '@island.is/application/types' import { InsurancestatementsApi, MinarsidurAPIModelsInsuranceStatementsResponseInsuranceStatementApplicationResponseDTO, @@ -8,6 +12,7 @@ import { BaseTemplateApiService } from '../../base-template-api.service' import { TemplateApiModuleActionProps } from '../../../types' import { AuthMiddleware, Auth } from '@island.is/auth-nest-tools' import { ApplicationAttachmentProvider } from './attachments/provider' +import { prerequisites } from '@island.is/application/templates/health-insurance-declaration' import { applicationToStudentApplication, applicationToTouristApplication, @@ -17,6 +22,7 @@ import { getPersonsFromExternalData, } from './health-insurance-declaration.utils' import { ApplicantType } from './consts' +import { TemplateApiError } from '@island.is/nest/problem' @Injectable() export class HealthInsuranceDeclarationService extends BaseTemplateApiService { @@ -52,10 +58,29 @@ export class HealthInsuranceDeclarationService extends BaseTemplateApiService { ).getInsuranceStatementCountries() } - async getInsuranceStatementData(application: TemplateApiModuleActionProps) { - const status = await this.status(application) - const continents = await this.continents(application) - const countries = await this.countries(application) + async getInsuranceStatementData( + applicationWithProps: TemplateApiModuleActionProps, + ) { + const status = await this.status(applicationWithProps) + const continents = await this.continents(applicationWithProps) + const countries = await this.countries(applicationWithProps) + const { application } = applicationWithProps + + if (status.canApply !== true) { + const childrenInformation = application.externalData + .childrenCustodyInformation.data as ApplicantChildCustodyInformation[] + const spouse = application.externalData.nationalRegistrySpouse + .data as NationalRegistrySpouse + if (!spouse && childrenInformation.length < 1) { + throw new TemplateApiError( + { + summary: prerequisites.errors.noDeclarationAvailable, + title: prerequisites.errors.noDeclarationAvailableTitle, + }, + 400, + ) + } + } return { ...status, diff --git a/libs/application/template-api-modules/src/lib/modules/templates/health-insurance-declaration/health-insurance-declaration.utils.ts b/libs/application/template-api-modules/src/lib/modules/templates/health-insurance-declaration/health-insurance-declaration.utils.ts index e0689d43909d..289537cf7f61 100644 --- a/libs/application/template-api-modules/src/lib/modules/templates/health-insurance-declaration/health-insurance-declaration.utils.ts +++ b/libs/application/template-api-modules/src/lib/modules/templates/health-insurance-declaration/health-insurance-declaration.utils.ts @@ -65,7 +65,7 @@ const getApplicants = ( } // Spouse - answers.registerPersonsSpouseCheckboxField.map((s) => { + answers.selectedApplicants?.registerPersonsSpouseCheckboxField?.map((s) => { const externalSpouse = application.externalData.nationalRegistrySpouse.data.nationalId === s ? application.externalData.nationalRegistrySpouse.data @@ -79,7 +79,7 @@ const getApplicants = ( } }) // Children - answers.registerPersonsChildrenCheckboxField.map((c) => { + answers.selectedApplicants?.registerPersonsChildrenCheckboxField?.map((c) => { const child = application.externalData.childrenCustodyInformation.data.find( (externalChild) => externalChild.nationalId === c, ) @@ -125,10 +125,12 @@ export const getPersonsFromExternalData = (application: Application) => { ).fullName, }, ] - persons.push({ - nationalId: spouse.nationalId, - name: spouse.name, - }) + if (spouse) { + persons.push({ + nationalId: spouse.nationalId, + name: spouse.name, + }) + } children.map((child) => { persons.push({ nationalId: child.nationalId, diff --git a/libs/application/templates/health-insurance-declaration/src/forms/HealthInsuranceDeclarationForm.ts b/libs/application/templates/health-insurance-declaration/src/forms/HealthInsuranceDeclarationForm.ts index 354d6b6d589a..518d2b4a7bd6 100644 --- a/libs/application/templates/health-insurance-declaration/src/forms/HealthInsuranceDeclarationForm.ts +++ b/libs/application/templates/health-insurance-declaration/src/forms/HealthInsuranceDeclarationForm.ts @@ -36,6 +36,7 @@ import { getInsuranceStatus, getSelectedFamily, getSpouseAsOptions, + hasFamilySelected, } from '../utils' import { HealthInsuranceDeclaration } from '../lib/dataSchema' import { applicantInformationMessages } from '@island.is/application/ui-forms' @@ -163,6 +164,18 @@ export const HealthInsuranceDeclarationForm: Form = buildForm({ application: HealthInsuranceDeclarationApplication, ) => getCommentFromExternalData(application.externalData), }), + buildHiddenInput({ + id: 'hasSpouse', + defaultValue: ( + application: HealthInsuranceDeclarationApplication, + ) => getSpouseAsOptions(application.externalData).length > 0, + }), + buildHiddenInput({ + id: 'hasChildren', + defaultValue: ( + application: HealthInsuranceDeclarationApplication, + ) => getChildrenAsOptions(application.externalData).length > 0, + }), ], }), ], @@ -207,7 +220,8 @@ export const HealthInsuranceDeclarationForm: Form = buildForm({ }), ], condition: (answers: FormValue) => { - return !answers.isHealthInsured as boolean + return (answers.isHealthInsured !== undefined && + !answers.isHealthInsured) as boolean }, }), buildSection({ @@ -254,18 +268,32 @@ export const HealthInsuranceDeclarationForm: Form = buildForm({ title: m.application.registerPersons.sectionDescription, children: [ buildCheckboxField({ - id: 'registerPersonsSpouseCheckboxField', + id: 'selectedApplicants.registerPersonsSpouseCheckboxField', title: m.application.registerPersons.spousetitle, options: ({ externalData }) => getSpouseAsOptions(externalData), + condition: (answers) => { + return answers?.hasSpouse as boolean + }, }), buildCheckboxField({ - id: 'registerPersonsChildrenCheckboxField', + id: 'selectedApplicants.registerPersonsChildrenCheckboxField', title: m.application.registerPersons.childrenTitle, options: ({ externalData }) => getChildrenAsOptions(externalData), + condition: (answers) => { + return answers?.hasChildren as boolean + }, + }), + buildHiddenInput({ + id: 'selectedApplicants.isHealthInsured', + defaultValue: ( + application: HealthInsuranceDeclarationApplication, + ) => getInsuranceStatus(application.externalData), }), ], }), ], + condition: (answers: FormValue) => + !!(answers.hasSpouse || answers.hasChildren), }), buildSection({ id: 'residencySectionTourist', @@ -459,8 +487,13 @@ export const HealthInsuranceDeclarationForm: Form = buildForm({ applicantInformationMessages.labels.nationalId, 'Tengsl', ], + condition: (answers) => + hasFamilySelected(answers as HealthInsuranceDeclaration), + }), + buildDividerField({ + condition: (answers) => + hasFamilySelected(answers as HealthInsuranceDeclaration), }), - buildDividerField({}), // Date period buildDescriptionField({ id: 'overviewDatePeriodTitle', diff --git a/libs/application/templates/health-insurance-declaration/src/forms/Prerequisites.ts b/libs/application/templates/health-insurance-declaration/src/forms/Prerequisites.ts index 61cbd8e301fa..028b3d337b70 100644 --- a/libs/application/templates/health-insurance-declaration/src/forms/Prerequisites.ts +++ b/libs/application/templates/health-insurance-declaration/src/forms/Prerequisites.ts @@ -17,7 +17,7 @@ import { } from '@island.is/application/types' import { application } from '../lib/messages' import Logo from '../assets/Logo' -import { prerequisites } from '../lib/messages/prerequsites' +import { prerequisites } from '../lib/messages/prerequisites' export const Prerequisites: Form = buildForm({ id: 'HealthInsuranceDeclarationPrerequsites', diff --git a/libs/application/templates/health-insurance-declaration/src/forms/Submitted.ts b/libs/application/templates/health-insurance-declaration/src/forms/Submitted.ts index 938e7df9cc01..af5a06c03bd0 100644 --- a/libs/application/templates/health-insurance-declaration/src/forms/Submitted.ts +++ b/libs/application/templates/health-insurance-declaration/src/forms/Submitted.ts @@ -1,6 +1,5 @@ import { buildCustomField, - buildDataProviderItem, buildDescriptionField, buildForm, buildMessageWithLinkButtonField, diff --git a/libs/application/templates/health-insurance-declaration/src/index.ts b/libs/application/templates/health-insurance-declaration/src/index.ts index 3fbccd83de8c..055f97791e78 100644 --- a/libs/application/templates/health-insurance-declaration/src/index.ts +++ b/libs/application/templates/health-insurance-declaration/src/index.ts @@ -3,4 +3,6 @@ import HealthInsuranceDeclarationTemplate from './lib/HealthInsuranceDeclaration export const getFields = () => import('./fields') export * from './shared/constants' export * from './types' +export * from './lib/messages' + export default HealthInsuranceDeclarationTemplate diff --git a/libs/application/templates/health-insurance-declaration/src/lib/HealthInsuranceDeclarationTemplate.tsx b/libs/application/templates/health-insurance-declaration/src/lib/HealthInsuranceDeclarationTemplate.ts similarity index 100% rename from libs/application/templates/health-insurance-declaration/src/lib/HealthInsuranceDeclarationTemplate.tsx rename to libs/application/templates/health-insurance-declaration/src/lib/HealthInsuranceDeclarationTemplate.ts diff --git a/libs/application/templates/health-insurance-declaration/src/lib/dataSchema.ts b/libs/application/templates/health-insurance-declaration/src/lib/dataSchema.ts index ede7f41f111f..afaa2c264e33 100644 --- a/libs/application/templates/health-insurance-declaration/src/lib/dataSchema.ts +++ b/libs/application/templates/health-insurance-declaration/src/lib/dataSchema.ts @@ -7,6 +7,8 @@ export const HealthInsuranceDeclarationSchema = z.object({ approveExternalData: z.boolean().refine((v) => v), applicant: applicantInformationSchema(), isHealthInsured: z.boolean(), + hasSpouse: z.boolean(), + hasChildren: z.boolean(), studentOrTouristRadioFieldTourist: z.enum([ ApplicantType.STUDENT, ApplicantType.TOURIST, @@ -19,8 +21,32 @@ export const HealthInsuranceDeclarationSchema = z.object({ .string() .or(z.undefined()) .refine((v) => !!v), - registerPersonsSpouseCheckboxField: z.string().array(), - registerPersonsChildrenCheckboxField: z.string().array(), + selectedApplicants: z + .object({ + registerPersonsSpouseCheckboxField: z.string().array().optional(), + registerPersonsChildrenCheckboxField: z.string().array().optional(), + isHealthInsured: z.boolean(), + }) + .superRefine((v, ctx) => { + if ( + !v.isHealthInsured && + !v.registerPersonsSpouseCheckboxField?.length && + !v.registerPersonsChildrenCheckboxField?.length + ) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + path: ['registerPersonsChildrenCheckboxField'], + params: errors.fields.noSelectedApplicant, + }) + ctx.addIssue({ + code: z.ZodIssueCode.custom, + path: ['registerPersonsSpouseCheckboxField'], + params: errors.fields.noSelectedApplicant, + }) + return false + } + return true + }), educationConfirmationFileUploadField: z .object({ name: z.string(), diff --git a/libs/application/templates/health-insurance-declaration/src/lib/messages/errors.ts b/libs/application/templates/health-insurance-declaration/src/lib/messages/errors.ts index 76bdb44a907a..73961163a09c 100644 --- a/libs/application/templates/health-insurance-declaration/src/lib/messages/errors.ts +++ b/libs/application/templates/health-insurance-declaration/src/lib/messages/errors.ts @@ -17,6 +17,12 @@ export const errors = { defaultMessage: 'Upphafs dagsetning má ekki vera eftir loka dagsetningu', description: 'Start date after end date error message', }, + noSelectedApplicant: { + id: 'hid.application:errors.fields.noSelectedApplicant', + defaultMessage: + 'Að minnsta kosti einn aðlili þarf að vera valinn svo hægt sé að sækja um yfirlýsingu', + description: 'No selected applicant error message', + }, }), submitted: defineMessages({ externalError: { diff --git a/libs/application/templates/health-insurance-declaration/src/lib/messages/index.ts b/libs/application/templates/health-insurance-declaration/src/lib/messages/index.ts index 5fa84cddf412..5d447b6c4499 100644 --- a/libs/application/templates/health-insurance-declaration/src/lib/messages/index.ts +++ b/libs/application/templates/health-insurance-declaration/src/lib/messages/index.ts @@ -1,3 +1,4 @@ export * from './application' export * from './errors' export * from './conclution' +export * from './prerequisites' diff --git a/libs/application/templates/health-insurance-declaration/src/lib/messages/prerequsites.ts b/libs/application/templates/health-insurance-declaration/src/lib/messages/prerequisites.ts similarity index 72% rename from libs/application/templates/health-insurance-declaration/src/lib/messages/prerequsites.ts rename to libs/application/templates/health-insurance-declaration/src/lib/messages/prerequisites.ts index 0b67f3be01e1..27a6cae0a6a2 100644 --- a/libs/application/templates/health-insurance-declaration/src/lib/messages/prerequsites.ts +++ b/libs/application/templates/health-insurance-declaration/src/lib/messages/prerequisites.ts @@ -19,19 +19,30 @@ export const prerequisites = { description: 'Checkbox label', }, }), - errors: defineMessages({}), + errors: defineMessages({ + noDeclarationAvailableTitle: { + id: 'hid.application:prerequisites.errors.noDeclarationAvailableTitle', + defaultMessage: 'Engin yfirlýsing í boði', + description: + 'Prerequisite error message title when no declaration is available', + }, + noDeclarationAvailable: { + id: 'hid.application:prerequisites.errors.noDeclarationAvailable#markdown', + defaultMessage: `Engin yfirlýsing í boði, helstu ástæður eru þessar: +* Þú ert ekki með gilda sjúkratryggingu á Íslandi. +* Ekki eru einstaklingar á þínu lögheimili sem þú getur sótt yfirlýsingu fyrir + +Ef þú telur þetta ekki rétt skaltu hafa samband hér: (ehic@sjukra.is)[mailto:ethic@sjukra.is]`, + description: + 'Prerequisite error message when no declaration is available', + }, + }), intro: defineMessages({ sectionTitle: { id: 'hid.application:prerequisites.intro.section.title', defaultMessage: 'Upplýsingar til umsækjanda', description: 'Introduction section title', }, - text: { - id: 'hid.application:prerequisites.intro.text#markdown', - defaultMessage: - '- Umsókn um kaup ríkisins á íbúðareign þinni skuldbindur þig ekki til að selja en með henni hefst söluferlið.\n- Nóg er að einn af eigendum fylli út umsóknina en þegar kemur að sölunni þurfa allir eigendur að undirrita.\n- Staðfesting umsóknar mun berast eigendum í Stafræna pósthólfið þeirra.\n- Gott er fyrir umsækjanda að þekkja öll lán eignar og uppgreiðsluverð þeirra því kallað er eftir þeim upphæðum í umsókninni.\n- Eftir að umsókn klárast hefst úrvinnsla hjá Þórkötlu en stefnt er að því að það ferli taki um 2-4 vikur.\n- Haft verður samband við eigendur ef einhver gögn vantar eða ef eitthvað stöðvar ferlið sem og til að fá staðfest formlega að óskað sé eftir að íbúðarhúsnæði verði keypt af ríkinu.', - description: 'Introduction text', - }, }), dataProviders: defineMessages({ nationalRegistryTitle: { diff --git a/libs/application/templates/health-insurance-declaration/src/utils/data.ts b/libs/application/templates/health-insurance-declaration/src/utils/data.ts index 4a15397f2926..392d63665dec 100644 --- a/libs/application/templates/health-insurance-declaration/src/utils/data.ts +++ b/libs/application/templates/health-insurance-declaration/src/utils/data.ts @@ -59,6 +59,21 @@ export const getCountryNameFromCode = ( return '' } +export const hasFamilyAvailable = (answers: HealthInsuranceDeclaration) => { + return answers.hasSpouse || answers.hasChildren +} + +export const hasFamilySelected = (answers: HealthInsuranceDeclaration) => { + return !!( + (answers.selectedApplicants?.registerPersonsSpouseCheckboxField && + answers.selectedApplicants?.registerPersonsSpouseCheckboxField?.length > + 0) || + (answers.selectedApplicants?.registerPersonsChildrenCheckboxField && + answers.selectedApplicants?.registerPersonsChildrenCheckboxField?.length > + 0) + ) +} + export const getContinentNameFromCode = ( code: string, externalData: ExternalData, @@ -145,27 +160,37 @@ export const getSelectedFamily = ( if (spouse) { selectedFamily = selectedFamily.concat( - answers.registerPersonsSpouseCheckboxField.map((s) => { - if (s === spouse.nationalId) { - return [ - spouse.name, - spouse.nationalId, - m.overview.familyTableRelationSpouseText, - ] - } else return [] - }), + answers.selectedApplicants?.registerPersonsSpouseCheckboxField + ? answers.selectedApplicants?.registerPersonsSpouseCheckboxField?.map( + (s) => { + if (s === spouse.nationalId) { + return [ + spouse.name, + spouse.nationalId, + m.overview.familyTableRelationSpouseText, + ] + } else return [] + }, + ) + : [], ) } - selectedFamily = selectedFamily.concat( - answers.registerPersonsChildrenCheckboxField.map((childNationalId) => { - const childData = children.find((c) => c.nationalId === childNationalId) - return [ - childData ? childData.fullName : '', - childData ? childData.nationalId : '', - m.overview.familyTableRelationChildText, - ] - }), - ) + + const selectedChildren = + answers.selectedApplicants?.registerPersonsChildrenCheckboxField?.map( + (childNationalId) => { + const childData = children.find((c) => c.nationalId === childNationalId) + return [ + childData ? childData.fullName : '', + childData ? childData.nationalId : '', + m.overview.familyTableRelationChildText, + ] + }, + ) + + if (selectedChildren) { + selectedFamily.concat(selectedChildren) + } return selectedFamily } diff --git a/libs/application/types/src/lib/template-api/shared-api/shared-api-definitions/health-insurance-api.ts b/libs/application/types/src/lib/template-api/shared-api/shared-api-definitions/health-insurance-api.ts index fbda4fbb8ac9..6be646c24814 100644 --- a/libs/application/types/src/lib/template-api/shared-api/shared-api-definitions/health-insurance-api.ts +++ b/libs/application/types/src/lib/template-api/shared-api/shared-api-definitions/health-insurance-api.ts @@ -13,6 +13,8 @@ export const HealthCenterApi = defineTemplateApi({ export const HealthInsuranceStatementsApi = defineTemplateApi({ action: 'getInsuranceStatementData', + order: 1, + throwOnError: true, namespace: 'HealthInsuranceDeclaration', externalDataId: 'insuranceStatementData', })