import { z } from "zod"; import { tr } from "../../i18n/tr"; import { MAX_ATTACHMENTS_PER_RECORD } from "../attachments"; import { BARCODE_PATTERN } from "../products"; import { parseQuantity } from "../quantity"; const v = tr.validation; const s = tr.products.validation; const quantity = (message: string) => z .string() .trim() .transform((x, ctx) => { const q = parseQuantity(x); if (q === null || q <= 0) { ctx.addIssue({ code: "custom", message }); return z.NEVER; } return q; }); /** * Ürün (marka/varyant). Dönüşümün zorunlu olup olmadığı ürün tipinin birimine bağlı olduğundan * serviste denetlenir; burada yalnızca biçim. */ export const productFormSchema = z.object({ productTypeId: z.string().regex(/^[a-f0-9]{24}$/i, s.productType), brand: z.string().trim().min(1, tr.common.required).max(60, v.nameMax), name: z.string().trim().max(120).default(""), barcode: z .string() .trim() .transform((x) => x.replace(/\s/g, "")) .refine((x) => x === "" || BARCODE_PATTERN.test(x), s.barcode) .transform((x) => (x === "" ? null : x)), packageQuantity: quantity(s.packageQuantity), packageUnit: z.string().trim().min(1, s.packageUnit).max(20, s.packageUnit), typeQuantity: z.preprocess( (x) => (x === undefined || x === null || String(x).trim() === "" ? null : x), quantity(s.typeQuantity).nullable(), ), note: z.string().trim().max(300).default(""), imageIds: z.array(z.string().regex(/^[a-f0-9]{24}$/i)).max(MAX_ATTACHMENTS_PER_RECORD), }); export type ProductFormInput = z.input; export type ProductForm = z.output;