f0b570284e
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
48 lines
1.7 KiB
TypeScript
48 lines
1.7 KiB
TypeScript
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<typeof productFormSchema>;
|
||
export type ProductForm = z.output<typeof productFormSchema>;
|