import { formatDate, removeTimeFromDate } from "@/lib/utils";
import { z } from "zod";
import { v4 as uuidv4 } from "uuid";
import { projectStatusEnum } from "@/server/project/domain/models";
const baseProjectSchema = z.object({
name: z
.string()
.min(3, { message: "El nombre debe tener al menos 3 caracteres." }),
costPerMeter: z.coerce
.number({ message: "Introduce un número válido" })
.min(0, { message: "Valor no puede ser inferior a 0" })
.refine((value) => !isNaN(value), {
message: "El costo por metro debe ser un número.",
}),
startDate: z.coerce
.date({ message: "Fecha de inicio es requerida" })
.transform((str) => removeTimeFromDate(str)),
estimatedEndDate: z.coerce
.date({ message: "Fecha final estimada es requerida" })
.transform((str) => (str ? removeTimeFromDate(str) : undefined))
.optional(),
laborCost: z.coerce
.number({ message: "Introduce un número válido" })
.min(0, { message: "Valor no puede ser inferior a 0" })
.default(0),
totalCostMaterials: z.coerce
.number({ message: "Introduce un número válido" })
.min(0, { message: "Valor no puede ser inferior a 0" })
.default(0),
totalCostPerMeter: z.coerce
.number({ message: "Introduce un número válido" })
.min(0, { message: "Valor no puede ser inferior a 0" })
.default(0),
typeCotization: z.string().min(2, { message: "Tipo de cotizacion invalido" }),
residence: z.string().min(2, { message: "Tipo de residencia invalido" }),
});
const withCustomRefinements = (schema: z.ZodType<any>) =>
schema
.refine(
(data) => {
if (data.estimatedEndDate) {
return (
formatDate(data.estimatedEndDate) >= formatDate(data.startDate!)
);
}
return true;
},
{
message:
"La fecha final estimada debe ser igual o posterior a la fecha de inicio",
path: ["estimatedEndDate"],
}
)
export const createProjectSchema = withCustomRefinements(
baseProjectSchema.extend({
id: z
.string()
.uuid()
.default(() => uuidv4()),
})
);
export const updateProjectSchema = withCustomRefinements(
baseProjectSchema
.extend({
id: z.string().uuid({ message: "Proyecto incorrecto" }),
status: z.enum(projectStatusEnum),
})
.partial()
);