catasto
This commit is contained in:
parent
306be40555
commit
219f76dd10
16 changed files with 827 additions and 41077 deletions
|
|
@ -18,11 +18,7 @@ import {
|
|||
} from "~/components/custom_ui/form";
|
||||
import Input from "~/components/custom_ui/input";
|
||||
import InputWIcon from "~/components/custom_ui/input-icon";
|
||||
import {
|
||||
MultiSelect,
|
||||
RepackValues,
|
||||
UnpackOptions,
|
||||
} from "~/components/custom_ui/multiselect";
|
||||
import { MultiSelect, UnpackOptions } from "~/components/custom_ui/multiselect";
|
||||
import { PhoneInput } from "~/components/phone-input";
|
||||
import { Badge } from "~/components/ui/badge";
|
||||
import { Button } from "~/components/ui/button";
|
||||
|
|
@ -49,12 +45,16 @@ import {
|
|||
TooltipProvider,
|
||||
TooltipTrigger,
|
||||
} from "~/components/ui/tooltip";
|
||||
import { getComuni } from "~/i18n/comuni";
|
||||
import { GetNazioni } from "~/i18n/nazioni";
|
||||
import { getProvinciaFromSigla, provincieWithSigla } from "~/i18n/provincie";
|
||||
import { checkFiscalCodeValidity, getComuneFieldValue } from "~/lib/form_utils";
|
||||
import {
|
||||
getProvinciaFromSigla,
|
||||
ITALY_CATASTO_CODE,
|
||||
parseDBComune,
|
||||
parseDBNazione,
|
||||
} from "~/lib/catasto";
|
||||
import { checkFiscalCodeValidity } from "~/lib/form_utils";
|
||||
import { cn } from "~/lib/utils";
|
||||
import { useZodForm } from "~/lib/zodForm";
|
||||
import { useCatasto } from "~/providers/CatastoProvider";
|
||||
import { useTranslation } from "~/providers/I18nProvider";
|
||||
import type { Servizio } from "~/schemas/public/Servizio";
|
||||
import TipologiaPosizioneEnum from "~/schemas/public/TipologiaPosizioneEnum";
|
||||
|
|
@ -75,8 +75,8 @@ const FormNewServizioSchema = z.object({
|
|||
azienda: z.boolean(),
|
||||
budget: z.number().positive(),
|
||||
cap_recapiti: z.string().length(5),
|
||||
citta_recapiti: z.string().nonempty("Inserisci una città"),
|
||||
civico_recapiti: z.string().nonempty("Inserisci un civico"),
|
||||
citta_recapiti: z.string().nullable(),
|
||||
civico_recapiti: z.string(),
|
||||
codice_destinatario: z.string().nullable(),
|
||||
codice_fiscale: z.string(),
|
||||
cognome: z.string().nonempty("Inserisci un cognome valido"),
|
||||
|
|
@ -88,22 +88,18 @@ const FormNewServizioSchema = z.object({
|
|||
giardino: z.boolean(),
|
||||
indirizzo_recapiti: z.string().nonempty("Inserisci un indirizzo"),
|
||||
legale_rappresentante: z.string().nullable(),
|
||||
luogo_nascita: z.string(),
|
||||
luogo_nascita: z.string().nullable(),
|
||||
motivazione_transitorio: z.string().nullable(),
|
||||
n_adulti: z.number().min(1),
|
||||
n_minori: z.number(),
|
||||
nazione_nascita: z.string(),
|
||||
nazione_recapiti: z
|
||||
.string()
|
||||
.refine((v) => v !== "", { params: { type: "nazione" } }),
|
||||
nazione_nascita: z.string().nullable(),
|
||||
nazione_recapiti: z.string().nullable(),
|
||||
nome: z.string().nonempty("Inserisci un nome valido"),
|
||||
p_iva: z.string().nullable(),
|
||||
parcheggio: z.boolean(),
|
||||
permanenza: z.number().nullable(),
|
||||
pianoterra: z.boolean(),
|
||||
provincia_recapiti: z
|
||||
.string()
|
||||
.refine((v) => v !== "", { params: { type: "provincia" } }),
|
||||
provincia_recapiti: z.string().nullable(),
|
||||
ragione_sociale: z.string().nullable(),
|
||||
reddito: z.string().nullable(),
|
||||
sede_legale: z.string().nullable(),
|
||||
|
|
@ -126,6 +122,7 @@ export const FormNewServizioAcquisto = ({
|
|||
isAdmin?: boolean;
|
||||
}) => {
|
||||
const router = useRouter();
|
||||
const { comuni, nazioni } = useCatasto();
|
||||
const schema = FormNewServizioSchema.superRefine(
|
||||
(
|
||||
{
|
||||
|
|
@ -150,6 +147,9 @@ export const FormNewServizioAcquisto = ({
|
|||
ragione_sociale,
|
||||
fatturazione_aziendale,
|
||||
codice_destinatario,
|
||||
citta_recapiti,
|
||||
nazione_recapiti,
|
||||
provincia_recapiti,
|
||||
},
|
||||
refinementContext,
|
||||
) => {
|
||||
|
|
@ -212,8 +212,50 @@ export const FormNewServizioAcquisto = ({
|
|||
input: "",
|
||||
message:
|
||||
"Il numero di telefono deve essere lungo almeno 10 caratteri",
|
||||
path: ["telefono"],
|
||||
});
|
||||
}
|
||||
if (!luogo_nascita || luogo_nascita.length < 1) {
|
||||
refinementContext.issues.push({
|
||||
code: "custom",
|
||||
input: "",
|
||||
message: "Inserisci il luogo di nascita",
|
||||
path: ["luogo_nascita"],
|
||||
});
|
||||
}
|
||||
if (!nazione_nascita || nazione_nascita.length < 1) {
|
||||
refinementContext.issues.push({
|
||||
code: "custom",
|
||||
input: "",
|
||||
message: "Inserisci la nazione di nascita",
|
||||
path: ["nazione_nascita"],
|
||||
});
|
||||
}
|
||||
if (!citta_recapiti || citta_recapiti.length < 1) {
|
||||
refinementContext.issues.push({
|
||||
code: "custom",
|
||||
input: "",
|
||||
message: "Inserisci la città di recapiti",
|
||||
path: ["citta_recapiti"],
|
||||
});
|
||||
}
|
||||
if (!nazione_recapiti || nazione_recapiti.length < 1) {
|
||||
refinementContext.issues.push({
|
||||
code: "custom",
|
||||
input: "",
|
||||
message: "Inserisci la nazione di recapiti",
|
||||
path: ["nazione_recapiti"],
|
||||
});
|
||||
}
|
||||
if (!provincia_recapiti || provincia_recapiti.length < 1) {
|
||||
refinementContext.issues.push({
|
||||
code: "custom",
|
||||
input: "",
|
||||
message: "Inserisci la provincia di recapiti",
|
||||
path: ["provincia_recapiti"],
|
||||
});
|
||||
}
|
||||
if (luogo_nascita && nazione_nascita) {
|
||||
checkFiscalCodeValidity({
|
||||
codiceFiscale: codice_fiscale,
|
||||
cognome,
|
||||
|
|
@ -224,7 +266,10 @@ export const FormNewServizioAcquisto = ({
|
|||
path: "codice_fiscale",
|
||||
refinementContext,
|
||||
sesso,
|
||||
comuneCatasto: comuni.find((c) => c.catasto === luogo_nascita),
|
||||
nazioneCatasto: nazioni.find((c) => c.catasto === nazione_nascita),
|
||||
});
|
||||
}
|
||||
if (n_adulti <= 0) {
|
||||
refinementContext.issues.push({
|
||||
code: "custom",
|
||||
|
|
@ -287,7 +332,7 @@ export const FormNewServizioAcquisto = ({
|
|||
...initialData.userData,
|
||||
azienda: initialData.anagrafica?.azienda || false,
|
||||
cap_recapiti: initialData.anagrafica?.cap_residenza || "",
|
||||
citta_recapiti: initialData.anagrafica?.comune_residenza || "",
|
||||
citta_recapiti: initialData.anagrafica?.comune_residenza || null,
|
||||
civico_recapiti: initialData.anagrafica?.civico_residenza || "",
|
||||
codice_destinatario: initialData.anagrafica?.codice_destinatario || "",
|
||||
codice_fiscale: initialData.anagrafica?.codice_fiscale || "",
|
||||
|
|
@ -298,12 +343,12 @@ export const FormNewServizioAcquisto = ({
|
|||
initialData.anagrafica?.fatturazione_aziendale || false,
|
||||
indirizzo_recapiti: initialData.anagrafica?.via_residenza || "",
|
||||
legale_rappresentante: initialData.anagrafica?.legale_rappresentante || "",
|
||||
luogo_nascita: initialData.anagrafica?.luogo_nascita || "",
|
||||
nazione_nascita: initialData.anagrafica?.nazione_nascita || "",
|
||||
nazione_recapiti: initialData.anagrafica?.nazione_residenza || "",
|
||||
luogo_nascita: initialData.anagrafica?.luogo_nascita || null,
|
||||
nazione_nascita: initialData.anagrafica?.nazione_nascita || null,
|
||||
nazione_recapiti: initialData.anagrafica?.nazione_residenza || null,
|
||||
|
||||
p_iva: initialData.anagrafica?.p_iva || "",
|
||||
provincia_recapiti: initialData.anagrafica?.provincia_residenza || "",
|
||||
provincia_recapiti: initialData.anagrafica?.provincia_residenza || null,
|
||||
ragione_sociale: initialData.anagrafica?.ragione_sociale || "",
|
||||
sede_legale: initialData.anagrafica?.sede_legale || "",
|
||||
sesso: initialData.anagrafica?.sesso || "M",
|
||||
|
|
@ -311,8 +356,6 @@ export const FormNewServizioAcquisto = ({
|
|||
};
|
||||
|
||||
const { locale, t } = useTranslation();
|
||||
const nazioni_options = GetNazioni();
|
||||
const comuni_options = getComuni();
|
||||
z.config(z.locales[locale]());
|
||||
|
||||
const form = useZodForm(schema, {
|
||||
|
|
@ -417,10 +460,9 @@ export const FormNewServizioAcquisto = ({
|
|||
["pianoterra", string],
|
||||
];
|
||||
const altrePrefMapping = t.altrePrefMapping as altrePrefMappingType;
|
||||
const [tipologia, nazione_nascita, nazione_recapiti, budget] = form.watch([
|
||||
const [tipologia, nazione_nascita, budget] = form.watch([
|
||||
"tipologia",
|
||||
"nazione_nascita",
|
||||
"nazione_recapiti",
|
||||
"budget",
|
||||
]);
|
||||
|
||||
|
|
@ -1004,7 +1046,12 @@ export const FormNewServizioAcquisto = ({
|
|||
<FormField
|
||||
control={form.control}
|
||||
name="nazione_nascita"
|
||||
render={({ field }) => (
|
||||
render={({ field }) => {
|
||||
const parsedNazioneNascita = parseDBNazione(
|
||||
field.value,
|
||||
nazioni,
|
||||
);
|
||||
return (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="select-naz-nascita">
|
||||
|
|
@ -1015,34 +1062,50 @@ export const FormNewServizioAcquisto = ({
|
|||
|
||||
<FormControl>
|
||||
<MultiSelect
|
||||
defaultValue={RepackValues({
|
||||
options: nazioni_options,
|
||||
values: field.value,
|
||||
})}
|
||||
defaultValue={
|
||||
field.value
|
||||
? parsedNazioneNascita
|
||||
? {
|
||||
label: parsedNazioneNascita.nome,
|
||||
value: parsedNazioneNascita.catasto,
|
||||
}
|
||||
: {
|
||||
label: field.value,
|
||||
value: field.value,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
elementId="select-naz-nascita"
|
||||
elementName="nazioneNascita"
|
||||
isMulti={false}
|
||||
onValueChange={async (value) => {
|
||||
field.onChange(value.value);
|
||||
await form.trigger("luogo_nascita");
|
||||
if (value.value !== "0") {
|
||||
form.setValue("luogo_nascita", "");
|
||||
}
|
||||
|
||||
form.setValue("luogo_nascita", null);
|
||||
}}
|
||||
options={UnpackOptions({ options: nazioni_options })}
|
||||
options={nazioni.map((n) => ({
|
||||
label: n.nome,
|
||||
value: n.catasto,
|
||||
}))}
|
||||
placeholder="Seleziona..."
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
)}
|
||||
);
|
||||
}}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="luogo_nascita"
|
||||
render={({ field }) => {
|
||||
if (nazione_nascita === "0") {
|
||||
const options = comuni_options.map((c) => c.nome);
|
||||
if (nazione_nascita === ITALY_CATASTO_CODE) {
|
||||
const parsedComuneNascita = parseDBComune(
|
||||
field.value,
|
||||
comuni,
|
||||
);
|
||||
|
||||
return (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
|
|
@ -1054,18 +1117,32 @@ export const FormNewServizioAcquisto = ({
|
|||
|
||||
<FormControl>
|
||||
<MultiSelect
|
||||
defaultValue={getComuneFieldValue(
|
||||
field.value,
|
||||
options,
|
||||
)}
|
||||
defaultValue={
|
||||
field.value
|
||||
? parsedComuneNascita
|
||||
? {
|
||||
label: `${parsedComuneNascita.nome} (${parsedComuneNascita.sigla})`,
|
||||
value: parsedComuneNascita.catasto,
|
||||
}
|
||||
: {
|
||||
label: field.value,
|
||||
value: field.value,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
elementId="select-comune-nascita"
|
||||
elementName="luogoNascita"
|
||||
isMulti={false}
|
||||
onValueChange={async (value) => {
|
||||
field.onChange(value.value);
|
||||
await form.trigger("luogo_nascita");
|
||||
|
||||
await form.trigger("codice_fiscale");
|
||||
}}
|
||||
options={UnpackOptions({ options })}
|
||||
options={comuni.map((c) => ({
|
||||
label: `${c.nome} (${c.sigla})`,
|
||||
value: c.catasto,
|
||||
}))}
|
||||
placeholder="Seleziona..."
|
||||
/>
|
||||
</FormControl>
|
||||
|
|
@ -1087,8 +1164,10 @@ export const FormNewServizioAcquisto = ({
|
|||
onChange={async (v) => {
|
||||
field.onChange(v.target.value);
|
||||
await form.trigger("luogo_nascita");
|
||||
await form.trigger("codice_fiscale");
|
||||
}}
|
||||
type="text"
|
||||
value={field.value || undefined}
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
|
|
@ -1204,179 +1283,11 @@ export const FormNewServizioAcquisto = ({
|
|||
/>
|
||||
</div>
|
||||
<Separator />
|
||||
<div className="flex w-full flex-col items-start justify-between gap-4 sm:flex-row">
|
||||
<FormField
|
||||
<ResidenzaSection
|
||||
control={form.control}
|
||||
name="nazione_recapiti"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="select-naz">
|
||||
{t.recapiti.nazione}
|
||||
</FormLabel>
|
||||
<FormMessage />
|
||||
</div>
|
||||
|
||||
<FormControl>
|
||||
<MultiSelect
|
||||
defaultValue={RepackValues({
|
||||
options: nazioni_options,
|
||||
values: field.value,
|
||||
})}
|
||||
elementId="select-naz"
|
||||
elementName="nazioneRecapiti"
|
||||
isMulti={false}
|
||||
onValueChange={async (value) => {
|
||||
field.onChange(value.value);
|
||||
form.setValue("provincia_recapiti", "");
|
||||
if (value.value !== "0") {
|
||||
form.setValue("citta_recapiti", "");
|
||||
}
|
||||
}}
|
||||
options={UnpackOptions({ options: nazioni_options })}
|
||||
placeholder="Seleziona..."
|
||||
setValue={form.setValue}
|
||||
trigger={form.trigger}
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="provincia_recapiti"
|
||||
render={({ field }) => {
|
||||
const provinciaName =
|
||||
field.value && getProvinciaFromSigla(field.value);
|
||||
return (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="provinciaRecapiti">
|
||||
{t.recapiti.provincia}
|
||||
</FormLabel>
|
||||
<FormMessage />
|
||||
</div>
|
||||
|
||||
{nazione_recapiti === "0" ? (
|
||||
<MultiSelect
|
||||
defaultValue={
|
||||
field.value && provinciaName
|
||||
? {
|
||||
label: provinciaName,
|
||||
value: field.value,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
elementId="provinciaRecapiti"
|
||||
elementName="provincia"
|
||||
isMulti={false}
|
||||
onValueChange={(value) => {
|
||||
field.onChange(value.value);
|
||||
}}
|
||||
options={provincieWithSigla.map((prov) => ({
|
||||
label: prov.nome,
|
||||
value: prov.sigla,
|
||||
}))}
|
||||
placeholder="Seleziona"
|
||||
/>
|
||||
) : (
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
id="provinciaRecapiti"
|
||||
type="text"
|
||||
/>
|
||||
</FormControl>
|
||||
)}
|
||||
</FormItem>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex w-full flex-col items-start justify-between gap-4 sm:flex-row">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="citta_recapiti"
|
||||
render={({ field }) => {
|
||||
if (nazione_recapiti === "0") {
|
||||
const provincia = form.watch("provincia_recapiti");
|
||||
const options = comuni_options
|
||||
.filter((comune) =>
|
||||
provincia ? comune.provincia === provincia : true,
|
||||
)
|
||||
.map((comune) => comune.nome);
|
||||
return (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="select-comune">
|
||||
{t.recapiti.comune}
|
||||
</FormLabel>
|
||||
<FormMessage />
|
||||
</div>
|
||||
|
||||
<FormControl>
|
||||
<MultiSelect
|
||||
defaultValue={getComuneFieldValue(
|
||||
field.value,
|
||||
options,
|
||||
)}
|
||||
elementId="select-comune"
|
||||
elementName="citta_recapiti"
|
||||
isMulti={false}
|
||||
onValueChange={async (value) => {
|
||||
field.onChange(value.value);
|
||||
await form.trigger("citta_recapiti");
|
||||
}}
|
||||
options={UnpackOptions({ options })}
|
||||
placeholder="Seleziona..."
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="citta_recapiti">
|
||||
{t.recapiti.comune}
|
||||
</FormLabel>
|
||||
<FormMessage />
|
||||
</div>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
id="citta_recapiti"
|
||||
onChange={async (v) => {
|
||||
field.onChange(v.target.value);
|
||||
await form.trigger("citta_recapiti");
|
||||
}}
|
||||
type="text"
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="cap_recapiti"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="cap">{t.recapiti.cap}</FormLabel>
|
||||
|
||||
<FormMessage />
|
||||
</div>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
id="cap"
|
||||
placeholder="00100"
|
||||
type="text"
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex w-full flex-col items-start justify-between gap-4 sm:flex-row">
|
||||
<FormField
|
||||
control={form.control}
|
||||
|
|
@ -1653,3 +1564,229 @@ const FatturazioneSection = ({
|
|||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const ResidenzaSection = ({
|
||||
control,
|
||||
trigger,
|
||||
setValue,
|
||||
}: {
|
||||
control: Control<FormNewServizioValues>;
|
||||
trigger: (name?: keyof FormNewServizioValues) => Promise<boolean>;
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <fine here>
|
||||
setValue: (field: keyof FormNewServizioValues, value: any) => void;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const { comuni, nazioni, provincie } = useCatasto();
|
||||
|
||||
const nazione_recapiti = useWatch({
|
||||
control,
|
||||
name: "nazione_recapiti",
|
||||
});
|
||||
const provincia_recapiti = useWatch({
|
||||
control,
|
||||
name: "provincia_recapiti",
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex w-full flex-col items-start justify-between gap-4 sm:flex-row">
|
||||
<FormField
|
||||
control={control}
|
||||
name="nazione_recapiti"
|
||||
render={({ field }) => {
|
||||
const parsedNazioneResidenza = parseDBNazione(field.value, nazioni);
|
||||
return (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="select-naz">
|
||||
{t.recapiti.nazione}
|
||||
</FormLabel>
|
||||
<FormMessage />
|
||||
</div>
|
||||
|
||||
<FormControl>
|
||||
<MultiSelect
|
||||
defaultValue={
|
||||
field.value
|
||||
? parsedNazioneResidenza
|
||||
? {
|
||||
label: parsedNazioneResidenza.nome,
|
||||
value: parsedNazioneResidenza.catasto,
|
||||
}
|
||||
: {
|
||||
label: field.value,
|
||||
value: field.value,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
elementId="select-naz"
|
||||
elementName="nazioneRecapiti"
|
||||
isMulti={false}
|
||||
onValueChange={async (value) => {
|
||||
setValue("provincia_recapiti", null);
|
||||
setValue("citta_recapiti", null);
|
||||
field.onChange(value.value);
|
||||
await trigger("citta_recapiti");
|
||||
}}
|
||||
options={nazioni.map((n) => ({
|
||||
label: n.nome,
|
||||
value: n.catasto,
|
||||
}))}
|
||||
placeholder="Seleziona..."
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<FormField
|
||||
control={control}
|
||||
name="provincia_recapiti"
|
||||
render={({ field }) => {
|
||||
const parseProvincia = getProvinciaFromSigla(
|
||||
field.value,
|
||||
provincie,
|
||||
);
|
||||
return (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="provinciaRecapiti">
|
||||
{t.recapiti.provincia}
|
||||
</FormLabel>
|
||||
<FormMessage />
|
||||
</div>
|
||||
|
||||
{nazione_recapiti === ITALY_CATASTO_CODE ? (
|
||||
<MultiSelect
|
||||
defaultValue={
|
||||
field.value && parseProvincia
|
||||
? {
|
||||
label: parseProvincia.nome,
|
||||
value: parseProvincia.sigla,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
elementId="provinciaRecapiti"
|
||||
elementName="provincia"
|
||||
isMulti={false}
|
||||
onValueChange={(value) => {
|
||||
field.onChange(value.value);
|
||||
setValue("citta_recapiti", null);
|
||||
}}
|
||||
options={provincie.map((prov) => ({
|
||||
label: prov.nome,
|
||||
value: prov.sigla,
|
||||
}))}
|
||||
placeholder="Seleziona"
|
||||
/>
|
||||
) : (
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
id="provinciaRecapiti"
|
||||
type="text"
|
||||
value={field.value || undefined}
|
||||
/>
|
||||
</FormControl>
|
||||
)}
|
||||
</FormItem>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex w-full flex-col items-start justify-between gap-4 sm:flex-row">
|
||||
<FormField
|
||||
control={control}
|
||||
name="citta_recapiti"
|
||||
render={({ field }) => {
|
||||
if (nazione_recapiti === ITALY_CATASTO_CODE) {
|
||||
const parsedComuneResidenza = parseDBComune(field.value, comuni);
|
||||
|
||||
const options = comuni
|
||||
.filter((comune) =>
|
||||
provincia_recapiti
|
||||
? comune.sigla === provincia_recapiti
|
||||
: true,
|
||||
)
|
||||
.map((comune) => ({
|
||||
label: comune.nome,
|
||||
value: comune.catasto,
|
||||
}));
|
||||
|
||||
return (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="select-comune">
|
||||
{t.recapiti.comune}
|
||||
</FormLabel>
|
||||
<FormMessage />
|
||||
</div>
|
||||
|
||||
<FormControl>
|
||||
<MultiSelect
|
||||
defaultValue={
|
||||
field.value && parsedComuneResidenza
|
||||
? {
|
||||
label: parsedComuneResidenza.nome,
|
||||
value: parsedComuneResidenza.catasto,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
elementId="select-comune"
|
||||
elementName="citta_recapiti"
|
||||
isMulti={false}
|
||||
onValueChange={async (value) => {
|
||||
field.onChange(value.value);
|
||||
await trigger("citta_recapiti");
|
||||
}}
|
||||
options={options}
|
||||
placeholder="Seleziona..."
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="citta_recapiti">
|
||||
{t.recapiti.comune}
|
||||
</FormLabel>
|
||||
<FormMessage />
|
||||
</div>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
id="citta_recapiti"
|
||||
onChange={async (v) => {
|
||||
field.onChange(v.target.value);
|
||||
await trigger("citta_recapiti");
|
||||
}}
|
||||
type="text"
|
||||
value={field.value || undefined}
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<FormField
|
||||
control={control}
|
||||
name="cap_recapiti"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="cap">{t.recapiti.cap}</FormLabel>
|
||||
|
||||
<FormMessage />
|
||||
</div>
|
||||
<FormControl>
|
||||
<Input {...field} id="cap" placeholder="00100" type="text" />
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,11 +13,7 @@ import {
|
|||
FormMessage,
|
||||
} from "~/components/custom_ui/form";
|
||||
import Input from "~/components/custom_ui/input";
|
||||
import {
|
||||
MultiSelect,
|
||||
RepackValues,
|
||||
UnpackOptions,
|
||||
} from "~/components/custom_ui/multiselect";
|
||||
import { MultiSelect } from "~/components/custom_ui/multiselect";
|
||||
import { Button } from "~/components/ui/button";
|
||||
import { Calendar } from "~/components/ui/calendar";
|
||||
import {
|
||||
|
|
@ -27,12 +23,16 @@ import {
|
|||
} from "~/components/ui/popover";
|
||||
import { Separator } from "~/components/ui/separator";
|
||||
import { Switch } from "~/components/ui/switch";
|
||||
import { getComuni } from "~/i18n/comuni";
|
||||
import { GetNazioni } from "~/i18n/nazioni";
|
||||
import { getProvinciaFromSigla, provincieWithSigla } from "~/i18n/provincie";
|
||||
import { checkFiscalCodeValidity, getComuneFieldValue } from "~/lib/form_utils";
|
||||
import {
|
||||
getProvinciaFromSigla,
|
||||
ITALY_CATASTO_CODE,
|
||||
parseDBComune,
|
||||
parseDBNazione,
|
||||
} from "~/lib/catasto";
|
||||
import { checkFiscalCodeValidity } from "~/lib/form_utils";
|
||||
import { cn } from "~/lib/utils";
|
||||
import { useZodForm } from "~/lib/zodForm";
|
||||
import { useCatasto } from "~/providers/CatastoProvider";
|
||||
import { useTranslation } from "~/providers/I18nProvider";
|
||||
import type { UserWithAnagrafica } from "~/server/services/user.service";
|
||||
import { api } from "~/utils/api";
|
||||
|
|
@ -43,15 +43,15 @@ const profileFormSchema = z.object({
|
|||
civico_residenza: z.string().optional(),
|
||||
codice_destinatario: z.string().length(7).nullable(),
|
||||
codice_fiscale: z.string().optional(),
|
||||
comune_residenza: z.string().optional(),
|
||||
comune_residenza: z.string().nullable(),
|
||||
data_nascita: z.date().optional(),
|
||||
fatturazione_aziendale: z.boolean(),
|
||||
legale_rappresentante: z.string().nullable(),
|
||||
luogo_nascita: z.string().optional(),
|
||||
nazione_nascita: z.string().optional(),
|
||||
nazione_residenza: z.string().optional(),
|
||||
luogo_nascita: z.string().nullable(),
|
||||
nazione_nascita: z.string().nullable(),
|
||||
nazione_residenza: z.string().nullable(),
|
||||
p_iva: z.string().nullable(),
|
||||
provincia_residenza: z.string().optional(),
|
||||
provincia_residenza: z.string().nullable(),
|
||||
ragione_sociale: z.string().nullable(),
|
||||
sede_legale: z.string().nullable(),
|
||||
sesso: z.string().optional(),
|
||||
|
|
@ -64,6 +64,8 @@ export const ProfileFormAnagrafica = ({
|
|||
}: {
|
||||
userData: UserWithAnagrafica;
|
||||
}) => {
|
||||
const { comuni, nazioni } = useCatasto();
|
||||
|
||||
const schema = profileFormSchema.superRefine(
|
||||
(
|
||||
{
|
||||
|
|
@ -167,6 +169,8 @@ export const ProfileFormAnagrafica = ({
|
|||
path: "codice_fiscale",
|
||||
refinementContext,
|
||||
sesso,
|
||||
comuneCatasto: comuni.find((c) => c.catasto === luogo_nascita),
|
||||
nazioneCatasto: nazioni.find((c) => c.catasto === nazione_nascita),
|
||||
});
|
||||
}
|
||||
},
|
||||
|
|
@ -178,15 +182,15 @@ export const ProfileFormAnagrafica = ({
|
|||
civico_residenza: userData.civico_residenza || "",
|
||||
codice_destinatario: userData.codice_destinatario || null,
|
||||
codice_fiscale: userData.codice_fiscale || "",
|
||||
comune_residenza: userData.comune_residenza || "",
|
||||
comune_residenza: userData.comune_residenza,
|
||||
data_nascita: userData.data_nascita || new Date(),
|
||||
fatturazione_aziendale: userData.fatturazione_aziendale || false,
|
||||
legale_rappresentante: userData.legale_rappresentante || null,
|
||||
luogo_nascita: userData.luogo_nascita || "",
|
||||
nazione_nascita: userData.nazione_nascita || "",
|
||||
nazione_residenza: userData.nazione_residenza || "",
|
||||
luogo_nascita: userData.luogo_nascita,
|
||||
nazione_nascita: userData.nazione_nascita,
|
||||
nazione_residenza: userData.nazione_residenza,
|
||||
p_iva: userData.p_iva || null,
|
||||
provincia_residenza: userData.provincia_residenza || "",
|
||||
provincia_residenza: userData.provincia_residenza,
|
||||
ragione_sociale: userData.ragione_sociale || null,
|
||||
sede_legale: userData.sede_legale || null,
|
||||
sesso: userData.sesso || "",
|
||||
|
|
@ -222,8 +226,6 @@ export const ProfileFormAnagrafica = ({
|
|||
data: { ...fields },
|
||||
});
|
||||
}
|
||||
const nazioni_options = GetNazioni();
|
||||
const comuni_options = getComuni();
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
@ -288,7 +290,12 @@ export const ProfileFormAnagrafica = ({
|
|||
<FormField
|
||||
control={form.control}
|
||||
name="nazione_nascita"
|
||||
render={({ field }) => (
|
||||
render={({ field }) => {
|
||||
const parsedNazioneNascita = parseDBNazione(
|
||||
field.value,
|
||||
nazioni,
|
||||
);
|
||||
return (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="select-naz">
|
||||
|
|
@ -301,10 +308,15 @@ export const ProfileFormAnagrafica = ({
|
|||
<MultiSelect
|
||||
defaultValue={
|
||||
field.value
|
||||
? RepackValues({
|
||||
options: nazioni_options,
|
||||
values: field.value,
|
||||
})
|
||||
? parsedNazioneNascita
|
||||
? {
|
||||
label: parsedNazioneNascita.nome,
|
||||
value: parsedNazioneNascita.catasto,
|
||||
}
|
||||
: {
|
||||
label: field.value,
|
||||
value: field.value,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
elementId="select-naz"
|
||||
|
|
@ -313,21 +325,29 @@ export const ProfileFormAnagrafica = ({
|
|||
onValueChange={async (value) => {
|
||||
field.onChange(value.value);
|
||||
await form.trigger("luogo_nascita");
|
||||
form.setValue("luogo_nascita", null);
|
||||
}}
|
||||
options={UnpackOptions({ options: nazioni_options })}
|
||||
options={nazioni.map((n) => ({
|
||||
label: n.nome,
|
||||
value: n.catasto,
|
||||
}))}
|
||||
placeholder="Seleziona..."
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
)}
|
||||
);
|
||||
}}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="luogo_nascita"
|
||||
render={({ field }) => {
|
||||
if (form.watch("nazione_nascita") === "0") {
|
||||
const options = comuni_options.map((c) => c.nome);
|
||||
if (form.watch("nazione_nascita") === ITALY_CATASTO_CODE) {
|
||||
const parsedComuneNascita = parseDBComune(
|
||||
field.value,
|
||||
comuni,
|
||||
);
|
||||
return (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
|
|
@ -340,8 +360,11 @@ export const ProfileFormAnagrafica = ({
|
|||
<FormControl>
|
||||
<MultiSelect
|
||||
defaultValue={
|
||||
field.value
|
||||
? getComuneFieldValue(field.value, options)
|
||||
field.value && parsedComuneNascita
|
||||
? {
|
||||
label: `${parsedComuneNascita.nome} (${parsedComuneNascita.sigla})`,
|
||||
value: parsedComuneNascita.catasto,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
elementId="select-comune"
|
||||
|
|
@ -352,7 +375,10 @@ export const ProfileFormAnagrafica = ({
|
|||
await form.trigger("luogo_nascita");
|
||||
await form.trigger("codice_fiscale");
|
||||
}}
|
||||
options={UnpackOptions({ options })}
|
||||
options={comuni.map((c) => ({
|
||||
label: `${c.nome} (${c.sigla})`,
|
||||
value: c.catasto,
|
||||
}))}
|
||||
placeholder="Seleziona..."
|
||||
/>
|
||||
</FormControl>
|
||||
|
|
@ -377,6 +403,7 @@ export const ProfileFormAnagrafica = ({
|
|||
await form.trigger("codice_fiscale");
|
||||
}}
|
||||
type="text"
|
||||
value={field.value || ""}
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
|
|
@ -680,9 +707,9 @@ const ResidenzaSection = ({
|
|||
setValue: (field: keyof ProfileFormValues, value: any) => void;
|
||||
trigger: (name?: keyof ProfileFormValues) => Promise<boolean>;
|
||||
}) => {
|
||||
const { comuni, nazioni, provincie } = useCatasto();
|
||||
const { t } = useTranslation();
|
||||
const nazioni_options = GetNazioni();
|
||||
const comuni_options = getComuni();
|
||||
|
||||
const nazione_residenza = useWatch({
|
||||
control: control,
|
||||
name: "nazione_residenza",
|
||||
|
|
@ -698,7 +725,9 @@ const ResidenzaSection = ({
|
|||
<FormField
|
||||
control={control}
|
||||
name="nazione_residenza"
|
||||
render={({ field }) => (
|
||||
render={({ field }) => {
|
||||
const parsedNazioneResidenza = parseDBNazione(field.value, nazioni);
|
||||
return (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="nazione_residenza">
|
||||
|
|
@ -709,33 +738,45 @@ const ResidenzaSection = ({
|
|||
<MultiSelect
|
||||
defaultValue={
|
||||
field.value
|
||||
? RepackValues({
|
||||
options: nazioni_options,
|
||||
values: field.value,
|
||||
})
|
||||
? parsedNazioneResidenza
|
||||
? {
|
||||
label: parsedNazioneResidenza.nome,
|
||||
value: parsedNazioneResidenza.catasto,
|
||||
}
|
||||
: {
|
||||
label: field.value,
|
||||
value: field.value,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
elementId="nazione_residenza"
|
||||
elementName="nazione"
|
||||
isMulti={false}
|
||||
onValueChange={async (value) => {
|
||||
setValue("provincia_residenza", "");
|
||||
setValue("provincia_residenza", null);
|
||||
setValue("comune_residenza", null);
|
||||
field.onChange(value.value);
|
||||
await trigger("comune_residenza");
|
||||
}}
|
||||
options={UnpackOptions({ options: nazioni_options })}
|
||||
options={nazioni.map((n) => ({
|
||||
label: n.nome,
|
||||
value: n.catasto,
|
||||
}))}
|
||||
placeholder="Seleziona"
|
||||
/>
|
||||
</FormItem>
|
||||
)}
|
||||
);
|
||||
}}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={control}
|
||||
name="provincia_residenza"
|
||||
render={({ field }) => {
|
||||
const provinciaName =
|
||||
field.value && getProvinciaFromSigla(field.value);
|
||||
const parseProvincia = getProvinciaFromSigla(
|
||||
field.value,
|
||||
provincie,
|
||||
);
|
||||
return (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
|
|
@ -745,13 +786,13 @@ const ResidenzaSection = ({
|
|||
<FormMessage />
|
||||
</div>
|
||||
|
||||
{nazione_residenza === "0" ? (
|
||||
{nazione_residenza === ITALY_CATASTO_CODE ? (
|
||||
<MultiSelect
|
||||
defaultValue={
|
||||
field.value && provinciaName
|
||||
field.value && parseProvincia
|
||||
? {
|
||||
label: provinciaName,
|
||||
value: field.value,
|
||||
label: parseProvincia.nome,
|
||||
value: parseProvincia.sigla,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
|
|
@ -760,8 +801,9 @@ const ResidenzaSection = ({
|
|||
isMulti={false}
|
||||
onValueChange={(value) => {
|
||||
field.onChange(value.value);
|
||||
setValue("comune_residenza", null);
|
||||
}}
|
||||
options={provincieWithSigla.map((prov) => ({
|
||||
options={provincie.map((prov) => ({
|
||||
label: prov.nome,
|
||||
value: prov.sigla,
|
||||
}))}
|
||||
|
|
@ -769,7 +811,12 @@ const ResidenzaSection = ({
|
|||
/>
|
||||
) : (
|
||||
<FormControl>
|
||||
<Input {...field} id="provincia_residenza" type="text" />
|
||||
<Input
|
||||
{...field}
|
||||
id="provincia_residenza"
|
||||
type="text"
|
||||
value={field.value || undefined}
|
||||
/>
|
||||
</FormControl>
|
||||
)}
|
||||
</FormItem>
|
||||
|
|
@ -782,14 +829,19 @@ const ResidenzaSection = ({
|
|||
control={control}
|
||||
name="comune_residenza"
|
||||
render={({ field }) => {
|
||||
if (nazione_residenza === "0") {
|
||||
const options = comuni_options
|
||||
if (nazione_residenza === ITALY_CATASTO_CODE) {
|
||||
const parsedComuneResidenza = parseDBComune(field.value, comuni);
|
||||
|
||||
const options = comuni
|
||||
.filter((comune) =>
|
||||
provincia_residenza
|
||||
? comune.provincia === provincia_residenza
|
||||
? comune.sigla === provincia_residenza
|
||||
: true,
|
||||
)
|
||||
.map((comune) => comune.nome);
|
||||
.map((comune) => ({
|
||||
label: comune.nome,
|
||||
value: comune.catasto,
|
||||
}));
|
||||
|
||||
return (
|
||||
<FormItem className="w-full">
|
||||
|
|
@ -803,8 +855,11 @@ const ResidenzaSection = ({
|
|||
<FormControl>
|
||||
<MultiSelect
|
||||
defaultValue={
|
||||
field.value
|
||||
? getComuneFieldValue(field.value, options)
|
||||
field.value && parsedComuneResidenza
|
||||
? {
|
||||
label: parsedComuneResidenza.nome,
|
||||
value: parsedComuneResidenza.catasto,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
elementId="select-comune"
|
||||
|
|
@ -814,9 +869,7 @@ const ResidenzaSection = ({
|
|||
field.onChange(value.value);
|
||||
await trigger("comune_residenza");
|
||||
}}
|
||||
options={UnpackOptions({
|
||||
options: options,
|
||||
})}
|
||||
options={options}
|
||||
placeholder="Seleziona..."
|
||||
/>
|
||||
</FormControl>
|
||||
|
|
@ -841,6 +894,7 @@ const ResidenzaSection = ({
|
|||
await trigger("comune_residenza");
|
||||
}}
|
||||
type="text"
|
||||
value={field.value || undefined}
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,120 +0,0 @@
|
|||
|
||||
export const getProvinciaFromSigla = (sigla: string): string | undefined => {
|
||||
const provincia = provincieWithSigla.find((prov) => prov.sigla === sigla);
|
||||
return provincia ? provincia.nome : undefined;
|
||||
}
|
||||
export const provincieWithSigla: {
|
||||
nome: string;
|
||||
sigla: string;
|
||||
}[] = [
|
||||
{nome: "AGRIGENTO",sigla: "AG"},
|
||||
{nome: "ALESSANDRIA",sigla: "AL"},
|
||||
{nome: "ANCONA",sigla: "AN"},
|
||||
{nome: "AOSTA",sigla: "AO"},
|
||||
{nome: "AREZZO",sigla: "AR"},
|
||||
{nome: "ASCOLI PICENO",sigla: "AP"},
|
||||
{nome: "ASTI",sigla: "AT"},
|
||||
{nome: "AVELLINO",sigla: "AV"},
|
||||
{nome: "BARI",sigla: "BA"},
|
||||
{nome: "BARLETTA-ANDRIA-TRANI",sigla: "BT"},
|
||||
{nome: "BELLUNO",sigla: "BL"},
|
||||
{nome: "BENEVENTO",sigla: "BN"},
|
||||
{nome: "BERGAMO",sigla: "BG"},
|
||||
{nome: "BIELLA",sigla: "BI"},
|
||||
{nome: "BOLOGNA",sigla: "BO"},
|
||||
{nome: "BOLZANO",sigla: "BZ"},
|
||||
{nome: "BRESCIA",sigla: "BS"},
|
||||
{nome: "BRINDISI",sigla: "BR"},
|
||||
{nome: "CAGLIARI",sigla: "CA"},
|
||||
{nome: "CALTANISSETTA",sigla: "CL"},
|
||||
{nome: "CAMPOBASSO",sigla: "CB"},
|
||||
{nome: "CARBONIA-IGLESIAS",sigla: "CI"},
|
||||
{nome: "CASERTA",sigla: "CE"},
|
||||
{nome: "CATANIA",sigla: "CT"},
|
||||
{nome: "CATANZARO",sigla: "CZ"},
|
||||
{nome: "CHIETI",sigla: "CH"},
|
||||
{nome: "COMO",sigla: "CO"},
|
||||
{nome: "COSENZA",sigla: "CS"},
|
||||
{nome: "CREMONA",sigla: "CR"},
|
||||
{nome: "CROTONE",sigla: "KR"},
|
||||
{nome: "CUNEO",sigla: "CN"},
|
||||
{nome: "ENNA",sigla: "EN"},
|
||||
{nome: "FERMO",sigla: "FM"},
|
||||
{nome: "FERRARA",sigla: "FE"},
|
||||
{nome: "FIRENZE",sigla: "FI"},
|
||||
{nome: "FOGGIA",sigla: "FG"},
|
||||
{nome: "FORLÌ-CESENA",sigla: "FC"},
|
||||
{nome: "FROSINONE",sigla: "FR"},
|
||||
{nome: "GENOVA",sigla: "GE"},
|
||||
{nome: "GORIZIA",sigla: "GO"},
|
||||
{nome: "GROSSETO",sigla: "GR"},
|
||||
{nome: "IMPERIA",sigla: "IM"},
|
||||
{nome: "ISERNIA",sigla: "IS"},
|
||||
{nome: "LA SPEZIA",sigla: "SP"},
|
||||
{nome: "L'AQUILA",sigla: "AQ"},
|
||||
{nome: "LATINA",sigla: "LT"},
|
||||
{nome: "LECCE",sigla: "LE"},
|
||||
{nome: "LECCO",sigla: "LC"},
|
||||
{nome: "LIVORNO",sigla: "LI"},
|
||||
{nome: "LODI",sigla: "LO"},
|
||||
{nome: "LUCCA",sigla: "LU"},
|
||||
{nome: "MACERATA",sigla: "MC"},
|
||||
{nome: "MANTOVA",sigla: "MN"},
|
||||
{nome: "MASSA-CARRARA",sigla: "MS"},
|
||||
{nome: "MATERA",sigla: "MT"},
|
||||
{nome: "MESSINA",sigla: "ME"},
|
||||
{nome: "MILANO",sigla: "MI"},
|
||||
{nome: "MODENA",sigla: "MO"},
|
||||
{nome: "MONZA E DELLA BRIANZA",sigla: "MB"},
|
||||
{nome: "NAPOLI",sigla: "NA"},
|
||||
{nome: "NOVARA",sigla: "NO"},
|
||||
{nome: "NUORO",sigla: "NU"},
|
||||
{nome: "OLBIA-TEMPIO",sigla: "OT"},
|
||||
{nome: "ORISTANO",sigla: "OR"},
|
||||
{nome: "PADOVA",sigla: "PD"},
|
||||
{nome: "PALERMO",sigla: "PA"},
|
||||
{nome: "PARMA",sigla: "PR"},
|
||||
{nome: "PAVIA",sigla: "PV"},
|
||||
{nome: "PERUGIA",sigla: "PG"},
|
||||
{nome: "PESARO E URBINO",sigla: "PU"},
|
||||
{nome: "PESCARA",sigla: "PE"},
|
||||
{nome: "PIACENZA",sigla: "PC"},
|
||||
{nome: "PISA",sigla: "PI"},
|
||||
{nome: "PISTOIA",sigla: "PT"},
|
||||
{nome: "PORDENONE",sigla: "PN"},
|
||||
{nome: "POTENZA",sigla: "PZ"},
|
||||
{nome: "PRATO",sigla: "PO"},
|
||||
{nome: "RAGUSA",sigla: "RG"},
|
||||
{nome: "RAVENNA",sigla: "RA"},
|
||||
{nome: "REGGIO CALABRIA",sigla: "RC"},
|
||||
{nome: "REGGIO EMILIA",sigla: "RE"},
|
||||
{nome: "RIETI",sigla: "RI"},
|
||||
{nome: "RIMINI",sigla: "RN"},
|
||||
{nome: "ROMA",sigla: "RM"},
|
||||
{nome: "ROVIGO",sigla: "RO"},
|
||||
{nome: "SALERNO",sigla: "SA"},
|
||||
{nome: "MEDIO CAMPIDANO",sigla: "VS"},
|
||||
{nome: "SASSARI",sigla: "SS"},
|
||||
{nome: "SAVONA",sigla: "SV"},
|
||||
{nome: "SIENA",sigla: "SI"},
|
||||
{nome: "SIRACUSA",sigla: "SR"},
|
||||
{nome: "SONDRIO",sigla: "SO"},
|
||||
{nome: "TARANTO",sigla: "TA"},
|
||||
{nome: "TERAMO",sigla: "TE"},
|
||||
{nome: "TERNI",sigla: "TR"},
|
||||
{nome: "TORINO",sigla: "TO"},
|
||||
{nome: "OGLIASTRA",sigla: "OG"},
|
||||
{nome: "TRAPANI",sigla: "TP"},
|
||||
{nome: "TRENTO",sigla: "TN"},
|
||||
{nome: "TREVISO",sigla: "TV"},
|
||||
{nome: "TRIESTE",sigla: "TS"},
|
||||
{nome: "UDINE",sigla: "UD"},
|
||||
{nome: "VARESE",sigla: "VA"},
|
||||
{nome: "VENEZIA",sigla: "VE"},
|
||||
{nome: "VERBANO-CUSIO-OSSOLA",sigla: "VB"},
|
||||
{nome: "VERCELLI",sigla: "VC"},
|
||||
{nome: "VERONA",sigla: "VR"},
|
||||
{nome: "VIBO VALENTIA",sigla: "VV"},
|
||||
{nome: "VICENZA",sigla: "VI"},
|
||||
{nome: "VITERBO",sigla: "VT"}
|
||||
];
|
||||
60
apps/infoalloggi/src/lib/catasto.ts
Normal file
60
apps/infoalloggi/src/lib/catasto.ts
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
import type { Comuni } from "~/schemas/public/Comuni";
|
||||
import type { Nazioni } from "~/schemas/public/Nazioni";
|
||||
import type { Provincie } from "~/schemas/public/Provincie";
|
||||
|
||||
export const ITALY_CATASTO_CODE = "0000";
|
||||
export const isNazioneCatastoValid = (str: string) => {
|
||||
if (str.length !== 4) return false;
|
||||
if (str === ITALY_CATASTO_CODE) return true;
|
||||
return /^Z[0-9]{3}$/.test(str);
|
||||
};
|
||||
|
||||
export const isComuneCatastoValid = (str: string) => {
|
||||
if (str.length !== 4) return false;
|
||||
return /^[A-Z][0-9]{3}$/.test(str);
|
||||
};
|
||||
|
||||
export const getComuneFromCatasto = (
|
||||
codice_catasto: string,
|
||||
comuni_options: Comuni[],
|
||||
): Comuni | undefined => {
|
||||
return comuni_options.find((c) => c.catasto === codice_catasto);
|
||||
};
|
||||
|
||||
export const getNazioneFromCatasto = (
|
||||
codice_catasto: string,
|
||||
nazioni_options: Nazioni[],
|
||||
): Nazioni | undefined => {
|
||||
return nazioni_options.find((n) => n.catasto === codice_catasto);
|
||||
};
|
||||
|
||||
export const parseDBComune = (
|
||||
db_value: string | null,
|
||||
comuni: Comuni[],
|
||||
): Comuni | undefined => {
|
||||
if (!db_value) return undefined;
|
||||
if (isComuneCatastoValid(db_value)) {
|
||||
return getComuneFromCatasto(db_value, comuni);
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
export const parseDBNazione = (
|
||||
db_value: string | null,
|
||||
nazioni: Nazioni[],
|
||||
): Nazioni | undefined => {
|
||||
if (!db_value) return undefined;
|
||||
if (isNazioneCatastoValid(db_value)) {
|
||||
return getNazioneFromCatasto(db_value, nazioni);
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
export const getProvinciaFromSigla = (
|
||||
str: string | null,
|
||||
provincie: Provincie[],
|
||||
): Provincie | undefined => {
|
||||
if (!str) return undefined;
|
||||
if (str.length !== 2) return undefined;
|
||||
return provincie.find((p) => p.sigla === str);
|
||||
};
|
||||
|
|
@ -1,8 +1,9 @@
|
|||
import dynamic from "next/dynamic";
|
||||
import type { z } from "zod/v4";
|
||||
import type { ListOption } from "~/components/custom_ui/multiselect";
|
||||
import { getComuneFromIndex } from "~/i18n/comuni";
|
||||
import { searchNazioneByIndex } from "~/i18n/nazioni";
|
||||
import type { Comuni } from "~/schemas/public/Comuni";
|
||||
import type { Nazioni } from "~/schemas/public/Nazioni";
|
||||
import { ITALY_CATASTO_CODE } from "./catasto";
|
||||
|
||||
export const FormDebug: React.ElementType =
|
||||
process.env.NODE_ENV === "development"
|
||||
|
|
@ -87,50 +88,22 @@ const getAlternativeCF = (input: string): string[] => {
|
|||
return result;
|
||||
};
|
||||
|
||||
const genCatasto = ({
|
||||
luogoNascita,
|
||||
nazioneNascita,
|
||||
}: {
|
||||
luogoNascita: string;
|
||||
nazioneNascita: string;
|
||||
}) => {
|
||||
let catasto = "";
|
||||
if (nazioneNascita === "0") {
|
||||
if (luogoNascita !== "") {
|
||||
const comune = getComuneFromIndex(parseInt(luogoNascita));
|
||||
if (comune) {
|
||||
catasto = comune.CATASTO;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (nazioneNascita !== "") {
|
||||
const nazione = searchNazioneByIndex(parseInt(nazioneNascita));
|
||||
if (nazione) {
|
||||
catasto = nazione.CATASTO;
|
||||
}
|
||||
}
|
||||
}
|
||||
return catasto;
|
||||
};
|
||||
|
||||
const gen15CF = ({
|
||||
cognome,
|
||||
nome,
|
||||
dataNascita,
|
||||
sesso,
|
||||
luogoNascita,
|
||||
nazioneNascita,
|
||||
catasto,
|
||||
}: {
|
||||
cognome: string;
|
||||
nome: string;
|
||||
dataNascita: Date;
|
||||
sesso: string;
|
||||
luogoNascita: string;
|
||||
nazioneNascita: string;
|
||||
catasto: string;
|
||||
}): string => {
|
||||
const data = new Date(dataNascita);
|
||||
|
||||
return `${getInizialiCF(cognome)}${getInizialiCF(nome)}${data.getFullYear().toString().slice(-2)}${getMonthLetterCF(data.getMonth())}${getDayCF(data.getDate(), sesso)}${genCatasto({ luogoNascita, nazioneNascita })}`;
|
||||
return `${getInizialiCF(cognome)}${getInizialiCF(nome)}${data.getFullYear().toString().slice(-2)}${getMonthLetterCF(data.getMonth())}${getDayCF(data.getDate(), sesso)}${catasto}`;
|
||||
};
|
||||
|
||||
const set1 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
|
|
@ -165,6 +138,8 @@ export const checkFiscalCodeValidity = ({
|
|||
refinementContext,
|
||||
luogoNascita,
|
||||
nazioneNascita,
|
||||
comuneCatasto,
|
||||
nazioneCatasto,
|
||||
}: {
|
||||
path: string;
|
||||
codiceFiscale: string;
|
||||
|
|
@ -175,14 +150,31 @@ export const checkFiscalCodeValidity = ({
|
|||
refinementContext: z.RefinementCtx;
|
||||
luogoNascita: string;
|
||||
nazioneNascita: string;
|
||||
comuneCatasto: Comuni | undefined;
|
||||
nazioneCatasto: Nazioni | undefined;
|
||||
}) => {
|
||||
const cognomeUpper = cognome.toUpperCase();
|
||||
const nomeUpper = nome.toUpperCase();
|
||||
|
||||
let codiceCatasto = "";
|
||||
if (nazioneNascita === ITALY_CATASTO_CODE) {
|
||||
if (luogoNascita !== "") {
|
||||
if (comuneCatasto) {
|
||||
codiceCatasto = comuneCatasto.catasto;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (nazioneNascita !== "") {
|
||||
if (nazioneCatasto) {
|
||||
codiceCatasto = nazioneCatasto.catasto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const gen = gen15CF({
|
||||
cognome: cognomeUpper,
|
||||
dataNascita,
|
||||
luogoNascita,
|
||||
nazioneNascita,
|
||||
catasto: codiceCatasto,
|
||||
nome: nomeUpper,
|
||||
sesso,
|
||||
});
|
||||
|
|
@ -228,7 +220,7 @@ export const checkFiscalCodeValidity = ({
|
|||
refinementContext.issues.push({
|
||||
code: "custom",
|
||||
input: "",
|
||||
message: "Inserisci un codice fiscale valido",
|
||||
message: `Inserisci un codice fiscale valido: received ${codiceFiscale}`,
|
||||
path: [path],
|
||||
});
|
||||
}
|
||||
|
|
@ -277,10 +269,13 @@ export const checkFiscalCodeValidity = ({
|
|||
path: [path],
|
||||
});
|
||||
}
|
||||
if (nazioneNascita === "0") {
|
||||
|
||||
if (nazioneNascita === ITALY_CATASTO_CODE) {
|
||||
if (luogoNascita !== "") {
|
||||
const comune = getComuneFromIndex(parseInt(luogoNascita));
|
||||
if (comune && codiceFiscale.slice(11, 15) !== comune.CATASTO) {
|
||||
if (
|
||||
comuneCatasto &&
|
||||
codiceFiscale.slice(11, 15) !== comuneCatasto.catasto
|
||||
) {
|
||||
refinementContext.issues.push({
|
||||
code: "custom",
|
||||
input: "",
|
||||
|
|
@ -291,8 +286,10 @@ export const checkFiscalCodeValidity = ({
|
|||
}
|
||||
} else {
|
||||
if (nazioneNascita !== "") {
|
||||
const nazione = searchNazioneByIndex(parseInt(nazioneNascita));
|
||||
if (nazione && codiceFiscale.slice(11, 15) !== nazione.CATASTO) {
|
||||
if (
|
||||
nazioneCatasto &&
|
||||
codiceFiscale.slice(11, 15) !== nazioneCatasto.catasto
|
||||
) {
|
||||
refinementContext.issues.push({
|
||||
code: "custom",
|
||||
input: "",
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import { OverridePasswordForm } from "~/forms/FormOverridePassword";
|
|||
import { ProfileFormAccount } from "~/forms/FormProfilo_Account";
|
||||
import { ProfileFormAnagrafica } from "~/forms/FormProfilo_Anagrafica";
|
||||
import type { NextPageWithLayout } from "~/pages/_app";
|
||||
import { CatastoProvider } from "~/providers/CatastoProvider";
|
||||
import type { UsersId } from "~/schemas/public/Users";
|
||||
import { TrpcAuthedFetchingIstance } from "~/server/utils/ssgHelper";
|
||||
import { zUserId } from "~/server/utils/zod_types";
|
||||
|
|
@ -193,7 +194,9 @@ const EditUser: NextPageWithLayout<EditUserProps> = ({
|
|||
</div>
|
||||
</TabsContent>
|
||||
<TabsContent className="mt-5 h-full space-y-6" value="anagrafica">
|
||||
<CatastoProvider>
|
||||
<ProfileFormAnagrafica userData={userData} />
|
||||
</CatastoProvider>
|
||||
</TabsContent>
|
||||
<TabsContent className="mt-5 h-full space-y-6" value="documenti">
|
||||
<DocumentiPersonali userData={userData} />
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { LoadingPage } from "~/components/loading";
|
|||
import { Status500 } from "~/components/status-page";
|
||||
import { FormNewServizioAcquisto } from "~/forms/FormNewServizioAcquisto";
|
||||
import type { NextPageWithLayout } from "~/pages/_app";
|
||||
import { CatastoProvider } from "~/providers/CatastoProvider";
|
||||
import type { ServizioServizioId } from "~/schemas/public/Servizio";
|
||||
import type { UsersId } from "~/schemas/public/Users";
|
||||
import { TrpcAuthedFetchingIstance } from "~/server/utils/ssgHelper";
|
||||
|
|
@ -34,11 +35,13 @@ const OnboardUser: NextPageWithLayout<OnboardUserProps> = ({
|
|||
Onboarding Utente (Versione Admin)
|
||||
</h3>
|
||||
</div>
|
||||
<CatastoProvider>
|
||||
<FormNewServizioAcquisto
|
||||
initialData={data}
|
||||
isAdmin
|
||||
userId={data.userData.id}
|
||||
/>
|
||||
</CatastoProvider>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import { ChangePasswordForm } from "~/forms/FormChangePassword";
|
|||
import { ProfileFormAccount } from "~/forms/FormProfilo_Account";
|
||||
import { ProfileFormAnagrafica } from "~/forms/FormProfilo_Anagrafica";
|
||||
import type { NextPageWithLayout } from "~/pages/_app";
|
||||
import { CatastoProvider } from "~/providers/CatastoProvider";
|
||||
import { useTranslation } from "~/providers/I18nProvider";
|
||||
import { useEnforcedSession } from "~/providers/SessionProvider";
|
||||
import { api } from "~/utils/api";
|
||||
|
|
@ -104,7 +105,9 @@ const Dashboard: NextPageWithLayout = () => {
|
|||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<CatastoProvider>
|
||||
<ProfileFormAnagrafica userData={userData} />
|
||||
</CatastoProvider>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import { OnboardTutorial } from "~/components/onboard_tutorial";
|
|||
import { Status500 } from "~/components/status-page";
|
||||
import { FormNewServizioAcquisto } from "~/forms/FormNewServizioAcquisto";
|
||||
import type { NextPageWithLayout } from "~/pages/_app";
|
||||
import { CatastoProvider } from "~/providers/CatastoProvider";
|
||||
import { useTranslation } from "~/providers/I18nProvider";
|
||||
import type { ServizioServizioId } from "~/schemas/public/Servizio";
|
||||
import { TrpcAuthedFetchingIstance } from "~/server/utils/ssgHelper";
|
||||
|
|
@ -36,7 +37,9 @@ const OnboardServizio: NextPageWithLayout<OnboardServizioProps> = ({
|
|||
</h3>
|
||||
</div>
|
||||
<OnboardTutorial />
|
||||
<CatastoProvider>
|
||||
<FormNewServizioAcquisto initialData={data} userId={data.userData.id} />
|
||||
</CatastoProvider>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
42
apps/infoalloggi/src/providers/CatastoProvider.tsx
Normal file
42
apps/infoalloggi/src/providers/CatastoProvider.tsx
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
import { createContext, type ReactNode, useContext } from "react";
|
||||
import { LoadingPage } from "~/components/loading";
|
||||
import type { Comuni } from "~/schemas/public/Comuni";
|
||||
import type { Nazioni } from "~/schemas/public/Nazioni";
|
||||
import type { Provincie } from "~/schemas/public/Provincie";
|
||||
import { api } from "~/utils/api";
|
||||
|
||||
type CatastoContextType = {
|
||||
comuni: Comuni[];
|
||||
provincie: Provincie[];
|
||||
nazioni: Nazioni[];
|
||||
};
|
||||
|
||||
const CatastoContext = createContext<CatastoContextType | null>(null);
|
||||
|
||||
export const CatastoProvider = ({ children }: { children: ReactNode }) => {
|
||||
const { data: comuni = [], isLoading: isLoadingComune } =
|
||||
api.catasto.getComuni.useQuery();
|
||||
const { data: provincie = [], isLoading: isLoadingProvincie } =
|
||||
api.catasto.getProvincie.useQuery();
|
||||
const { data: nazioni = [], isLoading: isLoadingNazioni } =
|
||||
api.catasto.getNazioni.useQuery();
|
||||
|
||||
return (
|
||||
<CatastoContext.Provider value={{ comuni, provincie, nazioni }}>
|
||||
{isLoadingComune || isLoadingProvincie || isLoadingNazioni ? (
|
||||
<LoadingPage />
|
||||
) : (
|
||||
children
|
||||
)}
|
||||
</CatastoContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useCatasto = () => {
|
||||
const context = useContext(CatastoContext);
|
||||
|
||||
if (!context) {
|
||||
throw new Error("useCatasto must be used within a CatastoProvider");
|
||||
}
|
||||
return context;
|
||||
};
|
||||
|
|
@ -19,6 +19,7 @@ import { stripeRouter } from "~/server/api/routers/stripe";
|
|||
import { testRouter } from "~/server/api/routers/test";
|
||||
import { usersRouter } from "~/server/api/routers/users";
|
||||
import { createTRPCRouter } from "~/server/api/trpc";
|
||||
import { catastoRouter } from "./routers/catasto";
|
||||
import { syncRouter } from "./routers/sync";
|
||||
|
||||
//import { lazy } from '@trpc/server';
|
||||
|
|
@ -45,5 +46,6 @@ export const appRouter = createTRPCRouter({
|
|||
test: testRouter,
|
||||
users: usersRouter,
|
||||
sync: syncRouter,
|
||||
catasto: catastoRouter,
|
||||
});
|
||||
export type AppRouter = typeof appRouter;
|
||||
|
|
|
|||
41
apps/infoalloggi/src/server/api/routers/catasto.ts
Normal file
41
apps/infoalloggi/src/server/api/routers/catasto.ts
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
import z from "zod";
|
||||
import { createTRPCRouter, publicProcedure } from "~/server/api/trpc";
|
||||
import {
|
||||
getComuneById,
|
||||
getComuni,
|
||||
getNazioneById,
|
||||
getNazioni,
|
||||
getProvincie,
|
||||
} from "~/server/controllers/catasto.controller";
|
||||
|
||||
import { zComuneId, zNazioneId } from "~/server/utils/zod_types";
|
||||
|
||||
export const catastoRouter = createTRPCRouter({
|
||||
getComuni: publicProcedure.query(async () => {
|
||||
return await getComuni();
|
||||
}),
|
||||
getComuneById: publicProcedure
|
||||
.input(
|
||||
z.object({
|
||||
id: zComuneId,
|
||||
}),
|
||||
)
|
||||
.query(async ({ input }) => {
|
||||
return await getComuneById(input.id);
|
||||
}),
|
||||
getProvincie: publicProcedure.query(async () => {
|
||||
return await getProvincie();
|
||||
}),
|
||||
getNazioni: publicProcedure.query(async () => {
|
||||
return await getNazioni();
|
||||
}),
|
||||
getNazioneById: publicProcedure
|
||||
.input(
|
||||
z.object({
|
||||
id: zNazioneId,
|
||||
}),
|
||||
)
|
||||
.query(async ({ input }) => {
|
||||
return await getNazioneById(input.id);
|
||||
}),
|
||||
});
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
import { TRPCError } from "@trpc/server";
|
||||
import type { Comuni, ComuniId } from "~/schemas/public/Comuni";
|
||||
import type { NazioniId } from "~/schemas/public/Nazioni";
|
||||
import { db } from "../db";
|
||||
|
||||
export type Comune = Pick<Comuni, "id" | "nome" | "sigla">;
|
||||
export const getComuni = async () => {
|
||||
try {
|
||||
return await db.selectFrom("comuni").selectAll().execute();
|
||||
} catch (e) {
|
||||
throw new TRPCError({
|
||||
code: "INTERNAL_SERVER_ERROR",
|
||||
message: `Error while getting Comuni: ${(e as Error).message}`,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const getComuneById = async (id: ComuniId) => {
|
||||
try {
|
||||
return await db
|
||||
.selectFrom("comuni")
|
||||
.selectAll()
|
||||
.where("id", "=", id)
|
||||
.executeTakeFirst();
|
||||
} catch (e) {
|
||||
throw new TRPCError({
|
||||
code: "INTERNAL_SERVER_ERROR",
|
||||
message: `Error while getting ComuneById: ${(e as Error).message}`,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const getProvincie = async () => {
|
||||
try {
|
||||
return await db.selectFrom("provincie").selectAll().execute();
|
||||
} catch (e) {
|
||||
throw new TRPCError({
|
||||
code: "INTERNAL_SERVER_ERROR",
|
||||
message: `Error while getting Provincie: ${(e as Error).message}`,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const getNazioni = async () => {
|
||||
try {
|
||||
return await db.selectFrom("nazioni").selectAll().execute();
|
||||
} catch (e) {
|
||||
throw new TRPCError({
|
||||
code: "INTERNAL_SERVER_ERROR",
|
||||
message: `Error while getting Nazioni: ${(e as Error).message}`,
|
||||
});
|
||||
}
|
||||
};
|
||||
export const getNazioneById = async (id: NazioniId) => {
|
||||
try {
|
||||
return await db
|
||||
.selectFrom("nazioni")
|
||||
.selectAll()
|
||||
.where("id", "=", id)
|
||||
.executeTakeFirst();
|
||||
} catch (e) {
|
||||
throw new TRPCError({
|
||||
code: "INTERNAL_SERVER_ERROR",
|
||||
message: `Error while getting NazioneById: ${(e as Error).message}`,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -3,9 +3,11 @@ import type { AnnunciId } from "~/schemas/public/Annunci";
|
|||
import type { BanlistId } from "~/schemas/public/Banlist";
|
||||
import BanType from "~/schemas/public/BanType";
|
||||
import type { ChatsChatid } from "~/schemas/public/Chats";
|
||||
import type { ComuniId } from "~/schemas/public/Comuni";
|
||||
import type { EtichetteIdEtichetta } from "~/schemas/public/Etichette";
|
||||
import type { FlagsId } from "~/schemas/public/Flags";
|
||||
import type { MessagesMessageid } from "~/schemas/public/Messages";
|
||||
import type { NazioniId } from "~/schemas/public/Nazioni";
|
||||
import type { OrdiniOrdineId } from "~/schemas/public/Ordini";
|
||||
import type { PaymentsId } from "~/schemas/public/Payments";
|
||||
import type { PrezziarioIdprezziario } from "~/schemas/public/Prezziario";
|
||||
|
|
@ -82,3 +84,13 @@ export const zPagamentoId = z.custom<PaymentsId>(
|
|||
(val) => typeof val === "string",
|
||||
"falied to validate PagamentoId",
|
||||
);
|
||||
|
||||
export const zComuneId = z.custom<ComuniId>(
|
||||
(val) => typeof val === "number",
|
||||
"falied to validate ComuneId",
|
||||
);
|
||||
|
||||
export const zNazioneId = z.custom<NazioniId>(
|
||||
(val) => typeof val === "number",
|
||||
"falied to validate NazioneId",
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue