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) => 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() );