50 lines
1.4 KiB
TypeScript
50 lines
1.4 KiB
TypeScript
import { z } from "zod"
|
|
|
|
const relationFieldSchema = z
|
|
.object({ value: z.string(), label: z.string() })
|
|
.nullable()
|
|
|
|
const labelItemSchema = z.object({
|
|
id: z.number(),
|
|
title: z.string(),
|
|
color_code: z.string(),
|
|
})
|
|
|
|
const expenseLineItemSchema = z.object({
|
|
expense_id: z.number(),
|
|
title: z.string(),
|
|
quantity: z.number().min(1),
|
|
rate: z.number().min(0),
|
|
discount_amount: z.number().min(0).optional(),
|
|
chart_of_account: z.string().optional(),
|
|
description: z.string().optional(),
|
|
})
|
|
|
|
const expenseFormSchema = z.object({
|
|
// ── Relations ──
|
|
job_card: relationFieldSchema,
|
|
category: relationFieldSchema,
|
|
vendor: relationFieldSchema,
|
|
department: relationFieldSchema,
|
|
tax: relationFieldSchema,
|
|
|
|
// ── Basic info ──
|
|
title: z.string().min(1, "Title is required"),
|
|
invoice_number: z.string().optional(),
|
|
expense_date: z.string().optional(),
|
|
notes: z.string().optional(),
|
|
status: z.string().optional(),
|
|
|
|
// ── Discount / Tax ──
|
|
discount: z.string().optional(),
|
|
discount_amount: z.coerce.number().min(0).optional(),
|
|
|
|
labels: z.array(labelItemSchema).optional(),
|
|
items: z.array(expenseLineItemSchema).optional(),
|
|
})
|
|
|
|
type ExpenseFormValues = z.infer<typeof expenseFormSchema>
|
|
|
|
export { expenseFormSchema, relationFieldSchema }
|
|
export type { ExpenseFormValues }
|