diff --git a/backend/src/common/helpers/utils.ts b/backend/src/common/helpers/utils.ts index 98bf388e..ebdc6fc9 100644 --- a/backend/src/common/helpers/utils.ts +++ b/backend/src/common/helpers/utils.ts @@ -1,3 +1,4 @@ +import { differenceInYears } from 'date-fns'; import * as XLSX from 'xlsx'; export function JSONStringifyError(value: Error): string { @@ -25,3 +26,19 @@ export function jsonToExcelBuffer( return XLSX.write(wb, { type: 'buffer', bookType: 'xlsx' }); } + +export const isOver16FromCNP = (cnp: string): boolean => { + // we don't need to perform the calculation before the user has entered all the necessary digits to calculate + if (cnp.length !== 13) { + throw new Error('CNP must be 13 digits long'); + } + // if first digit is above 5, then the birth year is 2000+ + const yearPrefix = parseInt(cnp[0], 10) < 5 ? '19' : '20'; + const year = (yearPrefix + cnp.substring(1, 3)).toString(); + const month = cnp.substring(3, 5); + const day = cnp.substring(5, 7); + const birthday = new Date(`${year}-${month}-${day}`); + + const age = differenceInYears(new Date(), birthday); + return age >= 16; +}; diff --git a/backend/src/usecases/documents/new_contracts/create-document-contract.usecase.ts b/backend/src/usecases/documents/new_contracts/create-document-contract.usecase.ts index 7699fd07..4a512815 100644 --- a/backend/src/usecases/documents/new_contracts/create-document-contract.usecase.ts +++ b/backend/src/usecases/documents/new_contracts/create-document-contract.usecase.ts @@ -1,4 +1,5 @@ import { Injectable } from '@nestjs/common'; +import { isOver16FromCNP } from 'src/common/helpers/utils'; import { IUseCaseService } from 'src/common/interfaces/use-case-service.interface'; import { ExceptionsService } from 'src/infrastructure/exceptions/exceptions.service'; import { DocumentContractStatus } from 'src/modules/documents/enums/contract-status.enum'; @@ -44,10 +45,7 @@ export class CreateDocumentContractUsecase implements IUseCaseService { >, ): Promise { // 1. check if the organization exists - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const organization = await this.getOrganizationUsecase.execute( - newContract.organizationId, - ); + await this.getOrganizationUsecase.execute(newContract.organizationId); // 2. check if the volunteer exists const volunteer = await this.checkVolunteerExists( @@ -68,10 +66,18 @@ export class CreateDocumentContractUsecase implements IUseCaseService { // 6. Extract volunteerData and volunteerTutorData from the user const volunteerPersonalData = volunteer.user.userPersonalData; - // console.log(volunteerPersonalData); - await this.validateVolunteerPersonalData(volunteerPersonalData); - await this.validateLegalGuardianData(volunteerPersonalData.legalGuardian); + + if (!isOver16FromCNP(volunteerPersonalData.cnp)) { + if (!volunteerPersonalData.legalGuardian) { + this.exceptionsService.badRequestException({ + message: 'Legal guardian data is required for under 16 volunteers', + code_error: 'LEGAL_GUARDIAN_DATA_REQUIRED', + }); + } + + await this.validateLegalGuardianData(volunteerPersonalData.legalGuardian); + } const newContractOptions: CreateDocumentContractOptions = { ...newContract,