refactor: remove company-related fields from user forms and schemas

This commit is contained in:
Marco Pedone 2026-02-19 11:45:09 +01:00
parent 1a4e3dc776
commit 61927448ca
7 changed files with 20 additions and 614 deletions

View file

@ -0,0 +1,20 @@
ALTER TABLE IF EXISTS public.users_anagrafica
DROP COLUMN IF EXISTS azienda;
ALTER TABLE IF EXISTS public.users_anagrafica
DROP COLUMN IF EXISTS ragione_sociale;
ALTER TABLE IF EXISTS public.users_anagrafica
DROP COLUMN IF EXISTS sede_legale;
ALTER TABLE IF EXISTS public.users_anagrafica
DROP COLUMN IF EXISTS p_iva;
ALTER TABLE IF EXISTS public.users_anagrafica
DROP COLUMN IF EXISTS fatturazione_aziendale;
ALTER TABLE IF EXISTS public.users_anagrafica
DROP COLUMN IF EXISTS codice_destinatario;
ALTER TABLE IF EXISTS public.users_anagrafica
DROP COLUMN IF EXISTS legale_rappresentante;

View file

@ -78,22 +78,18 @@ const FormNewServizioSchema = z.object({
animali: z.boolean(),
arredato: z.boolean(),
ascensore: z.boolean(),
azienda: z.boolean(),
budget: z.number().positive(),
cap_recapiti: z.string().length(5),
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"),
data_nascita: z.date(),
email: z.email(),
entromese: z.number().nullable(),
fatturazione_aziendale: z.boolean(),
fumatori: z.boolean(),
giardino: z.boolean(),
indirizzo_recapiti: z.string().nonempty("Inserisci un indirizzo"),
legale_rappresentante: z.string().nullable(),
luogo_nascita: z.string().nullable(),
motivazione_transitorio: z.string().nullable(),
n_adulti: z.number().min(1),
@ -101,14 +97,11 @@ const FormNewServizioSchema = z.object({
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().nullable(),
ragione_sociale: z.string().nullable(),
reddito: z.string().nullable(),
sede_legale: z.string().nullable(),
sesso: z.string(),
telefono: z.string(),
terrazzo: z.boolean(),
@ -146,13 +139,6 @@ export const FormNewServizioAcquisto = ({
motivazione_transitorio,
scadenza_motivazione_transitoria,
reddito,
azienda,
p_iva,
sede_legale,
legale_rappresentante,
ragione_sociale,
fatturazione_aziendale,
codice_destinatario,
citta_recapiti,
nazione_recapiti,
provincia_recapiti,
@ -167,50 +153,6 @@ export const FormNewServizioAcquisto = ({
path: ["entromese"],
});
}
if (azienda) {
if (!ragione_sociale || ragione_sociale.length < 1) {
refinementContext.issues.push({
code: "custom",
input: "",
message: "Inserisci la ragione sociale",
path: ["ragione_sociale"],
});
}
if (!sede_legale || sede_legale.length < 1) {
refinementContext.issues.push({
code: "custom",
input: "",
message: "Inserisci la sede legale",
path: ["sede_legale"],
});
}
if (!p_iva || p_iva.length < 1) {
refinementContext.issues.push({
code: "custom",
input: "",
message: "Inserisci la partita iva",
path: ["p_iva"],
});
}
if (!legale_rappresentante || legale_rappresentante.length < 1) {
refinementContext.issues.push({
code: "custom",
input: "",
message: "Inserisci il legale rappresentante",
path: ["legale_rappresentante"],
});
}
}
if (fatturazione_aziendale) {
if (!codice_destinatario || codice_destinatario.length !== 7) {
refinementContext.issues.push({
code: "custom",
input: "",
message: "Inserisci un codice destinatario valido",
path: ["codice_destinatario"],
});
}
}
if (!telefono || telefono.length < 10) {
refinementContext.issues.push({
@ -336,27 +278,18 @@ export const FormNewServizioAcquisto = ({
// This can come from your database or API.
const defaultValues: FormNewServizioValues = {
...initialData.userData,
azienda: initialData.anagrafica?.azienda || false,
cap_recapiti: initialData.anagrafica?.cap_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 || "",
data_nascita: initialData.anagrafica?.data_nascita
? new Date(initialData.anagrafica.data_nascita)
: new Date(),
fatturazione_aziendale:
initialData.anagrafica?.fatturazione_aziendale || false,
indirizzo_recapiti: initialData.anagrafica?.via_residenza || "",
legale_rappresentante: initialData.anagrafica?.legale_rappresentante || "",
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 || null,
ragione_sociale: initialData.anagrafica?.ragione_sociale || "",
sede_legale: initialData.anagrafica?.sede_legale || "",
sesso: initialData.anagrafica?.sesso || "M",
...initialData.servizio,
};
@ -404,23 +337,16 @@ export const FormNewServizioAcquisto = ({
function onSubmit(fields: FormNewServizioValues) {
const a: UsersAnagraficaUpdate = {
azienda: fields.azienda,
cap_residenza: fields.cap_recapiti,
civico_residenza: fields.civico_recapiti,
codice_destinatario: fields.codice_destinatario,
codice_fiscale: fields.codice_fiscale,
comune_residenza: fields.citta_recapiti,
data_nascita: fields.data_nascita,
fatturazione_aziendale: fields.fatturazione_aziendale,
idanagrafica: initialData.anagrafica?.idanagrafica,
legale_rappresentante: fields.legale_rappresentante,
luogo_nascita: fields.luogo_nascita,
nazione_nascita: fields.nazione_nascita,
nazione_residenza: fields.nazione_recapiti,
p_iva: fields.p_iva,
provincia_residenza: fields.provincia_recapiti,
ragione_sociale: fields.ragione_sociale,
sede_legale: fields.sede_legale,
sesso: fields.sesso,
userid: userId,
via_residenza: fields.indirizzo_recapiti,
@ -484,7 +410,6 @@ export const FormNewServizioAcquisto = ({
? {
dettagli: "Dettagli del servizio",
dettagli_desc: "Questi dati rappresentano la tua ricerca",
fattura: "Vuoi che la fatturazione sia intestata alla tua azienda?",
personali: "Dati personali",
personali_desc: "Inserisci i tuoi dati personali",
salva: "Salva e procedi",
@ -493,7 +418,6 @@ export const FormNewServizioAcquisto = ({
: {
dettagli: "Service Details",
dettagli_desc: "These data represent your search",
fattura: "Do you want the invoice to be issued to your company?",
personali: "Personal Data",
personali_desc: "Enter your personal data",
salva: "Save and proceed",
@ -970,40 +894,7 @@ export const FormNewServizioAcquisto = ({
</FormItem>
)}
/>
<FormField
control={form.control}
name="azienda"
render={({ field }) => (
<FormItem className="mt-6 w-full">
<div className="flex items-center justify-center gap-x-4">
<FormLabel htmlFor="azienda">
{t.account.azienda_o_pf_disclamer}
</FormLabel>
<FormControl>
<Switch
checked={field.value}
className="data-[state=checked]:bg-neutral-700"
id="azienda"
onCheckedChange={(v) => {
field.onChange(v);
if (!v) {
form.setValue("ragione_sociale", null);
form.setValue("sede_legale", null);
form.setValue("p_iva", null);
}
}}
/>
</FormControl>
<FormMessage />
</div>
</FormItem>
)}
/>
</div>
<AziendaSection control={form.control} setValue={form.setValue} />
<FatturazioneSection control={form.control} />
<Separator />
<div className="flex w-full flex-col items-start justify-between gap-4 sm:flex-row">
<FormField
@ -1389,202 +1280,6 @@ export const FormNewServizioAcquisto = ({
);
};
const AziendaSection = ({
control,
setValue,
}: {
control: Control<FormNewServizioValues>;
setValue: (
name: keyof FormNewServizioValues,
// biome-ignore lint/suspicious/noExplicitAny: <fine here>
value: any,
) => void;
}) => {
const { t, locale } = useTranslation();
const azienda = useWatch({
control,
name: "azienda",
});
return (
<>
<div
className={cn(
"flex w-full flex-col items-start justify-between gap-4 sm:flex-row",
!azienda && "hidden",
)}
>
<FormField
control={control}
name="ragione_sociale"
render={({ field }) => (
<FormItem className="w-full">
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="ragione_sociale">
{t.anagrafica.ragioneSociale}
</FormLabel>
<FormMessage />
</div>
<FormControl>
<Input
{...field}
id="ragione_sociale"
onChange={(e) => NullableStringOnChange(e, field.onChange)}
type="text"
value={field.value || ""}
/>
</FormControl>
</FormItem>
)}
/>
<FormField
control={control}
name="sede_legale"
render={({ field }) => (
<FormItem className="w-full">
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="sede_legale">
{t.anagrafica.sedeLegale}
</FormLabel>
<FormMessage />
</div>
<FormControl>
<Input
{...field}
id="sede_legale"
onChange={(e) => NullableStringOnChange(e, field.onChange)}
type="text"
value={field.value || ""}
/>
</FormControl>
</FormItem>
)}
/>
</div>
<div
className={cn(
"flex w-full flex-col items-start justify-between gap-4 sm:flex-row",
!azienda && "hidden",
)}
>
<FormField
control={control}
name="p_iva"
render={({ field }) => (
<FormItem className="w-full">
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="p_iva">{t.anagrafica.p_iva}</FormLabel>
<FormMessage />
</div>
<FormControl>
<Input
{...field}
id="p_iva"
onChange={(e) => NullableStringOnChange(e, field.onChange)}
type="text"
value={field.value || ""}
/>
</FormControl>
</FormItem>
)}
/>
<FormField
control={control}
name="legale_rappresentante"
render={({ field }) => (
<FormItem className="w-full">
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="legale_rappresentante">
{t.anagrafica.legale_rappresentante}
</FormLabel>
<FormMessage />
</div>
<FormControl>
<Input
{...field}
id="legale_rappresentante"
onChange={(e) => NullableStringOnChange(e, field.onChange)}
type="text"
value={field.value || ""}
/>
</FormControl>
</FormItem>
)}
/>
</div>
<FormField
control={control}
name="fatturazione_aziendale"
render={({ field }) => (
<FormItem className={cn("py-2", !azienda && "hidden")}>
<div className="flex items-center justify-start gap-x-4">
<FormLabel htmlFor="fatturazione_aziendale">
{locale === "it"
? "Vuoi che la fatturazione sia intestata alla tua azienda?"
: "Do you want the invoice to be issued to your company?"}
</FormLabel>
<FormControl>
<Switch
checked={field.value}
className="data-[state=checked]:bg-neutral-700"
id="fatturazione_aziendale"
onCheckedChange={(v) => {
field.onChange(v);
if (!v) {
setValue("codice_destinatario", null);
}
}}
/>
</FormControl>
<FormMessage />
</div>
</FormItem>
)}
/>
</>
);
};
const FatturazioneSection = ({
control,
}: {
control: Control<FormNewServizioValues>;
}) => {
const { locale } = useTranslation();
const fatturazione_aziendale = useWatch({
control,
name: "fatturazione_aziendale",
});
return (
<FormField
control={control}
name="codice_destinatario"
render={({ field }) => (
<FormItem className={cn("w-full", !fatturazione_aziendale && "hidden")}>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="codice_destinatario">
{locale === "it"
? "Codice destinatario SDI"
: "SDI Recipient Code"}
</FormLabel>
<FormMessage />
</div>
<FormControl>
<Input
{...field}
id="codice_destinatario"
onChange={(e) => NullableStringOnChange(e, field.onChange)}
type="text"
value={field.value || ""}
/>
</FormControl>
</FormItem>
)}
/>
);
};
const ResidenzaSection = ({
control,
trigger,

View file

@ -22,7 +22,6 @@ import {
PopoverTrigger,
} from "~/components/ui/popover";
import { Separator } from "~/components/ui/separator";
import { Switch } from "~/components/ui/switch";
import {
getProvinciaFromSigla,
ITALY_CATASTO_CODE,
@ -41,22 +40,15 @@ import type { CompleteUserData } from "~/server/services/user.service";
import { api } from "~/utils/api";
const profileFormSchema = z.object({
azienda: z.boolean(),
cap_residenza: z.string().optional(),
civico_residenza: z.string().optional(),
codice_destinatario: z.string().length(7).nullable(),
codice_fiscale: 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().nullable(),
nazione_nascita: z.string().nullable(),
nazione_residenza: z.string().nullable(),
p_iva: z.string().nullable(),
provincia_residenza: z.string().nullable(),
ragione_sociale: z.string().nullable(),
sede_legale: z.string().nullable(),
sesso: z.string().optional(),
via_residenza: z.string().optional(),
});
@ -78,61 +70,9 @@ export const ProfileFormAnagrafica = ({
luogo_nascita,
nazione_nascita,
cap_residenza,
azienda,
p_iva,
ragione_sociale,
sede_legale,
legale_rappresentante,
fatturazione_aziendale,
codice_destinatario,
},
refinementContext,
) => {
if (azienda) {
if (!ragione_sociale || ragione_sociale.length < 1) {
refinementContext.issues.push({
code: "custom",
input: "",
message: "Inserisci la ragione sociale",
path: ["ragione_sociale"],
});
}
if (!sede_legale || sede_legale.length < 1) {
refinementContext.issues.push({
code: "custom",
input: "",
message: "Inserisci la sede legale",
path: ["sede_legale"],
});
}
if (!p_iva || p_iva.length < 1) {
refinementContext.issues.push({
code: "custom",
input: "",
message: "Inserisci la partita iva",
path: ["p_iva"],
});
}
if (!legale_rappresentante || legale_rappresentante.length < 1) {
refinementContext.issues.push({
code: "custom",
input: "",
message: "Inserisci il legale rappresentante",
path: ["legale_rappresentante"],
});
}
}
if (fatturazione_aziendale) {
if (!codice_destinatario || codice_destinatario.length !== 7) {
refinementContext.issues.push({
code: "custom",
input: "",
message: "Inserisci il codice destinatario",
path: ["codice_destinatario"],
});
}
}
if (cap_residenza) {
if (cap_residenza.length !== 5) {
refinementContext.issues.push({
@ -180,22 +120,15 @@ export const ProfileFormAnagrafica = ({
);
const defaultValues: ProfileFormValues = {
azienda: userData.azienda || false,
cap_residenza: userData.cap_residenza || "",
civico_residenza: userData.civico_residenza || "",
codice_destinatario: userData.codice_destinatario || null,
codice_fiscale: userData.codice_fiscale || "",
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,
p_iva: userData.p_iva || null,
provincia_residenza: userData.provincia_residenza,
ragione_sociale: userData.ragione_sociale || null,
sede_legale: userData.sede_legale || null,
sesso: userData.sesso || "",
via_residenza: userData.via_residenza || "",
};
@ -471,38 +404,8 @@ export const ProfileFormAnagrafica = ({
</FormItem>
)}
/>
<FormField
control={form.control}
name="azienda"
render={({ field }) => (
<FormItem className="mt-6 w-full">
<div className="flex items-center justify-center gap-x-4">
<FormLabel htmlFor="azienda">Azienda?</FormLabel>
<FormControl>
<Switch
checked={field.value}
className="data-[state=checked]:bg-neutral-700"
id="azienda"
onCheckedChange={(v) => {
field.onChange(v);
if (!v) {
form.setValue("ragione_sociale", null);
form.setValue("sede_legale", null);
form.setValue("p_iva", null);
}
}}
/>
</FormControl>
<FormMessage />
</div>
</FormItem>
)}
/>
</div>
<AziendaSection control={form.control} setValue={form.setValue} />
<FatturazioneSection control={form.control} />
<Separator />
<ResidenzaSection
@ -518,189 +421,6 @@ export const ProfileFormAnagrafica = ({
);
};
const AziendaSection = ({
control,
setValue,
}: {
control: Control<ProfileFormValues>;
// biome-ignore lint/suspicious/noExplicitAny: <fine here>
setValue: (field: keyof ProfileFormValues, value: any) => void;
}) => {
const { t } = useTranslation();
const azienda = useWatch({ control, name: "azienda" });
return (
<>
<div
className={cn(
"flex w-full flex-col items-start justify-between gap-4 sm:flex-row",
!azienda && "hidden",
)}
>
<FormField
control={control}
name="ragione_sociale"
render={({ field }) => (
<FormItem className="w-full">
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="ragione_sociale">
{t.anagrafica.ragioneSociale}
</FormLabel>
<FormMessage />
</div>
<FormControl>
<Input
{...field}
id="ragione_sociale"
type="text"
value={field.value || undefined}
/>
</FormControl>
</FormItem>
)}
/>
<FormField
control={control}
name="sede_legale"
render={({ field }) => (
<FormItem className="w-full">
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="sede_legale">
{t.anagrafica.sedeLegale}
</FormLabel>
<FormMessage />
</div>
<FormControl>
<Input
{...field}
id="sede_legale"
type="text"
value={field.value || undefined}
/>
</FormControl>
</FormItem>
)}
/>
</div>
<div
className={cn(
"flex w-full flex-col items-start justify-between gap-4 sm:flex-row",
!azienda && "hidden",
)}
>
<FormField
control={control}
name="p_iva"
render={({ field }) => (
<FormItem className="w-full">
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="p_iva">{t.anagrafica.p_iva}</FormLabel>
<FormMessage />
</div>
<FormControl>
<Input
{...field}
id="p_iva"
type="text"
value={field.value || undefined}
/>
</FormControl>
</FormItem>
)}
/>
<FormField
control={control}
name="legale_rappresentante"
render={({ field }) => (
<FormItem className="w-full">
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="legale_rappresentante">
{t.anagrafica.legale_rappresentante}
</FormLabel>
<FormMessage />
</div>
<FormControl>
<Input
{...field}
id="legale_rappresentante"
type="text"
value={field.value || undefined}
/>
</FormControl>
</FormItem>
)}
/>
</div>
<FormField
control={control}
name="fatturazione_aziendale"
render={({ field }) => (
<FormItem className={cn("py-2", !azienda && "hidden")}>
<div className="flex items-center justify-start gap-x-4">
<FormLabel htmlFor="fatturazione_aziendale">
Vuoi che la fatturazione sia intestata alla tua azienda?
</FormLabel>
<FormControl>
<Switch
checked={field.value}
className="data-[state=checked]:bg-neutral-700"
id="fatturazione_aziendale"
onCheckedChange={(v) => {
field.onChange(v);
if (!v) {
setValue("codice_destinatario", null);
}
}}
/>
</FormControl>
<FormMessage />
</div>
</FormItem>
)}
/>
</>
);
};
const FatturazioneSection = ({
control,
}: {
control: Control<ProfileFormValues>;
}) => {
const fatturazione_aziendale = useWatch({
control,
name: "fatturazione_aziendale",
});
return (
<>
<FormField
control={control}
name="codice_destinatario"
render={({ field }) => (
<FormItem
className={cn("w-full", !fatturazione_aziendale && "hidden")}
>
<div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="codice_destinatario">
Codice destinatario (SDI)
</FormLabel>
<FormMessage />
</div>
<FormControl>
<Input
{...field}
id="codice_destinatario"
type="text"
value={field.value || undefined}
/>
</FormControl>
</FormItem>
)}
/>
</>
);
};
const ResidenzaSection = ({
control,
setValue,

View file

@ -185,11 +185,6 @@ export const en: LangDict = {
accetta: "Accept",
acconto: "Dwn. Paym.",
account: {
azieda_titolo: "Company Data",
azienda_o_pf: "Personal or Company?",
azienda_o_pf_disclamer: "Company purchase?",
azienda_o_pf_info: "Additional information will be requested later",
azienda_o_pf_options: ["For me", "For my company"],
cognome: "Surname",
email: "Email",
nome: "Name",

View file

@ -188,11 +188,6 @@ export const it: LangDict = {
accetta: "Accetta",
acconto: "Acconto",
account: {
azieda_titolo: "Dati Azienda",
azienda_o_pf: "Persona Fisica o Azienda?",
azienda_o_pf_disclamer: "Acquisto come azienda?",
azienda_o_pf_info: "Informazioni aggiuntive saranno richieste in seguito",
azienda_o_pf_options: ["Per me", "Per la mia azienda"],
cognome: "Cognome",
email: "Email",
nome: "Nome",

View file

@ -403,11 +403,6 @@ export type LangDict = {
tipologia_desc: string;
tipologia_disclamer: string;
tipologia_options: string[];
azieda_titolo: string;
azienda_o_pf: string;
azienda_o_pf_disclamer: string;
azienda_o_pf_options: string[];
azienda_o_pf_info: string;
};
anagrafica: {
titolo: string;

View file

@ -36,20 +36,6 @@ export default interface UsersAnagraficaTable {
sesso: ColumnType<string | null, string | null, string | null>;
azienda: ColumnType<boolean, boolean | undefined, boolean>;
ragione_sociale: ColumnType<string | null, string | null, string | null>;
sede_legale: ColumnType<string | null, string | null, string | null>;
p_iva: ColumnType<string | null, string | null, string | null>;
fatturazione_aziendale: ColumnType<boolean, boolean | undefined, boolean>;
codice_destinatario: ColumnType<string | null, string | null, string | null>;
legale_rappresentante: ColumnType<string | null, string | null, string | null>;
doc_personale_fronte_ref: ColumnType<UsersStorageUserStorageId | null, UsersStorageUserStorageId | null, UsersStorageUserStorageId | null>;
doc_personale_retro_ref: ColumnType<UsersStorageUserStorageId | null, UsersStorageUserStorageId | null, UsersStorageUserStorageId | null>;