marco.pms.web/src/components/purchase/PurchaseSchema.jsx

212 lines
5.8 KiB
JavaScript

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: "",
};