diff --git a/libs/api/domains/energy-funds/src/lib/energyFunds.service.ts b/libs/api/domains/energy-funds/src/lib/energyFunds.service.ts index 0cb734c2dbf3..fb2f7c9658e3 100644 --- a/libs/api/domains/energy-funds/src/lib/energyFunds.service.ts +++ b/libs/api/domains/energy-funds/src/lib/energyFunds.service.ts @@ -55,38 +55,43 @@ export class EnergyFundsService { } async getVehicleDetailsWithGrant(auth: User, permno: string) { - const vehicle = await this.vehiclesApiWithAuth( + // Get current vehicle information where you are (main) owner + const result = await this.vehiclesApiWithAuth( + auth, + ).currentvehicleswithmileageandinspGet({ + permno: permno, + showOwned: true, + showCoowned: false, + showOperated: false, + }) + + const basicVehicle = await this.vehiclesApiWithAuth( auth, ).basicVehicleInformationGet({ permno: permno }) - if (!vehicle) { - throw Error( - 'Did not find the vehicle with for that permno, or you are neither owner nor co-owner of the vehicle', - ) - } - if ( - vehicle.owners && - !vehicle.owners.some((owner) => owner.persidno === auth.nationalId) - ) { + + if (!result || !result.data || result.data.length === 0 || !basicVehicle) { throw Error( - 'Did not find the vehicle with for that permno, or you are neither owner nor co-owner of the vehicle', + 'Did not find the vehicle with that permno, or you are not owner of the vehicle', ) } + const vehicle = result.data[0] + const vehicleGrantItem = await this.energyFundsClientService.getCatalogValueForVehicle(auth, { - vehicleRegistrationCode: vehicle.euGroup, - firstRegistrationDate: vehicle.firstregdate, - newRegistrationDate: vehicle.newregdate, + vehicleRegistrationCode: basicVehicle.euGroup, + firstRegistrationDate: basicVehicle.firstregdate, + newRegistrationDate: basicVehicle.newregdate, permno: vehicle.permno, }) if (!vehicleGrantItem) throw new Error('Could not get available grants for this vehicle') - const hasReceivedSubsidy = vehicle.vin + const hasReceivedSubsidy = basicVehicle.vin ? await this.energyFundsClientService.checkVehicleSubsidyAvilability( auth, - vehicle.vin, + basicVehicle.vin, ) : false @@ -96,11 +101,11 @@ export class EnergyFundsService { hasReceivedSubsidy, permno: vehicle.permno, make: vehicle.make, - color: vehicle.color, + color: vehicle.colorName, requireMileage: vehicle.requiresMileageRegistration, - newRegistrationDate: vehicle.newregdate, - firstRegistrationDate: vehicle.firstregdate, - vin: vehicle.vin, + newRegistrationDate: basicVehicle.newregdate, + firstRegistrationDate: basicVehicle.firstregdate, + vin: basicVehicle.vin, } } } diff --git a/libs/api/domains/transport-authority/src/lib/transportAuthority.service.ts b/libs/api/domains/transport-authority/src/lib/transportAuthority.service.ts index f2936cf1a24d..f2fee3b09a5f 100644 --- a/libs/api/domains/transport-authority/src/lib/transportAuthority.service.ts +++ b/libs/api/domains/transport-authority/src/lib/transportAuthority.service.ts @@ -25,6 +25,7 @@ import { } from './graphql/models' import { ApolloError } from 'apollo-server-express' import { CoOwnerChangeAnswers } from './graphql/dto/coOwnerChangeAnswers.input' +import { MileageReadingApi } from '@island.is/clients/vehicles-mileage' @Injectable() export class TransportAuthorityApi { @@ -36,12 +37,17 @@ export class TransportAuthorityApi { private readonly vehiclePlateRenewalClient: VehiclePlateRenewalClient, private readonly vehicleServiceFjsV1Client: VehicleServiceFjsV1Client, private readonly vehiclesApi: VehicleSearchApi, + private readonly mileageReadingApi: MileageReadingApi, ) {} private vehiclesApiWithAuth(auth: Auth) { return this.vehiclesApi.withMiddleware(new AuthMiddleware(auth)) } + private mileageReadingApiWithAuth(auth: Auth) { + return this.mileageReadingApi.withMiddleware(new AuthMiddleware(auth)) + } + async checkTachoNet( user: User, input: CheckTachoNetInput, @@ -55,25 +61,29 @@ export class TransportAuthorityApi { return { exists: hasActiveCard } } - private isOwnerOrCoOwner( - vehicle: BasicVehicleInformationDto, - auth: Auth, - ): boolean { - if (vehicle.owners) { - for (const owner of vehicle.owners) { - if (owner.persidno === auth.nationalId) { - return true - } - if (owner.coOwners) { - for (const coOwner of owner.coOwners) { - if (coOwner.persidno === auth.nationalId) { - return true - } - } - } - } + private async fetchVehicleDataForOwnerCoOwner(auth: User, permno: string) { + const result = await this.vehiclesApiWithAuth( + auth, + ).currentvehicleswithmileageandinspGet({ + permno: permno, + showOwned: true, + showCoowned: true, + showOperated: false, + }) + if (!result || !result.data || result.data.length === 0) { + throw Error( + 'Did not find the vehicle with that permno, or you are neither owner nor co-owner of the vehicle', + ) } - return false + + const vehicle = result.data[0] + + // Get mileage reading + const mileageReadings = await this.mileageReadingApiWithAuth( + auth, + ).getMileageReading({ permno: permno }) + + return { vehicle, mileageReadings } } async getVehicleOwnerchangeChecksByPermno( @@ -82,19 +92,8 @@ export class TransportAuthorityApi { ): Promise { // Make sure user is only fetching information for vehicles where he is either owner or co-owner // (mainly debt status info that is sensitive) - const vehicle = await this.vehiclesApiWithAuth( - auth, - ).basicVehicleInformationGet({ permno: permno }) - if (!vehicle) { - throw Error( - 'Did not find the vehicle with for that permno, or you are neither owner nor co-owner of the vehicle', - ) - } - if (!this.isOwnerOrCoOwner(vehicle, auth)) { - throw Error( - 'Did not find the vehicle with for that permno, or you are neither owner nor co-owner of the vehicle', - ) - } + const { vehicle, mileageReadings } = + await this.fetchVehicleDataForOwnerCoOwner(auth, permno) // Get debt status const debtStatus = @@ -106,18 +105,19 @@ export class TransportAuthorityApi { auth, permno, ) + return { - isDebtLess: debtStatus.isDebtLess, - validationErrorMessages: ownerChangeValidation?.hasError - ? ownerChangeValidation.errorMessages - : null, basicVehicleInformation: { permno: vehicle.permno, - make: `${vehicle.make} ${vehicle.vehcom}`, - color: vehicle.color, + make: vehicle.make, + color: vehicle.colorName, requireMileage: vehicle.requiresMileageRegistration, - mileageReading: vehicle?.mileageReadings?.[0]?.mileage || '', + mileageReading: mileageReadings?.[0]?.mileage?.toString() ?? '', }, + isDebtLess: debtStatus.isDebtLess, + validationErrorMessages: ownerChangeValidation?.hasError + ? ownerChangeValidation.errorMessages + : null, } } @@ -258,19 +258,8 @@ export class TransportAuthorityApi { ): Promise { // Make sure user is only fetching information for vehicles where he is either owner or co-owner // (mainly debt status info that is sensitive) - const vehicle = await this.vehiclesApiWithAuth( - auth, - ).basicVehicleInformationGet({ permno: permno }) - if (!vehicle) { - throw Error( - 'Did not find the vehicle with for that permno, or you are neither owner nor co-owner of the vehicle', - ) - } - if (!this.isOwnerOrCoOwner(vehicle, auth)) { - throw Error( - 'Did not find the vehicle with for that permno, or you are neither owner nor co-owner of the vehicle', - ) - } + const { vehicle, mileageReadings } = + await this.fetchVehicleDataForOwnerCoOwner(auth, permno) // Get debt status const debtStatus = @@ -289,11 +278,11 @@ export class TransportAuthorityApi { ? operatorChangeValidation.errorMessages : null, basicVehicleInformation: { - color: vehicle.color, - make: `${vehicle.make} ${vehicle.vehcom}`, + color: vehicle.colorName, + make: vehicle.make, permno: vehicle.permno, requireMileage: vehicle.requiresMileageRegistration, - mileageReading: vehicle?.mileageReadings?.[0]?.mileage || '', + mileageReading: mileageReadings?.[0]?.mileage?.toString() ?? '', }, } } @@ -373,8 +362,6 @@ export class TransportAuthorityApi { color: vehicleInfo.color, make: `${vehicleInfo.make} ${vehicleInfo.vehcom}`, permno: vehicleInfo.permno, - requireMileage: vehicleInfo.requiresMileageRegistration, - mileageReading: vehicleInfo?.mileageReadings?.[0]?.mileage || '', }, } } diff --git a/libs/application/template-api-modules/src/lib/modules/templates/transport-authority/change-co-owner-of-vehicle/change-co-owner-of-vehicle.service.ts b/libs/application/template-api-modules/src/lib/modules/templates/transport-authority/change-co-owner-of-vehicle/change-co-owner-of-vehicle.service.ts index 3b75a3530164..d2736498d3a8 100644 --- a/libs/application/template-api-modules/src/lib/modules/templates/transport-authority/change-co-owner-of-vehicle/change-co-owner-of-vehicle.service.ts +++ b/libs/application/template-api-modules/src/lib/modules/templates/transport-authority/change-co-owner-of-vehicle/change-co-owner-of-vehicle.service.ts @@ -16,7 +16,10 @@ import { VehicleDebtStatus, VehicleServiceFjsV1Client, } from '@island.is/clients/vehicle-service-fjs-v1' -import { VehicleSearchApi } from '@island.is/clients/vehicles' +import { + CurrentVehiclesWithMilageAndNextInspDto, + VehicleSearchApi, +} from '@island.is/clients/vehicles' import { MileageReadingApi, MileageReadingDto, @@ -44,9 +47,8 @@ import { } from './smsGenerators' import { LOGGER_PROVIDER } from '@island.is/logging' import type { Logger } from '@island.is/logging' -import { Auth, AuthMiddleware } from '@island.is/auth-nest-tools' +import { Auth, AuthMiddleware, User } from '@island.is/auth-nest-tools' import { coreErrorMessages } from '@island.is/application/core' -import { VehicleCodetablesClient } from '@island.is/clients/transport-authority/vehicle-codetables' @Injectable() export class ChangeCoOwnerOfVehicleService extends BaseTemplateApiService { @@ -55,7 +57,6 @@ export class ChangeCoOwnerOfVehicleService extends BaseTemplateApiService { private readonly sharedTemplateAPIService: SharedTemplateApiService, private readonly vehicleOwnerChangeClient: VehicleOwnerChangeClient, private readonly vehicleOperatorsClient: VehicleOperatorsClient, - private readonly vehicleCodetablesClient: VehicleCodetablesClient, private readonly chargeFjsV2ClientService: ChargeFjsV2ClientService, private readonly vehicleServiceFjsV1Client: VehicleServiceFjsV1Client, private readonly vehiclesApi: VehicleSearchApi, @@ -75,6 +76,7 @@ export class ChangeCoOwnerOfVehicleService extends BaseTemplateApiService { async getCurrentVehiclesWithOwnerchangeChecks({ auth, }: TemplateApiModuleActionProps) { + // Get total count of vehicles const countResult = ( await this.vehiclesApiWithAuth( @@ -87,78 +89,101 @@ export class ChangeCoOwnerOfVehicleService extends BaseTemplateApiService { pageSize: 1, }) ).totalRecords || 0 - if (countResult && countResult > 20) { + + // Validate that user has at least 1 vehicle + if (!countResult) { + throw new TemplateApiError( + { + title: coreErrorMessages.vehiclesEmptyListOwner, + summary: coreErrorMessages.vehiclesEmptyListOwner, + }, + 400, + ) + } + + // A. vehicleCount > 20 + // Display search box, validate vehicle when permno is entered + if (countResult > 20) { return { totalRecords: countResult, vehicles: [], } } - const result = await this.vehiclesApiWithAuth(auth).currentVehiclesGet({ - persidNo: auth.nationalId, + + // Get all vehicles + const result = await this.vehiclesApiWithAuth( + auth, + ).currentvehicleswithmileageandinspGet({ showOwned: true, showCoowned: false, showOperated: false, }) - // Validate that user has at least 1 vehicle - if (!result || !result.length) { - throw new TemplateApiError( - { - title: coreErrorMessages.vehiclesEmptyListOwner, - summary: coreErrorMessages.vehiclesEmptyListOwner, - }, - 400, + const resultData = result.data || [] + + const vehicles = await Promise.all( + resultData.map(async (vehicle) => { + // B. 20 >= vehicleCount > 5 + // Display dropdown, validate vehicle when selected in dropdown + if (countResult > 5) { + return this.mapVehicle(auth, vehicle, false) + } + + // C. vehicleCount <= 5 + // Display radio buttons, validate all vehicles now + return this.mapVehicle(auth, vehicle, true) + }), + ) + + return { + totalRecords: countResult, + vehicles: vehicles, + } + } + + private async mapVehicle( + auth: User, + vehicle: CurrentVehiclesWithMilageAndNextInspDto, + fetchExtraData: boolean, + ) { + let validation: OwnerChangeValidation | undefined + let debtStatus: VehicleDebtStatus | undefined + let mileageReadings: MileageReadingDto[] | undefined + + if (fetchExtraData) { + // Get debt status + debtStatus = await this.vehicleServiceFjsV1Client.getVehicleDebtStatus( + auth, + vehicle.permno || '', ) + + // Get owner change validation + validation = + await this.vehicleOwnerChangeClient.validateVehicleForOwnerChange( + auth, + vehicle.permno || '', + ) + + // Get mileage reading + mileageReadings = await this.mileageReadingApiWithAuth( + auth, + ).getMileageReading({ permno: vehicle.permno || '' }) } return { - totalRecords: countResult, - vehicles: await Promise.all( - result?.map(async (vehicle) => { - let validation: OwnerChangeValidation | undefined - let debtStatus: VehicleDebtStatus | undefined - let mileageReadings: MileageReadingDto[] | undefined - - // Only validate if fewer than 5 items - if (result.length <= 5) { - // Get debt status - debtStatus = - await this.vehicleServiceFjsV1Client.getVehicleDebtStatus( - auth, - vehicle.permno || '', - ) - - // Get validation - validation = - await this.vehicleOwnerChangeClient.validateVehicleForOwnerChange( - auth, - vehicle.permno || '', - ) - - mileageReadings = await this.mileageReadingApiWithAuth( - auth, - ).getMileageReading({ permno: vehicle.permno || '' }) - } - - const electricFuelCodes = - this.vehicleCodetablesClient.getElectricFueldCodes() - - return { - permno: vehicle.permno || undefined, - make: vehicle.make || undefined, - color: vehicle.color || undefined, - role: vehicle.role || undefined, - requireMileage: electricFuelCodes.includes(vehicle.fuelCode || ''), - mileageReading: (mileageReadings?.[0]?.mileage ?? '').toString(), - isDebtLess: debtStatus?.isDebtLess, - validationErrorMessages: validation?.hasError - ? validation.errorMessages - : null, - } - }), - ), + permno: vehicle.permno || undefined, + make: vehicle.make || undefined, + color: vehicle.colorName || undefined, + role: vehicle.role || undefined, + requireMileage: vehicle.requiresMileageRegistration, + mileageReading: mileageReadings?.[0]?.mileage?.toString() ?? '', + isDebtLess: debtStatus?.isDebtLess, + validationErrorMessages: validation?.hasError + ? validation.errorMessages + : null, } } + async validateApplication({ application, auth, diff --git a/libs/application/template-api-modules/src/lib/modules/templates/transport-authority/change-operator-of-vehicle/change-operator-of-vehicle.service.ts b/libs/application/template-api-modules/src/lib/modules/templates/transport-authority/change-operator-of-vehicle/change-operator-of-vehicle.service.ts index 7bdc09ff081f..0ef9de4b1658 100644 --- a/libs/application/template-api-modules/src/lib/modules/templates/transport-authority/change-operator-of-vehicle/change-operator-of-vehicle.service.ts +++ b/libs/application/template-api-modules/src/lib/modules/templates/transport-authority/change-operator-of-vehicle/change-operator-of-vehicle.service.ts @@ -23,7 +23,10 @@ import { VehicleDebtStatus, VehicleServiceFjsV1Client, } from '@island.is/clients/vehicle-service-fjs-v1' -import { VehicleSearchApi } from '@island.is/clients/vehicles' +import { + CurrentVehiclesWithMilageAndNextInspDto, + VehicleSearchApi, +} from '@island.is/clients/vehicles' import { MileageReadingApi, MileageReadingDto, @@ -42,9 +45,8 @@ import { } from './smsGenerators' import { LOGGER_PROVIDER } from '@island.is/logging' import type { Logger } from '@island.is/logging' -import { Auth, AuthMiddleware } from '@island.is/auth-nest-tools' +import { Auth, AuthMiddleware, User } from '@island.is/auth-nest-tools' import { coreErrorMessages } from '@island.is/application/core' -import { VehicleCodetablesClient } from '@island.is/clients/transport-authority/vehicle-codetables' @Injectable() export class ChangeOperatorOfVehicleService extends BaseTemplateApiService { @@ -52,7 +54,6 @@ export class ChangeOperatorOfVehicleService extends BaseTemplateApiService { @Inject(LOGGER_PROVIDER) private logger: Logger, private readonly sharedTemplateAPIService: SharedTemplateApiService, private readonly vehicleOperatorsClient: VehicleOperatorsClient, - private readonly vehicleCodetablesClient: VehicleCodetablesClient, private readonly chargeFjsV2ClientService: ChargeFjsV2ClientService, private readonly vehicleOwnerChangeClient: VehicleOwnerChangeClient, private readonly vehicleServiceFjsV1Client: VehicleServiceFjsV1Client, @@ -73,6 +74,7 @@ export class ChangeOperatorOfVehicleService extends BaseTemplateApiService { async getCurrentVehiclesWithOperatorChangeChecks({ auth, }: TemplateApiModuleActionProps) { + // Get total count of vehicles const countResult = ( await this.vehiclesApiWithAuth( @@ -85,75 +87,98 @@ export class ChangeOperatorOfVehicleService extends BaseTemplateApiService { pageSize: 1, }) ).totalRecords || 0 - if (countResult && countResult > 20) { + + // Validate that user has at least 1 vehicle + if (!countResult) { + throw new TemplateApiError( + { + title: coreErrorMessages.vehiclesEmptyListOwner, + summary: coreErrorMessages.vehiclesEmptyListOwner, + }, + 400, + ) + } + + // A. vehicleCount > 20 + // Display search box, validate vehicle when permno is entered + if (countResult > 20) { return { totalRecords: countResult, vehicles: [], } } - const result = await this.vehiclesApiWithAuth(auth).currentVehiclesGet({ - persidNo: auth.nationalId, + + // Get all vehicles + const result = await this.vehiclesApiWithAuth( + auth, + ).currentvehicleswithmileageandinspGet({ showOwned: true, showCoowned: false, showOperated: false, }) - // Validate that user has at least 1 vehicle - if (!result || !result.length) { - throw new TemplateApiError( - { - title: coreErrorMessages.vehiclesEmptyListOwner, - summary: coreErrorMessages.vehiclesEmptyListOwner, - }, - 400, + const resultData = result.data || [] + + const vehicles = await Promise.all( + resultData.map(async (vehicle) => { + // B. 20 >= vehicleCount > 5 + // Display dropdown, validate vehicle when selected in dropdown + if (countResult > 5) { + return this.mapVehicle(auth, vehicle, false) + } + + // C. vehicleCount <= 5 + // Display radio buttons, validate all vehicles now + return this.mapVehicle(auth, vehicle, true) + }), + ) + + return { + totalRecords: countResult, + vehicles: vehicles, + } + } + + private async mapVehicle( + auth: User, + vehicle: CurrentVehiclesWithMilageAndNextInspDto, + fetchExtraData: boolean, + ) { + let validation: OperatorChangeValidation | undefined + let debtStatus: VehicleDebtStatus | undefined + let mileageReadings: MileageReadingDto[] | undefined + + if (fetchExtraData) { + // Get debt status + debtStatus = await this.vehicleServiceFjsV1Client.getVehicleDebtStatus( + auth, + vehicle.permno || '', ) + + // Get operator change validation + validation = + await this.vehicleOperatorsClient.validateVehicleForOperatorChange( + auth, + vehicle.permno || '', + ) + + // Get mileage reading + mileageReadings = await this.mileageReadingApiWithAuth( + auth, + ).getMileageReading({ permno: vehicle.permno || '' }) } return { - totalRecords: countResult, - vehicles: await Promise.all( - result?.map(async (vehicle) => { - let validation: OperatorChangeValidation | undefined - let debtStatus: VehicleDebtStatus | undefined - let mileageReadings: MileageReadingDto[] | undefined - - // Only validate if fewer than 5 items - if (result.length <= 5) { - // Get debt status - debtStatus = - await this.vehicleServiceFjsV1Client.getVehicleDebtStatus( - auth, - vehicle.permno || '', - ) - - // Get validation - validation = - await this.vehicleOperatorsClient.validateVehicleForOperatorChange( - auth, - vehicle.permno || '', - ) - mileageReadings = await this.mileageReadingApiWithAuth( - auth, - ).getMileageReading({ permno: vehicle.permno || '' }) - } - - const electricFuelCodes = - this.vehicleCodetablesClient.getElectricFueldCodes() - - return { - permno: vehicle.permno || undefined, - make: vehicle.make || undefined, - color: vehicle.color || undefined, - role: vehicle.role || undefined, - requireMileage: electricFuelCodes.includes(vehicle.fuelCode || ''), - mileageReading: (mileageReadings?.[0]?.mileage ?? '').toString(), - isDebtLess: debtStatus?.isDebtLess, - validationErrorMessages: validation?.hasError - ? validation.errorMessages - : null, - } - }), - ), + permno: vehicle.permno || undefined, + make: vehicle.make || undefined, + color: vehicle.colorName || undefined, + role: vehicle.role || undefined, + requireMileage: vehicle.requiresMileageRegistration, + mileageReading: mileageReadings?.[0]?.mileage?.toString() ?? '', + isDebtLess: debtStatus?.isDebtLess, + validationErrorMessages: validation?.hasError + ? validation.errorMessages + : null, } } diff --git a/libs/application/template-api-modules/src/lib/modules/templates/transport-authority/transfer-of-vehicle-ownership/transfer-of-vehicle-ownership.service.ts b/libs/application/template-api-modules/src/lib/modules/templates/transport-authority/transfer-of-vehicle-ownership/transfer-of-vehicle-ownership.service.ts index 4d265b85aebd..8bc963e132a0 100644 --- a/libs/application/template-api-modules/src/lib/modules/templates/transport-authority/transfer-of-vehicle-ownership/transfer-of-vehicle-ownership.service.ts +++ b/libs/application/template-api-modules/src/lib/modules/templates/transport-authority/transfer-of-vehicle-ownership/transfer-of-vehicle-ownership.service.ts @@ -33,7 +33,10 @@ import { VehicleDebtStatus, VehicleServiceFjsV1Client, } from '@island.is/clients/vehicle-service-fjs-v1' -import { VehicleSearchApi } from '@island.is/clients/vehicles' +import { + CurrentVehiclesWithMilageAndNextInspDto, + VehicleSearchApi, +} from '@island.is/clients/vehicles' import { MileageReadingApi, MileageReadingDto, @@ -42,7 +45,7 @@ import { TemplateApiError } from '@island.is/nest/problem' import { applicationCheck } from '@island.is/application/templates/transport-authority/transfer-of-vehicle-ownership' import { LOGGER_PROVIDER } from '@island.is/logging' import type { Logger } from '@island.is/logging' -import { Auth, AuthMiddleware } from '@island.is/auth-nest-tools' +import { Auth, AuthMiddleware, User } from '@island.is/auth-nest-tools' import { coreErrorMessages } from '@island.is/application/core' @Injectable() @@ -75,7 +78,7 @@ export class TransferOfVehicleOwnershipService extends BaseTemplateApiService { async getCurrentVehiclesWithOwnerchangeChecks({ auth, }: TemplateApiModuleActionProps) { - // Check total vehicles + // Get total count of vehicles const countResult = ( await this.vehiclesApiWithAuth( @@ -88,75 +91,98 @@ export class TransferOfVehicleOwnershipService extends BaseTemplateApiService { pageSize: 1, }) ).totalRecords || 0 - if (countResult && countResult > 20) { + + // Validate that user has at least 1 vehicle + if (!countResult) { + throw new TemplateApiError( + { + title: coreErrorMessages.vehiclesEmptyListOwner, + summary: coreErrorMessages.vehiclesEmptyListOwner, + }, + 400, + ) + } + + // A. vehicleCount > 20 + // Display search box, validate vehicle when permno is entered + if (countResult > 20) { return { totalRecords: countResult, vehicles: [], } } - const result = await this.vehiclesApiWithAuth(auth).currentVehiclesGet({ - persidNo: auth.nationalId, + + // Get all vehicles + const result = await this.vehiclesApiWithAuth( + auth, + ).currentvehicleswithmileageandinspGet({ showOwned: true, showCoowned: false, showOperated: false, }) - // Validate that user has at least 1 vehicle - if (!result || !result.length) { - throw new TemplateApiError( - { - title: coreErrorMessages.vehiclesEmptyListOwner, - summary: coreErrorMessages.vehiclesEmptyListOwner, - }, - 400, + const resultData = result.data || [] + + const vehicles = await Promise.all( + resultData.map(async (vehicle) => { + // B. 20 >= vehicleCount > 5 + // Display dropdown, validate vehicle when selected in dropdown + if (countResult > 5) { + return this.mapVehicle(auth, vehicle, false) + } + + // C. vehicleCount <= 5 + // Display radio buttons, validate all vehicles now + return this.mapVehicle(auth, vehicle, true) + }), + ) + + return { + totalRecords: countResult, + vehicles: vehicles, + } + } + + private async mapVehicle( + auth: User, + vehicle: CurrentVehiclesWithMilageAndNextInspDto, + fetchExtraData: boolean, + ) { + let validation: OwnerChangeValidation | undefined + let debtStatus: VehicleDebtStatus | undefined + let mileageReadings: MileageReadingDto[] | undefined + + if (fetchExtraData) { + // Get debt status + debtStatus = await this.vehicleServiceFjsV1Client.getVehicleDebtStatus( + auth, + vehicle.permno || '', ) + + // Get owner change validation + validation = + await this.vehicleOwnerChangeClient.validateVehicleForOwnerChange( + auth, + vehicle.permno || '', + ) + + // Get mileage reading + mileageReadings = await this.mileageReadingApiWithAuth( + auth, + ).getMileageReading({ permno: vehicle.permno || '' }) } return { - totalRecords: countResult, - vehicles: await Promise.all( - result?.map(async (vehicle) => { - let validation: OwnerChangeValidation | undefined - let debtStatus: VehicleDebtStatus | undefined - let mileageReadings: MileageReadingDto[] | undefined - - // Only validate if fewer than 5 items - if (result.length <= 5) { - // Get debt status - debtStatus = - await this.vehicleServiceFjsV1Client.getVehicleDebtStatus( - auth, - vehicle.permno || '', - ) - - // Get validation - validation = - await this.vehicleOwnerChangeClient.validateVehicleForOwnerChange( - auth, - vehicle.permno || '', - ) - mileageReadings = await this.mileageReadingApiWithAuth( - auth, - ).getMileageReading({ permno: vehicle.permno || '' }) - } - - const electricFuelCodes = - this.vehicleCodetablesClient.getElectricFueldCodes() - - return { - permno: vehicle.permno || undefined, - make: vehicle.make || undefined, - color: vehicle.color || undefined, - role: vehicle.role || undefined, - requireMileage: electricFuelCodes.includes(vehicle.fuelCode || ''), - mileageReading: (mileageReadings?.[0]?.mileage ?? '').toString(), - isDebtLess: debtStatus?.isDebtLess, - validationErrorMessages: validation?.hasError - ? validation.errorMessages - : null, - } - }), - ), + permno: vehicle.permno || undefined, + make: vehicle.make || undefined, + color: vehicle.colorName || undefined, + role: vehicle.role || undefined, + requireMileage: vehicle.requiresMileageRegistration, + mileageReading: mileageReadings?.[0]?.mileage?.toString() ?? '', + isDebtLess: debtStatus?.isDebtLess, + validationErrorMessages: validation?.hasError + ? validation.errorMessages + : null, } } @@ -615,7 +641,7 @@ export class TransferOfVehicleOwnershipService extends BaseTemplateApiService { ) .catch((e) => { this.logger.error( - `Error sending sms about rejectApplication to + `Error sending sms about submitApplication to a phonenumber in application: ID: ${application.id}, role: ${recipientList[i].role}`, e, diff --git a/libs/application/templates/transport-authority/change-co-owner-of-vehicle/src/forms/ChangeCoOwnerOfVehicleForm/InformationSection/vehicleSubSection.ts b/libs/application/templates/transport-authority/change-co-owner-of-vehicle/src/forms/ChangeCoOwnerOfVehicleForm/InformationSection/vehicleSubSection.ts index 246e3301bd7f..efac7e83c97d 100644 --- a/libs/application/templates/transport-authority/change-co-owner-of-vehicle/src/forms/ChangeCoOwnerOfVehicleForm/InformationSection/vehicleSubSection.ts +++ b/libs/application/templates/transport-authority/change-co-owner-of-vehicle/src/forms/ChangeCoOwnerOfVehicleForm/InformationSection/vehicleSubSection.ts @@ -48,7 +48,7 @@ export const vehicleSubSection = buildSubSection({ }, }), buildHiddenInput({ - id: 'vehicleMileage.isRequired', + id: 'vehicleMileage.requireMileage', defaultValue: (application: Application) => { const vehicle = getSelectedVehicle( application.externalData, diff --git a/libs/application/templates/transport-authority/change-co-owner-of-vehicle/src/lib/dataSchema.ts b/libs/application/templates/transport-authority/change-co-owner-of-vehicle/src/lib/dataSchema.ts index 40301c21e05a..97fa523a2f26 100644 --- a/libs/application/templates/transport-authority/change-co-owner-of-vehicle/src/lib/dataSchema.ts +++ b/libs/application/templates/transport-authority/change-co-owner-of-vehicle/src/lib/dataSchema.ts @@ -97,13 +97,13 @@ export const ChangeCoOwnerOfVehicleSchema = z.object({ }), vehicleMileage: z .object({ - isRequired: z.boolean().optional(), + requireMileage: z.boolean().optional(), mileageReading: z.string().optional(), value: z.string().optional(), }) .refine( (x: VehicleMileage) => { - if (x.isRequired) { + if (x.requireMileage) { return ( (x.value !== undefined && x.value !== '' && diff --git a/libs/application/templates/transport-authority/change-co-owner-of-vehicle/src/shared/types.ts b/libs/application/templates/transport-authority/change-co-owner-of-vehicle/src/shared/types.ts index 2d3b35973204..889de7e27519 100644 --- a/libs/application/templates/transport-authority/change-co-owner-of-vehicle/src/shared/types.ts +++ b/libs/application/templates/transport-authority/change-co-owner-of-vehicle/src/shared/types.ts @@ -39,7 +39,7 @@ export type VehiclesCurrentVehicleWithOwnerchangeChecks = { } export type VehicleMileage = { - isRequired?: boolean + requireMileage?: boolean mileageReading?: string value?: string } diff --git a/libs/application/templates/transport-authority/change-co-owner-of-vehicle/src/utils/getSelectedVehicle.ts b/libs/application/templates/transport-authority/change-co-owner-of-vehicle/src/utils/getSelectedVehicle.ts index 95c50a96e5be..a13ea829dc3c 100644 --- a/libs/application/templates/transport-authority/change-co-owner-of-vehicle/src/utils/getSelectedVehicle.ts +++ b/libs/application/templates/transport-authority/change-co-owner-of-vehicle/src/utils/getSelectedVehicle.ts @@ -13,6 +13,7 @@ export const getSelectedVehicle = ( ) as VehiclesCurrentVehicle return vehicle } + const currentVehicleList = (externalData?.currentVehicleList?.data as CurrentVehiclesAndRecords) ?? undefined @@ -22,11 +23,7 @@ export const getSelectedVehicle = ( 'pickVehicle.vehicle', '', ) as string - const requireMileage = getValueViaPath( - answers, - 'vehicleMileage.requireMileage', - false, - ) as boolean + const mileageReading = getValueViaPath( answers, 'vehicleMileage.mileageReading', @@ -35,16 +32,14 @@ export const getSelectedVehicle = ( const index = parseInt(vehicleIndex, 10) - if ( - currentVehicleList?.vehicles && - currentVehicleList.vehicles[index] && - !Object.isFrozen(currentVehicleList.vehicles[index]) - ) { + const vehicle = currentVehicleList?.vehicles?.[index] + + if (vehicle && !Object.isFrozen(vehicle)) { currentVehicleList.vehicles[index] = { - ...currentVehicleList.vehicles[index], - requireMileage: requireMileage, + ...vehicle, mileageReading: mileageReading, } } - return currentVehicleList?.vehicles[parseInt(vehicleIndex, 10)] + + return currentVehicleList?.vehicles?.[index] } diff --git a/libs/application/templates/transport-authority/change-operator-of-vehicle/src/forms/ChangeOperatorOfVehicleForm/InformationSection/vehicleSubSection.ts b/libs/application/templates/transport-authority/change-operator-of-vehicle/src/forms/ChangeOperatorOfVehicleForm/InformationSection/vehicleSubSection.ts index dfbb5d76029e..70cd26729e83 100644 --- a/libs/application/templates/transport-authority/change-operator-of-vehicle/src/forms/ChangeOperatorOfVehicleForm/InformationSection/vehicleSubSection.ts +++ b/libs/application/templates/transport-authority/change-operator-of-vehicle/src/forms/ChangeOperatorOfVehicleForm/InformationSection/vehicleSubSection.ts @@ -46,7 +46,7 @@ export const vehicleSubSection = buildSubSection({ }, }), buildHiddenInput({ - id: 'vehicleMileage.isRequired', + id: 'vehicleMileage.requireMileage', defaultValue: (application: Application) => { const vehicle = getSelectedVehicle( application.externalData, diff --git a/libs/application/templates/transport-authority/change-operator-of-vehicle/src/lib/dataSchema.ts b/libs/application/templates/transport-authority/change-operator-of-vehicle/src/lib/dataSchema.ts index 012d5f5b01c9..e44cf922b248 100644 --- a/libs/application/templates/transport-authority/change-operator-of-vehicle/src/lib/dataSchema.ts +++ b/libs/application/templates/transport-authority/change-operator-of-vehicle/src/lib/dataSchema.ts @@ -97,13 +97,13 @@ export const ChangeOperatorOfVehicleSchema = z.object({ ownerCoOwner: z.array(UserInformationSchema), vehicleMileage: z .object({ - isRequired: z.boolean().optional(), + requireMileage: z.boolean().optional(), mileageReading: z.string().optional(), value: z.string().optional(), }) .refine( (x: VehicleMileage) => { - if (x.isRequired) { + if (x.requireMileage) { return ( (x.value !== undefined && x.value !== '' && diff --git a/libs/application/templates/transport-authority/change-operator-of-vehicle/src/shared/types.ts b/libs/application/templates/transport-authority/change-operator-of-vehicle/src/shared/types.ts index 3a890608f315..8f2d5bd3d1ea 100644 --- a/libs/application/templates/transport-authority/change-operator-of-vehicle/src/shared/types.ts +++ b/libs/application/templates/transport-authority/change-operator-of-vehicle/src/shared/types.ts @@ -55,7 +55,7 @@ export type OperatorFormField = Partial< > export type VehicleMileage = { - isRequired?: boolean + requireMileage?: boolean mileageReading?: string value?: string } diff --git a/libs/application/templates/transport-authority/change-operator-of-vehicle/src/utils/getSelectedVehicle.ts b/libs/application/templates/transport-authority/change-operator-of-vehicle/src/utils/getSelectedVehicle.ts index 95c50a96e5be..a13ea829dc3c 100644 --- a/libs/application/templates/transport-authority/change-operator-of-vehicle/src/utils/getSelectedVehicle.ts +++ b/libs/application/templates/transport-authority/change-operator-of-vehicle/src/utils/getSelectedVehicle.ts @@ -13,6 +13,7 @@ export const getSelectedVehicle = ( ) as VehiclesCurrentVehicle return vehicle } + const currentVehicleList = (externalData?.currentVehicleList?.data as CurrentVehiclesAndRecords) ?? undefined @@ -22,11 +23,7 @@ export const getSelectedVehicle = ( 'pickVehicle.vehicle', '', ) as string - const requireMileage = getValueViaPath( - answers, - 'vehicleMileage.requireMileage', - false, - ) as boolean + const mileageReading = getValueViaPath( answers, 'vehicleMileage.mileageReading', @@ -35,16 +32,14 @@ export const getSelectedVehicle = ( const index = parseInt(vehicleIndex, 10) - if ( - currentVehicleList?.vehicles && - currentVehicleList.vehicles[index] && - !Object.isFrozen(currentVehicleList.vehicles[index]) - ) { + const vehicle = currentVehicleList?.vehicles?.[index] + + if (vehicle && !Object.isFrozen(vehicle)) { currentVehicleList.vehicles[index] = { - ...currentVehicleList.vehicles[index], - requireMileage: requireMileage, + ...vehicle, mileageReading: mileageReading, } } - return currentVehicleList?.vehicles[parseInt(vehicleIndex, 10)] + + return currentVehicleList?.vehicles?.[index] } diff --git a/libs/application/templates/transport-authority/order-vehicle-license-plate/src/graphql/queries.ts b/libs/application/templates/transport-authority/order-vehicle-license-plate/src/graphql/queries.ts index a0bf71701059..526d8a5f041d 100644 --- a/libs/application/templates/transport-authority/order-vehicle-license-plate/src/graphql/queries.ts +++ b/libs/application/templates/transport-authority/order-vehicle-license-plate/src/graphql/queries.ts @@ -10,7 +10,6 @@ export const GET_VEHICLE_PLATE_ORDER_CHECKS_BY_PERMNO = ` make color role - requireMileage } } } diff --git a/libs/application/templates/transport-authority/transfer-of-vehicle-ownership/src/forms/TransferOfVehicleOwnershipForm/InformationSection/vehicleSubSection.ts b/libs/application/templates/transport-authority/transfer-of-vehicle-ownership/src/forms/TransferOfVehicleOwnershipForm/InformationSection/vehicleSubSection.ts index 71acea93db7a..24869654cb25 100644 --- a/libs/application/templates/transport-authority/transfer-of-vehicle-ownership/src/forms/TransferOfVehicleOwnershipForm/InformationSection/vehicleSubSection.ts +++ b/libs/application/templates/transport-authority/transfer-of-vehicle-ownership/src/forms/TransferOfVehicleOwnershipForm/InformationSection/vehicleSubSection.ts @@ -67,7 +67,7 @@ export const vehicleSubSection = buildSubSection({ defaultValue: new Date().toISOString().substring(0, 10), }), buildHiddenInput({ - id: 'vehicleMileage.isRequired', + id: 'vehicleMileage.requireMileage', defaultValue: (application: Application) => { const vehicle = getSelectedVehicle( application.externalData, diff --git a/libs/application/templates/transport-authority/transfer-of-vehicle-ownership/src/lib/dataSchema.ts b/libs/application/templates/transport-authority/transfer-of-vehicle-ownership/src/lib/dataSchema.ts index 2ebd9c218f8b..0c52b45ce0b5 100644 --- a/libs/application/templates/transport-authority/transfer-of-vehicle-ownership/src/lib/dataSchema.ts +++ b/libs/application/templates/transport-authority/transfer-of-vehicle-ownership/src/lib/dataSchema.ts @@ -101,13 +101,13 @@ export const TransferOfVehicleOwnershipSchema = z.object({ }), vehicleMileage: z .object({ - isRequired: z.boolean().optional(), + requireMileage: z.boolean().optional(), mileageReading: z.string().optional(), value: z.string().optional(), }) .refine( (x: VehicleMileage) => { - if (x.isRequired) { + if (x.requireMileage) { return ( (x.value !== undefined && x.value !== '' && diff --git a/libs/application/templates/transport-authority/transfer-of-vehicle-ownership/src/shared/types.ts b/libs/application/templates/transport-authority/transfer-of-vehicle-ownership/src/shared/types.ts index 638b1b5b7567..b50cd53c0360 100644 --- a/libs/application/templates/transport-authority/transfer-of-vehicle-ownership/src/shared/types.ts +++ b/libs/application/templates/transport-authority/transfer-of-vehicle-ownership/src/shared/types.ts @@ -84,7 +84,7 @@ export type VehiclesCurrentVehicleWithOwnerchangeChecks = { } export type VehicleMileage = { - isRequired?: boolean + requireMileage?: boolean mileageReading?: string value?: string } diff --git a/libs/application/templates/transport-authority/transfer-of-vehicle-ownership/src/utils/getSelectedVehicle.ts b/libs/application/templates/transport-authority/transfer-of-vehicle-ownership/src/utils/getSelectedVehicle.ts index 95c50a96e5be..a13ea829dc3c 100644 --- a/libs/application/templates/transport-authority/transfer-of-vehicle-ownership/src/utils/getSelectedVehicle.ts +++ b/libs/application/templates/transport-authority/transfer-of-vehicle-ownership/src/utils/getSelectedVehicle.ts @@ -13,6 +13,7 @@ export const getSelectedVehicle = ( ) as VehiclesCurrentVehicle return vehicle } + const currentVehicleList = (externalData?.currentVehicleList?.data as CurrentVehiclesAndRecords) ?? undefined @@ -22,11 +23,7 @@ export const getSelectedVehicle = ( 'pickVehicle.vehicle', '', ) as string - const requireMileage = getValueViaPath( - answers, - 'vehicleMileage.requireMileage', - false, - ) as boolean + const mileageReading = getValueViaPath( answers, 'vehicleMileage.mileageReading', @@ -35,16 +32,14 @@ export const getSelectedVehicle = ( const index = parseInt(vehicleIndex, 10) - if ( - currentVehicleList?.vehicles && - currentVehicleList.vehicles[index] && - !Object.isFrozen(currentVehicleList.vehicles[index]) - ) { + const vehicle = currentVehicleList?.vehicles?.[index] + + if (vehicle && !Object.isFrozen(vehicle)) { currentVehicleList.vehicles[index] = { - ...currentVehicleList.vehicles[index], - requireMileage: requireMileage, + ...vehicle, mileageReading: mileageReading, } } - return currentVehicleList?.vehicles[parseInt(vehicleIndex, 10)] + + return currentVehicleList?.vehicles?.[index] } diff --git a/libs/clients/transport-authority/vehicle-codetables/src/lib/vehicleCodetablesClient.service.ts b/libs/clients/transport-authority/vehicle-codetables/src/lib/vehicleCodetablesClient.service.ts index 97250da640fe..42d1a9f62e33 100644 --- a/libs/clients/transport-authority/vehicle-codetables/src/lib/vehicleCodetablesClient.service.ts +++ b/libs/clients/transport-authority/vehicle-codetables/src/lib/vehicleCodetablesClient.service.ts @@ -31,15 +31,4 @@ export class VehicleCodetablesClient { plateWidth: item.plateWidth, })) } - - public getElectricFueldCodes(): string[] { - return [ - '3', // Rafmagn - '5', // Vetni - 'D', // Bensín /Raf.tengill - 'E', // Dísel /Raf.tengill - 'F', // Vetni /Rafmagn - 'G', // Vetni/ Raf.tengill - ] - } }