178 lines
5.3 KiB
JavaScript

import { z } from "zod";
import { localToUtc } from "../../utils/appUtils";
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" }),
gstNumber: z.string().optional(),
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",
}),
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" }),
})
.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: "",
gstNumber: "",
billAttachments: [],
};
export const ExpenseActionScheam = (
isReimbursement = false,
transactionDate
) => {
return z
.object({
comment: z.string().min(1, { message: "Please leave comment" }),
statusId: z.string().min(1, { message: "Please select a status" }),
reimburseTransactionId: z.string().nullable().optional(),
reimburseDate: z.string().nullable().optional(),
reimburseById: z.string().nullable().optional(),
})
.superRefine((data, ctx) => {
if (isReimbursement) {
if (!data.reimburseTransactionId?.trim()) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["reimburseTransactionId"],
message: "Reimburse Transaction ID is required",
});
}
if (!data.reimburseDate) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["reimburseDate"],
message: "Reimburse Date is required",
});
}
// let reimburse_Date = localToUtc(data.reimburseDate);
// if (transactionDate > reimburse_Date) {
// ctx.addIssue({
// code: z.ZodIssueCode.custom,
// path: ["reimburseDate"],
// message:
// "Reimburse Date must be greater than or equal to Expense created Date",
// });
// }
if (!data.reimburseById) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["reimburseById"],
message: "Reimburse By is required",
});
}
}
});
};
export const defaultActionValues = {
comment: "",
statusId: "",
reimburseTransactionId: null,
reimburseDate: null,
reimburseById: null,
};
export const SearchSchema = z.object({
projectIds: z.array(z.string()).optional(),
statusIds: z.array(z.string()).optional(),
createdByIds: z.array(z.string()).optional(),
paidById: z.array(z.string()).optional(),
ExpenseTypeIds: z.array(z.string()).optional(),
startDate: z.string().optional(),
endDate: z.string().optional(),
isTransactionDate: z.boolean().default(true),
});
export const defaultFilter = {
projectIds: [],
statusIds: [],
createdByIds: [],
paidById: [],
ExpenseTypeIds: [],
isTransactionDate: true,
startDate: null,
endDate: null,
};