import { z } from "zod"; import { normalizeAllowedContentTypes } from "../../utils/appUtils"; const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB const ALLOWED_TYPES = [ "application/pdf", "image/png", "image/jpg", "image/jpeg", ]; export const AttachmentSchema = z.object({ invoiceAttachmentTypeId: z.string().nullable(), 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().default(""), isActive: z.boolean().default(true), documentId: z.string().nullable().default(null), }); export const PurchaseSchema = z.object({ title: z.string().min(1, { message: "Title is required" }), projectId: z.string().min(1, { message: "Project is required" }), organizationId: z.string().min(1, { message: "Organization is required" }), billingAddress: z.string().min(1, { message: "Address is required" }), shippingAddress: z.string().min(1, { message: "Address is required" }), purchaseOrderNumber: z.string().nullable(), purchaseOrderDate: z.coerce.date().nullable(), supplierId: z.string().min(1, { message: "Supplier is required" }), proformaInvoiceNumber: z.string().nullable(), proformaInvoiceDate: z.coerce.date().nullable(), proformaInvoiceAmount: z.coerce.number().optional(), invoiceNumber: z.string().nullable(), invoiceDate: z.coerce.date().nullable(), eWayBillNumber: z.string().nullable(), eWayBillDate: z.coerce.date().nullable(), invoiceReferenceNumber: z.string().nullable(), acknowledgmentDate: z.coerce.date().nullable(), acknowledgmentNumber: z.string().nullable(), baseAmount: z .number() .or(z.nan()) // allow NaN .transform((val) => (Number.isNaN(val) ? null : val)), taxAmount: z .number() .or(z.nan()) // allow NaN .transform((val) => (Number.isNaN(val) ? null : val)), totalAmount: z .number() .or(z.nan()) // allow NaN .transform((val) => (Number.isNaN(val) ? null : val)), paymentDueDate: z.coerce.date().nullable(), transportCharges: z .number() .or(z.nan()) // allow NaN .transform((val) => (Number.isNaN(val) ? null : val)), description: z.string(), invoiceAttachmentTypeId: z.string().nullable(), attachments: z.array(AttachmentSchema), }); export const defaultPurchaseValue = { title: "", projectId: "", organizationId: "", billingAddress: "", shippingAddress: "", purchaseOrderNumber: null, purchaseOrderDate: null, supplierId: "", proformaInvoiceNumber: null, proformaInvoiceDate: null, proformaInvoiceAmount: 0, invoiceNumber: null, invoiceDate: null, eWayBillNumber: null, eWayBillDate: null, invoiceReferenceNumber: null, acknowledgmentNumber: null, acknowledgmentDate: null, baseAmount: 0, taxAmount: 0, totalAmount: 0, paymentDueDate: null, transportCharges: 0, description: "", invoiceAttachmentTypeId: null, attachments: [], }; export const getStepFields = (stepIndex) => { const stepFieldMap = { 0: [ "title", "projectId", "organizationId", "supplierId", "billingAddress", "shippingAddress", "purchaseOrderNumber", "purchaseOrderDate", "proformaInvoiceNumber", "proformaInvoiceDate", "proformaInvoiceAmount", ], 1: [ "invoiceNumber", "invoiceDate", "eWayBillNumber", "eWayBillDate", "invoiceReferenceNumber", "acknowledgmentNumber", "acknowledgmentDate", ], 2: [ "baseAmount", "taxAmount", "totalAmount", "transportCharges", "paymentDueDate", "invoiceAttachmentTypeId", "description", "attachments", ], }; return stepFieldMap[stepIndex] || []; }; export const SingleAttachmentSchema = z.object({ fileName: z.string().min(1, { message: "File name is required" }), base64Data: z.string().min(1, { message: "File data is required" }), invoiceAttachmentTypeId: z.string().nullable(), contentType: z .string() .min(1, { message: "MIME type is required" }) .refine( (val) => ["application/pdf", "image/jpeg", "image/jpg", "image/png"].includes( val ), { message: "File type must be PDF, JPG, JPEG or PNG", } ), fileSize: z .number() .int() .nonnegative("fileSize must be ≥ 0") .max(5 * 1024 * 1024, "File size must be ≤ 5MB"), description: z.string().optional().default(""), isActive: z.boolean(), }); export const DeliveryChallanSchema = z.object({ deliveryChallanNumber: z .string() .min(1, { message: "Challan Number required" }), invoiceAttachmentTypeId: z.string().nullable(), deliveryChallanDate: z.string().min(1, { message: "Deliver date required" }), description: z.string().min(1, { message: "Description required" }), attachment: z .any() .refine((val) => val && typeof val === "object" && !!val.base64Data, { message: "Please upload document", }), }); export const DeliveryChallanDefaultValue = { deliveryChallanNumber: "", deliveryChallanDate: "", description: "", attachment: null, invoiceAttachmentTypeId: null, }; export const AddPurchasePayment = z.object({ paymentReceivedDate: z.string().min(1, { message: "Date is required" }), transactionId: z.string().min(1, "Transaction ID is required"), amount: z.number().min(1, "Amount must be greater than zero"), comment: z.string().min(1, { message: "Comment required" }), paymentAdjustmentHeadId: z .string() .min(1, { message: "Payment Type required" }), }); export const defaultPurchasePayment = { paymentReceivedDate: null, transactionId: "", amount: 0, comment: "", paymentAdjustmentHeadId: "", };