diff --git a/libs/application/template-api-modules/src/lib/modules/templates/aosh/street-registration/street-registration.service.ts b/libs/application/template-api-modules/src/lib/modules/templates/aosh/street-registration/street-registration.service.ts index 8d9512b5afd7..faf9bc8e602c 100644 --- a/libs/application/template-api-modules/src/lib/modules/templates/aosh/street-registration/street-registration.service.ts +++ b/libs/application/template-api-modules/src/lib/modules/templates/aosh/street-registration/street-registration.service.ts @@ -3,7 +3,7 @@ import { SharedTemplateApiService } from '../../../shared' import { TemplateApiModuleActionProps } from '../../../../types' import { ApplicationTypes } from '@island.is/application/types' import { BaseTemplateApiService } from '../../../base-template-api.service' - +import { error as errorMsg } from '@island.is/application/templates/aosh/street-registration' import { TemplateApiError } from '@island.is/nest/problem' import { coreErrorMessages } from '@island.is/application/core' import { StreetRegistrationAnswers } from '@island.is/application/templates/aosh/street-registration' @@ -61,9 +61,41 @@ export class StreetRegistrationTemplateService extends BaseTemplateApiService { async getTypesMustInspectBeforeRegistration({ auth, }: TemplateApiModuleActionProps): Promise { - return await this.workMachineClientService.mustInspectBeforeRegistration( - auth, - ) + return await this.workMachineClientService + .mustInspectBeforeRegistration(auth) + .catch((error) => { + this.logger.warning( + '[street-registration-service]: Error fetching types requires for inspection', + error, + ) + throw new TemplateApiError( + { + title: coreErrorMessages.defaultTemplateApiError, + summary: errorMsg.errorGetFromAOSH, + }, + 500, + ) + }) + } + + async getAvailableRegistrationTypes({ + auth, + }: TemplateApiModuleActionProps): Promise { + return await this.workMachineClientService + .getAvailableRegistrationTypes(auth) + .catch((error) => { + this.logger.warning( + '[street-registration-service]: Error fetching available types for registration', + error, + ) + throw new TemplateApiError( + { + title: coreErrorMessages.defaultTemplateApiError, + summary: errorMsg.errorGetFromAOSH, + }, + 500, + ) + }) } async submitApplication({ diff --git a/libs/application/templates/aosh/register-new-machine/src/index.ts b/libs/application/templates/aosh/register-new-machine/src/index.ts index 2e527d7f65bc..299df2f313a9 100644 --- a/libs/application/templates/aosh/register-new-machine/src/index.ts +++ b/libs/application/templates/aosh/register-new-machine/src/index.ts @@ -3,7 +3,7 @@ import RegisterNewMachineTemplate from './lib/RegisterNewMachineTemplate' export const getDataProviders = () => import('./dataProviders/') export const getFields = () => import('./fields/') -export { NewMachineAnswers } from './lib/dataSchema' +export type { NewMachineAnswers } from './lib/dataSchema' export * from './utils' export * from './shared/types' diff --git a/libs/application/templates/aosh/street-registration/src/dataProviders/index.ts b/libs/application/templates/aosh/street-registration/src/dataProviders/index.ts index 12d03fb3687f..7561f04b4c33 100644 --- a/libs/application/templates/aosh/street-registration/src/dataProviders/index.ts +++ b/libs/application/templates/aosh/street-registration/src/dataProviders/index.ts @@ -16,6 +16,11 @@ export const MustInspectBeforeRegistrationApi = defineTemplateApi({ externalDataId: 'typesMustInspectBeforeRegistration', }) +export const GetAvailableRegistrationTypes = defineTemplateApi({ + action: 'getAvailableRegistrationTypes', + externalDataId: 'availableRegistrationTypes', +}) + export const VinnueftirlitidPaymentCatalogApi = PaymentCatalogApi.configure({ params: { organizationId: InstitutionNationalIds.SAMGONGUSTOFA, diff --git a/libs/application/templates/aosh/street-registration/src/forms/StreetRegistrationForm/InformationSection/pickMachineSubSection.ts b/libs/application/templates/aosh/street-registration/src/forms/StreetRegistrationForm/InformationSection/pickMachineSubSection.ts index b59d0ab2c99b..a3f832323a64 100644 --- a/libs/application/templates/aosh/street-registration/src/forms/StreetRegistrationForm/InformationSection/pickMachineSubSection.ts +++ b/libs/application/templates/aosh/street-registration/src/forms/StreetRegistrationForm/InformationSection/pickMachineSubSection.ts @@ -6,10 +6,36 @@ import { getValueViaPath, } from '@island.is/application/core' import { information } from '../../../lib/messages' -import { MachinesWithTotalCount } from '@island.is/clients/work-machines' -import { mustInspectBeforeStreetRegistration } from '../../../utils/getSelectedMachine' +import { + MachineDto, + MachinesWithTotalCount, +} from '@island.is/clients/work-machines' +import { + isInvalidRegistrationType, + isMachineDisabled, + mustInspectBeforeStreetRegistration, +} from '../../../utils/getSelectedMachine' import { useLocale } from '@island.is/localization' -import { Application } from '@island.is/application/types' +import { ExternalData } from '@island.is/application/types' +import { MessageDescriptor } from 'react-intl' + +const getTagLabel = ( + externalData: ExternalData, + machine: MachineDto, + formatMessage: (message: MessageDescriptor) => string, +): string => { + if ( + mustInspectBeforeStreetRegistration(externalData, machine?.regNumber || '') + ) { + return formatMessage( + information.labels.pickMachine.inspectBeforeRegistration, + ) + } + if (isInvalidRegistrationType(externalData, machine?.regNumber || '')) { + return formatMessage(information.labels.pickMachine.invalidRegistrationType) + } + return machine?.status || '' +} export const pickMachineSubSection = buildSubSection({ id: 'pickMachine', @@ -31,14 +57,11 @@ export const pickMachineSubSection = buildSubSection({ ) as MachinesWithTotalCount return machines.totalCount <= 5 }, - defaultValue: (application: Application) => { - const machineList = application?.externalData.machinesList - .data as MachinesWithTotalCount - return machineList?.machines[0].id ?? '' - }, + options: (application) => { const machineList = application?.externalData.machinesList .data as MachinesWithTotalCount + const externalData = application.externalData return machineList.machines.map((machine) => { return { @@ -47,25 +70,21 @@ export const pickMachineSubSection = buildSubSection({ subLabel: `${machine.category}: ${machine.type} - ${machine.subType}`, disabled: machine?.disabled ? true - : mustInspectBeforeStreetRegistration( - application?.externalData, - machine?.regNumber || '', - ) || false, - tag: machine?.disabled - ? { - label: mustInspectBeforeStreetRegistration( - application?.externalData, - machine?.regNumber || '', - ) - ? useLocale().formatMessage( - information.labels.pickMachine - .inspectBeforeRegistration, - ) - : machine?.status || '', - variant: 'red', - outlined: true, - } - : undefined, + : isMachineDisabled(externalData, machine?.regNumber || '') || + false, + tag: + machine?.disabled || + isMachineDisabled(externalData, machine?.regNumber || '') + ? { + label: getTagLabel( + externalData, + machine, + useLocale().formatMessage, + ), + variant: 'red', + outlined: true, + } + : undefined, } }) }, diff --git a/libs/application/templates/aosh/street-registration/src/forms/StreetRegistrationForm/prerequisitesSection.ts b/libs/application/templates/aosh/street-registration/src/forms/StreetRegistrationForm/prerequisitesSection.ts index e40bb4f940eb..0bc27da313bf 100644 --- a/libs/application/templates/aosh/street-registration/src/forms/StreetRegistrationForm/prerequisitesSection.ts +++ b/libs/application/templates/aosh/street-registration/src/forms/StreetRegistrationForm/prerequisitesSection.ts @@ -12,6 +12,7 @@ import { MachinesApi, MustInspectBeforeRegistrationApi, VinnueftirlitidPaymentCatalogApi, + GetAvailableRegistrationTypes, } from '../../dataProviders' import { DefaultEvents } from '@island.is/application/types' @@ -58,6 +59,11 @@ export const prerequisitesSection = buildSection({ title: '', subTitle: '', }), + buildDataProviderItem({ + provider: GetAvailableRegistrationTypes, + title: '', + subTitle: '', + }), buildDataProviderItem({ provider: VinnueftirlitidPaymentCatalogApi, title: '', diff --git a/libs/application/templates/aosh/street-registration/src/index.ts b/libs/application/templates/aosh/street-registration/src/index.ts index 9225f3d712fa..87f142c43a78 100644 --- a/libs/application/templates/aosh/street-registration/src/index.ts +++ b/libs/application/templates/aosh/street-registration/src/index.ts @@ -9,4 +9,5 @@ export type StreetRegistrationAnswers = MachineAnswers export * from './utils' export * from './lib/messages/externalData' export * from './lib/messages/applicationCheck' +export * from './lib/messages/error' export default template diff --git a/libs/application/templates/aosh/street-registration/src/lib/StreetRegistrationTemplate.ts b/libs/application/templates/aosh/street-registration/src/lib/StreetRegistrationTemplate.ts index ebdc72f7c725..5af899f8dbae 100644 --- a/libs/application/templates/aosh/street-registration/src/lib/StreetRegistrationTemplate.ts +++ b/libs/application/templates/aosh/street-registration/src/lib/StreetRegistrationTemplate.ts @@ -30,6 +30,7 @@ import { MachinesApi, MustInspectBeforeRegistrationApi, VinnueftirlitidPaymentCatalogApi, + GetAvailableRegistrationTypes, } from '../dataProviders' import { ApiScope } from '@island.is/auth/scopes' import { getChargeItems } from '../utils' @@ -111,6 +112,7 @@ const template: ApplicationTemplate< UserProfileApi, MachinesApi, MustInspectBeforeRegistrationApi, + GetAvailableRegistrationTypes, VinnueftirlitidPaymentCatalogApi, ], }, diff --git a/libs/application/templates/aosh/street-registration/src/lib/dataSchema.ts b/libs/application/templates/aosh/street-registration/src/lib/dataSchema.ts index 92a83e93b185..d7c65744894f 100644 --- a/libs/application/templates/aosh/street-registration/src/lib/dataSchema.ts +++ b/libs/application/templates/aosh/street-registration/src/lib/dataSchema.ts @@ -12,16 +12,18 @@ const otherAddressSchema = z.object({ }) export const MachineAnswersSchema = z.object({ - machine: z.object({ - id: z.string().optional(), - date: z.string().optional(), - type: z.string().optional(), - plate: z.string().optional(), - subType: z.string().optional(), - category: z.string().optional(), - regNumber: z.string().optional(), - ownerNumber: z.string().optional(), - }), + machine: z + .object({ + id: z.string().optional(), + date: z.string().optional(), + type: z.string().optional(), + plate: z.string().optional(), + subType: z.string().optional(), + category: z.string().optional(), + regNumber: z.string().optional(), + ownerNumber: z.string().optional(), + }) + .refine((obj) => Object.keys(obj).length > 0), contact: z.object({ name: z.string().min(1), email: z.string().email().min(1), diff --git a/libs/application/templates/aosh/street-registration/src/lib/messages/applicationCheck.ts b/libs/application/templates/aosh/street-registration/src/lib/messages/applicationCheck.ts index eda53d8bc456..7e6ab37bdba3 100644 --- a/libs/application/templates/aosh/street-registration/src/lib/messages/applicationCheck.ts +++ b/libs/application/templates/aosh/street-registration/src/lib/messages/applicationCheck.ts @@ -17,5 +17,10 @@ export const applicationCheck = { defaultMessage: 'Hafið samband við Vinnueftirlitið til að götuskrá', description: 'Pick machine inspect before registration', }, + unavailableTypeForRegistration: { + id: 'aosh.sr.application:applicationCheck.validation.unavailableTypeForRegistration', + defaultMessage: 'Ekki er hægt að götuskrá tæki í þessum flokk', + description: 'Pick machine has type that is not valid for registration', + }, }), } diff --git a/libs/application/templates/aosh/street-registration/src/lib/messages/error.ts b/libs/application/templates/aosh/street-registration/src/lib/messages/error.ts index 400950c7ee9e..0e4b07ad7a69 100644 --- a/libs/application/templates/aosh/street-registration/src/lib/messages/error.ts +++ b/libs/application/templates/aosh/street-registration/src/lib/messages/error.ts @@ -43,4 +43,9 @@ export const error = defineMessages({ defaultMessage: 'Villa kom upp við að skila inn umsókn', description: 'Failed to submit application', }, + errorGetFromAOSH: { + id: 'aosh.sr.application:error.errorGetFromAOSH', + defaultMessage: 'Ekki tókst að sækja gögn frá Vinnueftirlitinu', + description: 'Failed to fetch data from AOSH', + }, }) diff --git a/libs/application/templates/aosh/street-registration/src/lib/messages/information.ts b/libs/application/templates/aosh/street-registration/src/lib/messages/information.ts index c0efe3526d81..b456a3e34f19 100644 --- a/libs/application/templates/aosh/street-registration/src/lib/messages/information.ts +++ b/libs/application/templates/aosh/street-registration/src/lib/messages/information.ts @@ -82,6 +82,11 @@ export const information = { defaultMessage: 'Hafið samband við Vinnueftirlitið til að götuskrá', description: 'Pick machine inspect before registration', }, + invalidRegistrationType: { + id: 'aosh.sr.application:information.labels.pickMachine.invalidRegistrationType', + defaultMessage: 'Ekki er hægt að götuskrá tæki í þessum flokk', + description: 'Pick machine invalid registration type tag', + }, }), machine: defineMessages({ sectionTitle: { diff --git a/libs/application/templates/aosh/street-registration/src/utils/getSelectedMachine.ts b/libs/application/templates/aosh/street-registration/src/utils/getSelectedMachine.ts index e1a151103faa..5f4c38295095 100644 --- a/libs/application/templates/aosh/street-registration/src/utils/getSelectedMachine.ts +++ b/libs/application/templates/aosh/street-registration/src/utils/getSelectedMachine.ts @@ -37,6 +37,7 @@ export const mustInspectBeforeStreetRegistration = ( 'typesMustInspectBeforeRegistration.data', [], ) as string[] + return inspectBeforeTypes?.includes(regNumber.substring(0, 2)) || false } @@ -47,3 +48,41 @@ export const getExtraData = (application: ApplicationType): ExtraData[] => { { name: 'date', value: streetAnswers.machine?.date || '' }, ] } + +export const isInvalidRegistrationType = ( + externalData: ExternalData, + regNumber: string, +) => { + const validTypes = getValueViaPath( + externalData, + 'availableRegistrationTypes.data', + [], + ) + const inspectBeforeTypes = getValueViaPath( + externalData, + 'typesMustInspectBeforeRegistration.data', + [], + ) + + const regType = regNumber.substring(0, 2) + + return ( + !validTypes?.includes(regType) && !inspectBeforeTypes?.includes(regType) + ) +} + +export const isMachineDisabled = ( + externalData: ExternalData, + regNumber: string, +): boolean => { + const validTypes = getValueViaPath( + externalData, + 'availableRegistrationTypes.data', + [], + ) + + const regType = regNumber.substring(0, 2) + + // Checks the machine type against the available registration types + return !validTypes?.includes(regType) +} diff --git a/libs/application/ui-fields/src/lib/FindVehicleFormField/FindVehicleFormField.tsx b/libs/application/ui-fields/src/lib/FindVehicleFormField/FindVehicleFormField.tsx index d1a8402df506..731106e4bf78 100644 --- a/libs/application/ui-fields/src/lib/FindVehicleFormField/FindVehicleFormField.tsx +++ b/libs/application/ui-fields/src/lib/FindVehicleFormField/FindVehicleFormField.tsx @@ -27,6 +27,7 @@ import format from 'date-fns/format' import { formatCurrency } from '@island.is/application/ui-components' import { energyFundsLabel, + isInvalidRegistrationType, mustInspectBeforeStreetRegistration, } from './FindVehicleFormField.util' @@ -159,8 +160,6 @@ export const FindVehicleFormField: FC> = ({ isMachine, isEnergyFunds, energyFundsMessages, - marginTop, - marginBottom, clearOnChange, } = field @@ -268,21 +267,30 @@ export const FindVehicleFormField: FC> = ({ const machineDisabled = machineDetails.disabled if (application.typeId === 'StreetRegistration') { + const isUnavailableTypeForRegistration = isInvalidRegistrationType( + application?.externalData, + machineDetails.regNumber || '', + ) const mustInspect = mustInspectBeforeStreetRegistration( application?.externalData, machineDetails.regNumber || '', ) - if (mustInspect && !machineDisabled) { + const statusKey = mustInspect + ? 'inspectBeforeRegistration' + : isUnavailableTypeForRegistration + ? 'unavailableTypeForRegistration' + : null + + if ( + statusKey === 'inspectBeforeRegistration' || + statusKey === 'unavailableTypeForRegistration' + ) { machineDetails = { ...machineDetails, disabled: true, status: validationErrors && - formatText( - validationErrors.inspectBeforeRegistration, - application, - formatMessage, - ), + formatText(validationErrors[statusKey], application, formatMessage), } } } diff --git a/libs/application/ui-fields/src/lib/FindVehicleFormField/FindVehicleFormField.util.ts b/libs/application/ui-fields/src/lib/FindVehicleFormField/FindVehicleFormField.util.ts index b604c94ec68b..f788511fe4b1 100644 --- a/libs/application/ui-fields/src/lib/FindVehicleFormField/FindVehicleFormField.util.ts +++ b/libs/application/ui-fields/src/lib/FindVehicleFormField/FindVehicleFormField.util.ts @@ -8,6 +8,8 @@ import { } from '@island.is/application/types' import { MessageDescriptor } from 'react-intl' +const REGISTRATION_TYPE_LENGTH = 2 + export const energyFundsLabel = function ( energyDetails: EnergyFundVehicleDetailsWithGrant | null, energyFundsMessages: Record | undefined, @@ -44,10 +46,39 @@ export const mustInspectBeforeStreetRegistration = ( externalData: ExternalData, regNumber: string, ) => { - const inspectBeforeTypes = getValueViaPath( + const inspectBeforeTypes = getValueViaPath( + externalData, + 'typesMustInspectBeforeRegistration.data', + [], + ) + return ( + inspectBeforeTypes?.includes( + regNumber.substring(0, REGISTRATION_TYPE_LENGTH), + ) || false + ) +} + +export const isInvalidRegistrationType = ( + externalData: ExternalData, + regNumber: string, +) => { + if (!regNumber || regNumber.length < REGISTRATION_TYPE_LENGTH) { + return true + } + const validTypes = getValueViaPath( + externalData, + 'availableRegistrationTypes.data', + [], + ) + const inspectBeforeTypes = getValueViaPath( externalData, 'typesMustInspectBeforeRegistration.data', [], - ) as string[] - return inspectBeforeTypes?.includes(regNumber.substring(0, 2)) || false + ) + + const regType = regNumber.substring(0, REGISTRATION_TYPE_LENGTH) + + return ( + !validTypes?.includes(regType) && !inspectBeforeTypes?.includes(regType) + ) } diff --git a/libs/clients/work-machines/src/lib/workMachines.service.ts b/libs/clients/work-machines/src/lib/workMachines.service.ts index ba1a730d4b75..bf38e22137d1 100644 --- a/libs/clients/work-machines/src/lib/workMachines.service.ts +++ b/libs/clients/work-machines/src/lib/workMachines.service.ts @@ -302,6 +302,12 @@ export class WorkMachinesClientService { ).apiMachineStreetRegistrationMustInspectBeforeRegistrationGet({}) } + async getAvailableRegistrationTypes(auth: Auth) { + return await this.machineStreetApiWithAuth( + auth, + ).apiMachineStreetRegistrationMayStreetRegisterGet({}) + } + async getMachineTypes(auth: Auth): Promise { return await this.machineTypesApiWithAuth(auth).apiMachineTypesGet({}) }