import { z } from "zod"; const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB const ALLOWED_TYPES = [ "application/pdf", "image/png", "image/jpg", "image/jpeg", ]; export const ExpenseSchema = (expenseTypes) => { return z .object({ projectId: z.string().min(1, { message: "Project is required" }), expensesTypeId: z.string().min(1, { message: "Expense type is required" }), paymentModeId: z.string().min(1, { message: "Payment mode is required" }), paidById: z.string().min(1, { message: "Employee name is required" }), transactionDate: z.string().min(1, { message: "Date is required" }), transactionId: z.string().optional(), description: z.string().min(1, { message: "Description is required" }), location: z.string().min(1, { message: "Location is required" }), supplerName: z.string().min(1, { message: "Supplier name is required" }), amount: z .coerce .number({ invalid_type_error: "Amount is required and must be a number" }) .min(1, "Amount must be Enter") .refine((val) => /^\d+(\.\d{1,2})?$/.test(val.toString()), { message: "Amount must have at most 2 decimal places", }), noOfPersons: z.coerce .number() .optional(), billAttachments: z .array( z.object({ fileName: z.string().min(1, { message: "Filename is required" }), base64Data: z.string().nullable(), contentType: z.string().refine((val) => ALLOWED_TYPES.includes(val), { message: "Only PDF, PNG, JPG, or JPEG files are allowed", }), fileSize: z.number().max(MAX_FILE_SIZE, { message: "File size must be less than or equal to 5MB", }), description: z.string().optional(), }) ) .nonempty({ message: "At least one file attachment is required" }), }) .refine( (data) => { return !data.projectId || (data.paidById && data.paidById.trim() !== ""); }, { message: "Please select who paid (employee)", path: ["paidById"], } ) .superRefine((data, ctx) => { const expenseType = expenseTypes.find((et) => et.id === data.expensesTypeId); if (expenseType?.noOfPersonsRequired && (!data.noOfPersons || data.noOfPersons < 1)) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: "No. of Persons is required and must be at least 1", path: ["noOfPersons"], }); } }); }; export const defaultExpense = { projectId: "", expensesTypeId: "", paymentModeId: "", paidById: "", transactionDate: "", transactionId: "", description: "", location: "", supplerName: "", amount: "", noOfPersons: "", billAttachments: [], } export const ActionSchema = z.object({ comment : z.string().min(1,{message:"Please leave comment"}), selectedStatus: z.string().min(1, { message: "Please select a status" }), })