import { boolean, z } from "zod"; import { INR_CURRENCY_CODE } from "../../utils/constants"; const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB const ALLOWED_TYPES = [ "application/pdf", "image/png", "image/jpg", "image/jpeg", ]; export const PaymentRequestSchema = (expenseTypes, isItself) => { return z.object({ title: z.string().min(1, { message: "Project is required" }), projectId: z.string().min(1, { message: "Project is required" }), expenseCategoryId: z .string() .min(1, { message: "Expense Category is required" }), currencyId: z.string().min(1, { message: "Currency is required" }), dueDate: z.string().min(1, { message: "Date is required" }), description: z.string().min(1, { message: "Description is required" }), payee: z.string().min(1, { message: "Supplier name is required" }), isAdvancePayment: z.boolean().optional().default(false), 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", }), 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", }), documentId: z.string().optional(), fileSize: z.number().max(MAX_FILE_SIZE, { message: "File size must be less than or equal to 5MB", }), description: z.string().optional(), isActive: z.boolean().default(true), }) ) , }) }; export const defaultPaymentRequest = { title:"", description: "", payee: "", currencyId: "", amount: "", dueDate: "", projectId: "", expenseCategoryId: "", isAdvancePayment: false, billAttachments: [], }; export const SearchPaymentRequestSchema = z.object({ projectIds: z.array(z.string()).optional(), statusIds: z.array(z.string()).optional(), createdByIds: z.array(z.string()).optional(), currencyIds: z.array(z.string()).optional(), expenseCategoryIds: z.array(z.string()).optional(), payees: z.array(z.string()).optional(), startDate: z.string().optional(), endDate: z.string().optional(), }); export const defaultPaymentRequestFilter = { projectIds: [], statusIds: [], createdByIds: [], currencyIds: [], expenseCategoryIds: [], payees: [], startDate: null, endDate: null, }; export const PaymentRequestActionScheam = ( isTransaction = false, transactionDate ) => { return z .object({ comment: z.string().min(1, { message: "Please leave comment" }), statusId: z.string().min(1, { message: "Please select a status" }), paidTransactionId: z.string().nullable().optional(), paidAt: z.string().nullable().optional(), paidById: z.string().nullable().optional(), tdsPercentage: z.string().nullable().optional(), baseAmount: z.string().nullable().optional(), taxAmount: z.string().nullable().optional(), }) .superRefine((data, ctx) => { if (isTransaction) { if (!data.paidTransactionId?.trim()) { ctx.addIssue({ code: z.ZodIssueCode.custom, path: ["paidTransactionId"], message: "Transaction ID is required", }); } if (!data.paidAt) { ctx.addIssue({ code: z.ZodIssueCode.custom, path: ["paidAt"], message: "Transacion Date is required", }); } if (!data.paidById) { ctx.addIssue({ code: z.ZodIssueCode.custom, path: ["paidById"], message: "Paid By is required", }); } if (!data.baseAmount) { ctx.addIssue({ code: z.ZodIssueCode.custom, path: ["baseAmount"], message: "Base Amount i required", }); } if (!data.taxAmount) { ctx.addIssue({ code: z.ZodIssueCode.custom, path: ["taxAmount"], message: "Tax is required", }); } } }); }; export const defaultPRActionValues = { comment: "", statusId: "", paidTransactionId: null, paidAt: null, paidById: null, tdsPercentage:"0", baseAmount: null, taxAmount:null, }; export const RequestedExpenseSchema = z.object({ paymentModeId: z.string().min(1, { message: "Payment mode is required" }), location: z.string().min(1, { message: "Location is required" }), gstNumber: z.string().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", }), documentId: z.string().optional(), fileSize: z.number().max(MAX_FILE_SIZE, { message: "File size must be less than or equal to 5MB", }), description: z.string().optional(), isActive: z.boolean().default(true), }) ) .nonempty({ message: "At least one file attachment is required" }), }); export const DefaultRequestedExpense = { paymentModeId: "", location: "", gstNumber: "", // amount:"", billAttachments: [], };