feat: implement codice fiscale calculation and validation
- Added `CalcolaCodiceFiscale` function to calculate Italian fiscal code based on name, surname, birth date, gender, and municipality code. - Introduced utility functions for generating parts of the fiscal code, including handling special cases for names and surnames. - Created tests for the fiscal code calculation covering various scenarios. - Updated forms to enforce a maximum length for the fiscal code input. - Added `vitest` for testing and configured it with Vite. - Updated package dependencies to include testing libraries and Vite plugins.
This commit is contained in:
parent
ef59e61545
commit
7b76132a94
8 changed files with 2743 additions and 163 deletions
2508
apps/infoalloggi/package-lock.json
generated
2508
apps/infoalloggi/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -16,7 +16,8 @@
|
||||||
"stripe-dev": "stripe listen --forward-to https://localhost:3000/api/stripe-webhook",
|
"stripe-dev": "stripe listen --forward-to https://localhost:3000/api/stripe-webhook",
|
||||||
"test": " npm run lint && npm run types ",
|
"test": " npm run lint && npm run types ",
|
||||||
"types": "tsc --noEmit",
|
"types": "tsc --noEmit",
|
||||||
"analyze": "cross-env ANALYZE=true next build"
|
"analyze": "cross-env ANALYZE=true next build",
|
||||||
|
"vitest": "vitest run"
|
||||||
},
|
},
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
@ -111,6 +112,8 @@
|
||||||
"@biomejs/biome": "^2.4.2",
|
"@biomejs/biome": "^2.4.2",
|
||||||
"@hookform/devtools": "^4.4.0",
|
"@hookform/devtools": "^4.4.0",
|
||||||
"@react-email/preview-server": "^5.2.8",
|
"@react-email/preview-server": "^5.2.8",
|
||||||
|
"@testing-library/dom": "^10.4.1",
|
||||||
|
"@testing-library/react": "^16.3.2",
|
||||||
"@total-typescript/ts-reset": "^0.6.1",
|
"@total-typescript/ts-reset": "^0.6.1",
|
||||||
"@types/leaflet": "^1.9.21",
|
"@types/leaflet": "^1.9.21",
|
||||||
"@types/node": "^24.2.0",
|
"@types/node": "^24.2.0",
|
||||||
|
|
@ -121,13 +124,17 @@
|
||||||
"@types/react-dom": "^19.2.3",
|
"@types/react-dom": "^19.2.3",
|
||||||
"@types/react-is": "^19.2.0",
|
"@types/react-is": "^19.2.0",
|
||||||
"@types/uuid": "^11.0.0",
|
"@types/uuid": "^11.0.0",
|
||||||
|
"@vitejs/plugin-react": "^5.1.4",
|
||||||
"cross-env": "^10.1.0",
|
"cross-env": "^10.1.0",
|
||||||
"jiti": "^2.6.1",
|
"jiti": "^2.6.1",
|
||||||
|
"jsdom": "^28.1.0",
|
||||||
"kanel": "^3.16.1",
|
"kanel": "^3.16.1",
|
||||||
"kanel-kysely": "^0.8.0",
|
"kanel-kysely": "^0.8.0",
|
||||||
"knip": "^5.85.0",
|
"knip": "^5.85.0",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"typescript": "^5.9.3"
|
"typescript": "^5.9.3",
|
||||||
|
"vite-tsconfig-paths": "^6.1.1",
|
||||||
|
"vitest": "^4.0.18"
|
||||||
},
|
},
|
||||||
"ct3aMetadata": {
|
"ct3aMetadata": {
|
||||||
"initVersion": "7.9.0"
|
"initVersion": "7.9.0"
|
||||||
|
|
|
||||||
|
|
@ -1136,6 +1136,7 @@ export const FormNewServizioAcquisto = ({
|
||||||
{...field}
|
{...field}
|
||||||
className="uppercase"
|
className="uppercase"
|
||||||
id="codice_fiscale"
|
id="codice_fiscale"
|
||||||
|
maxLength={16}
|
||||||
onChange={async (v) => {
|
onChange={async (v) => {
|
||||||
field.onChange(v.target.value.toUpperCase());
|
field.onChange(v.target.value.toUpperCase());
|
||||||
await form.trigger("codice_fiscale");
|
await form.trigger("codice_fiscale");
|
||||||
|
|
|
||||||
|
|
@ -394,6 +394,7 @@ export const ProfileFormAnagrafica = ({
|
||||||
{...field}
|
{...field}
|
||||||
className="uppercase"
|
className="uppercase"
|
||||||
id="codice_fiscale"
|
id="codice_fiscale"
|
||||||
|
maxLength={16}
|
||||||
onChange={async (v) => {
|
onChange={async (v) => {
|
||||||
field.onChange(v.target.value.toUpperCase());
|
field.onChange(v.target.value.toUpperCase());
|
||||||
await form.trigger("codice_fiscale");
|
await form.trigger("codice_fiscale");
|
||||||
|
|
|
||||||
113
apps/infoalloggi/src/lib/codice_fiscale.test.ts
Normal file
113
apps/infoalloggi/src/lib/codice_fiscale.test.ts
Normal file
|
|
@ -0,0 +1,113 @@
|
||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import { CalcolaCodiceFiscale } from "~/lib/codice_fiscale";
|
||||||
|
|
||||||
|
// Importa la tua funzione qui
|
||||||
|
// import { calcolaCF } from './ilTuoFile';
|
||||||
|
|
||||||
|
interface TestInput {
|
||||||
|
nome: string;
|
||||||
|
cognome: string;
|
||||||
|
dataNascita: string; // DD/MM/YYYY
|
||||||
|
sesso: "M" | "F";
|
||||||
|
catasto: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const testCases: { descrizione: string; input: TestInput; expected: string }[] =
|
||||||
|
[
|
||||||
|
{
|
||||||
|
descrizione: "Caso Francisco (Regola 1-3-4 e Stato Estero)",
|
||||||
|
input: {
|
||||||
|
nome: "Francisco Guillermo",
|
||||||
|
cognome: "Cespedes Catacora",
|
||||||
|
dataNascita: "1992-07-13",
|
||||||
|
sesso: "M",
|
||||||
|
catasto: "Z611",
|
||||||
|
},
|
||||||
|
expected: "CSPFNC92L13Z611Z",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
descrizione: "Cognome e Nome corti (2 lettere) -> Pad con X",
|
||||||
|
input: {
|
||||||
|
nome: "Bo",
|
||||||
|
cognome: "Fu",
|
||||||
|
dataNascita: "1990-01-01",
|
||||||
|
sesso: "M",
|
||||||
|
catasto: "H501",
|
||||||
|
},
|
||||||
|
expected: "FUXBOX90A01H501F",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
descrizione: "Cognome solo vocali",
|
||||||
|
input: {
|
||||||
|
nome: "Luca",
|
||||||
|
cognome: "Ao",
|
||||||
|
dataNascita: "1985-05-15",
|
||||||
|
sesso: "M",
|
||||||
|
catasto: "F205",
|
||||||
|
},
|
||||||
|
expected: "AOXLCU85E15F205Q",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
descrizione: "Femmina + Dicembre (Giorno + 40 e Mese T)",
|
||||||
|
input: {
|
||||||
|
nome: "Anna",
|
||||||
|
cognome: "Rossi",
|
||||||
|
dataNascita: "1975-12-31",
|
||||||
|
sesso: "F",
|
||||||
|
catasto: "L219",
|
||||||
|
},
|
||||||
|
expected: "RSSNNA75T71L219W",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
descrizione: "Nome con esattamente 3 consonanti (MRT)",
|
||||||
|
input: {
|
||||||
|
nome: "Marta",
|
||||||
|
cognome: "Rossi",
|
||||||
|
dataNascita: "1995-02-10",
|
||||||
|
sesso: "F",
|
||||||
|
catasto: "H501",
|
||||||
|
},
|
||||||
|
expected: "RSSMRT95B50H501Z",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
descrizione: "Gestione apostrofi e spazi (D'Arco Maria Adele)",
|
||||||
|
input: {
|
||||||
|
nome: "Maria Adele",
|
||||||
|
cognome: "D'Arco",
|
||||||
|
dataNascita: "1980-03-05",
|
||||||
|
sesso: "F",
|
||||||
|
catasto: "A662",
|
||||||
|
},
|
||||||
|
expected: "DRCMDL80C45A662W",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
descrizione: "Nato nel 2000 (Anno 00)",
|
||||||
|
input: {
|
||||||
|
nome: "Giuseppe",
|
||||||
|
cognome: "Verdi",
|
||||||
|
dataNascita: "2000-10-20",
|
||||||
|
sesso: "M",
|
||||||
|
catasto: "H501",
|
||||||
|
},
|
||||||
|
expected: "VRDGPP00R20H501M",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
describe("Calcolo Codice Fiscale", () => {
|
||||||
|
it.each(testCases)("$descrizione", ({ input, expected }) => {
|
||||||
|
// const result = calcolaCF(input);
|
||||||
|
// expect(result).toBe(expected);
|
||||||
|
|
||||||
|
// Placeholder per la tua funzione
|
||||||
|
const { cf, omocodie } = CalcolaCodiceFiscale({
|
||||||
|
nome: input.nome,
|
||||||
|
cognome: input.cognome,
|
||||||
|
dataNascita: new Date(input.dataNascita),
|
||||||
|
sesso: input.sesso,
|
||||||
|
catasto: input.catasto,
|
||||||
|
});
|
||||||
|
|
||||||
|
const allValidCFs = [cf, ...omocodie];
|
||||||
|
expect(allValidCFs).toContain(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
117
apps/infoalloggi/src/lib/codice_fiscale.ts
Normal file
117
apps/infoalloggi/src/lib/codice_fiscale.ts
Normal file
|
|
@ -0,0 +1,117 @@
|
||||||
|
export const CalcolaCodiceFiscale = ({
|
||||||
|
cognome,
|
||||||
|
nome,
|
||||||
|
dataNascita,
|
||||||
|
sesso,
|
||||||
|
catasto,
|
||||||
|
}: {
|
||||||
|
cognome: string;
|
||||||
|
nome: string;
|
||||||
|
dataNascita: Date;
|
||||||
|
sesso: "M" | "F";
|
||||||
|
catasto: string;
|
||||||
|
}) => {
|
||||||
|
const data = new Date(dataNascita);
|
||||||
|
|
||||||
|
const cf15 = `${calcoloCognome(cognome)}${calcoloNome(nome)}${data.getFullYear().toString().slice(-2)}${getMonthLetterCF(data.getMonth())}${getDayCF(data.getDate(), sesso)}${catasto}`;
|
||||||
|
const cf = `${cf15}${genCarattereControllo(cf15)}`;
|
||||||
|
const omocodie = genOmocodie(cf);
|
||||||
|
return {
|
||||||
|
cf,
|
||||||
|
omocodie,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function calcoloCognome(cognome: string): string {
|
||||||
|
const consonanti = cognome
|
||||||
|
.toUpperCase()
|
||||||
|
.replace(/[^BCDFGHJKLMNPQRSTVWXYZ]/g, "");
|
||||||
|
const vocali = cognome.toUpperCase().replace(/[^AEIOU]/g, "");
|
||||||
|
|
||||||
|
if (consonanti.length >= 3) {
|
||||||
|
return consonanti.substring(0, 3);
|
||||||
|
}
|
||||||
|
return `${consonanti + vocali}XXX`.substring(0, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
function calcoloNome(nome: string): string {
|
||||||
|
const consonanti = nome
|
||||||
|
.toUpperCase()
|
||||||
|
.replace(/[^BCDFGHJKLMNPQRSTVWXYZ]/g, "");
|
||||||
|
const vocali = nome.toUpperCase().replace(/[^AEIOU]/g, "");
|
||||||
|
|
||||||
|
if (consonanti.length >= 4) {
|
||||||
|
const c0 = consonanti[0];
|
||||||
|
const c2 = consonanti[2];
|
||||||
|
const c3 = consonanti[3];
|
||||||
|
if (!c0 || !c2 || !c3) {
|
||||||
|
throw new Error("Invalid name for CF generation");
|
||||||
|
}
|
||||||
|
// (4 o più consonanti): 1ª, 3ª e 4ª consonante
|
||||||
|
return c0 + c2 + c3;
|
||||||
|
}
|
||||||
|
// (meno di 4 consonanti): prime consonanti + eventuali vocali
|
||||||
|
const res = `${consonanti + vocali}XXX`.substring(0, 3);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
const lettere_mesi = "ABCDEHLMPRST";
|
||||||
|
const getMonthLetterCF = (month: number) => {
|
||||||
|
return lettere_mesi[month];
|
||||||
|
};
|
||||||
|
|
||||||
|
const getDayCF = (day: number, sesso: string) => {
|
||||||
|
if (sesso === "M") {
|
||||||
|
return day.toString().padStart(2, "0");
|
||||||
|
}
|
||||||
|
return (day + 40).toString().padStart(2, "0");
|
||||||
|
};
|
||||||
|
|
||||||
|
const set1 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
|
||||||
|
const set2 = "ABCDEFGHIJABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
|
||||||
|
const setpari = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
|
||||||
|
const setdisp = "BAKPLCQDREVOSFTGUHMINJWZYX";
|
||||||
|
|
||||||
|
const setcontrollo = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
|
||||||
|
const genCarattereControllo = (str: string) => {
|
||||||
|
let s = 0;
|
||||||
|
|
||||||
|
for (let i = 1; i <= 13; i += 2)
|
||||||
|
s += setpari.indexOf(set2.charAt(set1.indexOf(str.charAt(i))));
|
||||||
|
|
||||||
|
for (let i = 0; i <= 14; i += 2)
|
||||||
|
s += setdisp.indexOf(set2.charAt(set1.indexOf(str.charAt(i))));
|
||||||
|
|
||||||
|
return setcontrollo[s % 26];
|
||||||
|
};
|
||||||
|
|
||||||
|
const AltMapping = "LMNPQRSTUV";
|
||||||
|
const genOmocodie = (input: string): string[] => {
|
||||||
|
const substring = input.slice(0, Math.min(input.length, 15));
|
||||||
|
const result = [];
|
||||||
|
let wrk_string = substring;
|
||||||
|
|
||||||
|
for (let i = substring.length - 1; i >= 0; i--) {
|
||||||
|
const char = substring[i];
|
||||||
|
if (char && !Number.isNaN(parseInt(char))) {
|
||||||
|
const str_arr = wrk_string.split("");
|
||||||
|
const charNum = parseInt(char);
|
||||||
|
if (charNum > 9) {
|
||||||
|
throw new Error("Invalid CF");
|
||||||
|
}
|
||||||
|
|
||||||
|
const mappedChar = AltMapping[charNum];
|
||||||
|
if (!mappedChar) {
|
||||||
|
throw new Error("Invalid CF");
|
||||||
|
}
|
||||||
|
|
||||||
|
str_arr[i] = mappedChar;
|
||||||
|
wrk_string = str_arr.join("");
|
||||||
|
result.push(wrk_string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import dynamic from "next/dynamic";
|
|
||||||
import type { ChangeEvent } from "react";
|
import type { ChangeEvent } from "react";
|
||||||
import type { z } from "zod/v4";
|
import type { z } from "zod/v4";
|
||||||
import type { Comuni } from "~/schemas/public/Comuni";
|
import type { Comuni } from "~/schemas/public/Comuni";
|
||||||
import type { Nazioni } from "~/schemas/public/Nazioni";
|
import type { Nazioni } from "~/schemas/public/Nazioni";
|
||||||
import { ITALY_CATASTO_CODE } from "./catasto";
|
import { ITALY_CATASTO_CODE } from "./catasto";
|
||||||
|
import { CalcolaCodiceFiscale } from "./codice_fiscale";
|
||||||
|
|
||||||
export const NullableStringOnChange = (
|
export const NullableStringOnChange = (
|
||||||
e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
|
e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
|
||||||
|
|
@ -13,121 +13,6 @@ export const NullableStringOnChange = (
|
||||||
fn(e.target.value && e.target.value !== "" ? e.target.value : null);
|
fn(e.target.value && e.target.value !== "" ? e.target.value : null);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const FormDebug: React.ElementType =
|
|
||||||
process.env.NODE_ENV === "development"
|
|
||||||
? dynamic(
|
|
||||||
() => import("@hookform/devtools").then((module) => module.DevTool),
|
|
||||||
{ ssr: false },
|
|
||||||
)
|
|
||||||
: () => null; // Return null component in production
|
|
||||||
|
|
||||||
const lettere_mesi = "ABCDEHLMPRST";
|
|
||||||
const getMonthLetterCF = (month: number) => {
|
|
||||||
return lettere_mesi[month];
|
|
||||||
};
|
|
||||||
|
|
||||||
const getDayCF = (day: number, sesso: string) => {
|
|
||||||
if (sesso === "M") {
|
|
||||||
return day.toString().padStart(2, "0");
|
|
||||||
}
|
|
||||||
return (day + 40).toString().padStart(2, "0");
|
|
||||||
};
|
|
||||||
|
|
||||||
const AltMapping = "LMNPQRSTUV";
|
|
||||||
const getAlternativeCF = (input: string): string[] => {
|
|
||||||
const substring = input.slice(0, Math.min(input.length, 15));
|
|
||||||
const result = [];
|
|
||||||
let wrk_string = substring;
|
|
||||||
|
|
||||||
for (let i = substring.length - 1; i >= 0; i--) {
|
|
||||||
const char = substring[i];
|
|
||||||
if (char && !Number.isNaN(parseInt(char))) {
|
|
||||||
const str_arr = wrk_string.split("");
|
|
||||||
if (parseInt(char) > 9) {
|
|
||||||
throw new Error("Invalid CF");
|
|
||||||
}
|
|
||||||
// biome-ignore lint/style/noNonNullAssertion: <known length>
|
|
||||||
str_arr[i] = AltMapping[parseInt(char)]!;
|
|
||||||
wrk_string = str_arr.join("");
|
|
||||||
result.push(wrk_string);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
function calcolaParteCognome(cognome: string): string {
|
|
||||||
const consonanti = cognome
|
|
||||||
.toUpperCase()
|
|
||||||
.replace(/[^BCDFGHJKLMNPQRSTVWXYZ]/g, "");
|
|
||||||
const vocali = cognome.toUpperCase().replace(/[^AEIOU]/g, "");
|
|
||||||
|
|
||||||
if (consonanti.length >= 3) {
|
|
||||||
return consonanti.substring(0, 3);
|
|
||||||
}
|
|
||||||
return `${consonanti + vocali}XXX`.substring(0, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
function calcolaParteNome(nome: string): string {
|
|
||||||
const consonanti = nome
|
|
||||||
.toUpperCase()
|
|
||||||
.replace(/[^BCDFGHJKLMNPQRSTVWXYZ]/g, "");
|
|
||||||
const vocali = nome.toUpperCase().replace(/[^AEIOU]/g, "");
|
|
||||||
|
|
||||||
if (consonanti.length >= 4) {
|
|
||||||
const c0 = consonanti[0];
|
|
||||||
const c2 = consonanti[2];
|
|
||||||
const c3 = consonanti[3];
|
|
||||||
if (!c0 || !c2 || !c3) {
|
|
||||||
throw new Error("Invalid name for CF generation");
|
|
||||||
}
|
|
||||||
// (4 o più consonanti): 1ª, 3ª e 4ª consonante
|
|
||||||
return c0 + c2 + c3;
|
|
||||||
}
|
|
||||||
// (meno di 4 consonanti): prime consonanti + eventuali vocali
|
|
||||||
const res = `${consonanti + vocali}XXX`.substring(0, 3);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
const gen15CF = ({
|
|
||||||
cognome,
|
|
||||||
nome,
|
|
||||||
dataNascita,
|
|
||||||
sesso,
|
|
||||||
catasto,
|
|
||||||
}: {
|
|
||||||
cognome: string;
|
|
||||||
nome: string;
|
|
||||||
dataNascita: Date;
|
|
||||||
sesso: string;
|
|
||||||
catasto: string;
|
|
||||||
}): string => {
|
|
||||||
const data = new Date(dataNascita);
|
|
||||||
|
|
||||||
return `${calcolaParteCognome(cognome)}${calcolaParteNome(nome)}${data.getFullYear().toString().slice(-2)}${getMonthLetterCF(data.getMonth())}${getDayCF(data.getDate(), sesso)}${catasto}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
const set1 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
||||||
|
|
||||||
const set2 = "ABCDEFGHIJABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
||||||
|
|
||||||
const setpari = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
||||||
|
|
||||||
const setdisp = "BAKPLCQDREVOSFTGUHMINJWZYX";
|
|
||||||
|
|
||||||
const setcontrollo = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
||||||
|
|
||||||
const genCarattereControllo = (str: string) => {
|
|
||||||
let s = 0;
|
|
||||||
|
|
||||||
for (let i = 1; i <= 13; i += 2)
|
|
||||||
s += setpari.indexOf(set2.charAt(set1.indexOf(str.charAt(i))));
|
|
||||||
|
|
||||||
for (let i = 0; i <= 14; i += 2)
|
|
||||||
s += setdisp.indexOf(set2.charAt(set1.indexOf(str.charAt(i))));
|
|
||||||
|
|
||||||
return setcontrollo[s % 26];
|
|
||||||
};
|
|
||||||
|
|
||||||
export const checkFiscalCodeValidity = ({
|
export const checkFiscalCodeValidity = ({
|
||||||
path,
|
path,
|
||||||
codiceFiscale,
|
codiceFiscale,
|
||||||
|
|
@ -170,21 +55,21 @@ export const checkFiscalCodeValidity = ({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (sesso !== "M" && sesso !== "F") {
|
||||||
|
throw new Error("Invalid sex for CF generation");
|
||||||
|
}
|
||||||
|
|
||||||
const gen = gen15CF({
|
const { cf, omocodie } = CalcolaCodiceFiscale({
|
||||||
cognome: cognomeUpper,
|
cognome: cognomeUpper,
|
||||||
dataNascita,
|
dataNascita,
|
||||||
catasto: codiceCatasto,
|
catasto: codiceCatasto,
|
||||||
nome: nomeUpper,
|
nome: nomeUpper,
|
||||||
sesso,
|
sesso,
|
||||||
});
|
});
|
||||||
const control = genCarattereControllo(gen);
|
|
||||||
console.log("Generated CF:", gen + control);
|
|
||||||
console.log("Provided CF:", codiceFiscale);
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
gen !== codiceFiscale.slice(0, 15) &&
|
codiceFiscale.slice(0, 15) !== cf.slice(0, 15) &&
|
||||||
!(codiceFiscale in getAlternativeCF(gen))
|
!(codiceFiscale in omocodie)
|
||||||
) {
|
) {
|
||||||
refinementContext.issues.push({
|
refinementContext.issues.push({
|
||||||
code: "custom",
|
code: "custom",
|
||||||
|
|
@ -194,7 +79,7 @@ export const checkFiscalCodeValidity = ({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (control !== codiceFiscale.slice(-1)) {
|
if (codiceFiscale.slice(-1) !== cf.slice(-1)) {
|
||||||
refinementContext.issues.push({
|
refinementContext.issues.push({
|
||||||
code: "custom",
|
code: "custom",
|
||||||
input: "",
|
input: "",
|
||||||
|
|
@ -224,7 +109,7 @@ export const checkFiscalCodeValidity = ({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (codiceFiscale.slice(0, 3) !== calcolaParteCognome(cognomeUpper)) {
|
if (codiceFiscale.slice(0, 3) !== cf.slice(0, 3)) {
|
||||||
refinementContext.issues.push({
|
refinementContext.issues.push({
|
||||||
code: "custom",
|
code: "custom",
|
||||||
input: "",
|
input: "",
|
||||||
|
|
@ -232,7 +117,7 @@ export const checkFiscalCodeValidity = ({
|
||||||
path: [path],
|
path: [path],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (codiceFiscale.slice(3, 6) !== calcolaParteNome(nomeUpper)) {
|
if (codiceFiscale.slice(3, 6) !== cf.slice(3, 6)) {
|
||||||
refinementContext.issues.push({
|
refinementContext.issues.push({
|
||||||
code: "custom",
|
code: "custom",
|
||||||
input: "",
|
input: "",
|
||||||
|
|
@ -241,9 +126,7 @@ export const checkFiscalCodeValidity = ({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (codiceFiscale.slice(6, 8) !== cf.slice(6, 8)) {
|
||||||
codiceFiscale.slice(6, 8) !== dataNascita.getFullYear().toString().slice(-2)
|
|
||||||
) {
|
|
||||||
refinementContext.issues.push({
|
refinementContext.issues.push({
|
||||||
code: "custom",
|
code: "custom",
|
||||||
input: "",
|
input: "",
|
||||||
|
|
@ -252,7 +135,7 @@ export const checkFiscalCodeValidity = ({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (codiceFiscale.slice(8, 9) !== getMonthLetterCF(dataNascita.getMonth())) {
|
if (codiceFiscale.slice(8, 9) !== cf.slice(8, 9)) {
|
||||||
refinementContext.issues.push({
|
refinementContext.issues.push({
|
||||||
code: "custom",
|
code: "custom",
|
||||||
input: "",
|
input: "",
|
||||||
|
|
@ -260,7 +143,7 @@ export const checkFiscalCodeValidity = ({
|
||||||
path: [path],
|
path: [path],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (codiceFiscale.slice(9, 11) !== getDayCF(dataNascita.getDate(), sesso)) {
|
if (codiceFiscale.slice(9, 11) !== cf.slice(9, 11)) {
|
||||||
refinementContext.issues.push({
|
refinementContext.issues.push({
|
||||||
code: "custom",
|
code: "custom",
|
||||||
input: "",
|
input: "",
|
||||||
|
|
|
||||||
10
apps/infoalloggi/vitest.config.mts
Normal file
10
apps/infoalloggi/vitest.config.mts
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
import react from "@vitejs/plugin-react";
|
||||||
|
import tsconfigPaths from "vite-tsconfig-paths";
|
||||||
|
import { defineConfig } from "vitest/config";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [tsconfigPaths(), react()],
|
||||||
|
test: {
|
||||||
|
environment: "jsdom",
|
||||||
|
},
|
||||||
|
});
|
||||||
Loading…
Add table
Reference in a new issue