64 lines
2.2 KiB
TypeScript

import { z } from "zod"
import { RateType } from "@garage/api"
export const relationFieldSchema = z
.object({ value: z.string(), label: z.string() })
.nullable()
const requiredRelationFieldSchema = relationFieldSchema.superRefine((value, ctx) => {
if (!value?.value) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "This field is required",
})
}
})
const optionalNumericField = z.preprocess(
(value) => {
if (value === "" || value === null || value === undefined) {
return undefined
}
return Number(value)
},
z.number().min(0).optional(),
)
const optionalIntegerField = z.preprocess(
(value) => {
if (value === "" || value === null || value === undefined) {
return undefined
}
return Number(value)
},
z.number().int().optional(),
)
export const RATE_TYPE_OPTIONS = RateType
export const serviceFormSchema = z.object({
shop_type: requiredRelationFieldSchema,
category: requiredRelationFieldSchema,
unit_type: requiredRelationFieldSchema,
department: requiredRelationFieldSchema,
labor_name: z.string().trim().min(1, "Labor name is required").max(255, "Labor name must be at most 255 characters"),
service_code: z.string().trim().min(1, "Service code is required").max(255, "Service code must be at most 255 characters"),
labor_matrix: z.string().trim().min(1, "Labor matrix is required").max(255, "Labor matrix must be at most 255 characters"),
description: z.string().optional(),
sales_information: z.boolean().default(false),
rate_type: z.preprocess(
(value) => (value === "" || value === null ? undefined : value),
z.enum(RATE_TYPE_OPTIONS).optional(),
),
labor_rate: relationFieldSchema,
labor_hours: optionalNumericField,
sales_chart_of_account: optionalIntegerField,
selling_price: optionalNumericField,
purchase_information: z.boolean().default(false),
purchase_chart_of_account: optionalIntegerField,
purchase_preferred_vendor: relationFieldSchema,
purchase_price: optionalNumericField,
})
export type ServiceFormValues = z.infer<typeof serviceFormSchema>