import { z } from "zod"; import { numberFromForm, nonNegativeNumberFromForm, positiveNumberFromForm, intIdFromForm, nullableNumberFromForm, nullableIntIdFromForm, booleanFromForm, isoDateString, } from "./common"; // === Categories === export const CreateCategorySchema = z.object({ name: z.string().min(1, "Název je povinný").max(255), description: z.string().max(5000).nullish(), sort_order: numberFromForm.optional().default(0), }); export const UpdateCategorySchema = z.object({ name: z.string().min(1, "Název je povinný").max(255).optional(), description: z.string().max(5000).nullish(), sort_order: numberFromForm.optional(), }); export type CreateCategoryInput = z.infer; export type UpdateCategoryInput = z.infer; // === Suppliers === // Full mirror of the customers model: structured address + custom_fields // (the dedicated contact_person/email/phone/notes columns and the free-text // `address` blob were dropped; legacy clients sending them are silently // stripped by z.object). Limits are DB-aligned. export const CreateSupplierSchema = z.object({ name: z.string().min(1, "Název je povinný").max(255), ico: z.string().max(255).nullish(), dic: z.string().max(255).nullish(), street: z.string().max(255).nullish(), city: z.string().max(255).nullish(), postal_code: z.string().max(20).nullish(), country: z.string().max(100).nullish(), custom_fields: z.array(z.unknown()).max(100).optional(), is_active: booleanFromForm.optional().default(true), }); export const UpdateSupplierSchema = z.object({ name: z.string().min(1, "Název je povinný").max(255).optional(), ico: z.string().max(255).nullish(), dic: z.string().max(255).nullish(), street: z.string().max(255).nullish(), city: z.string().max(255).nullish(), postal_code: z.string().max(20).nullish(), country: z.string().max(100).nullish(), custom_fields: z.array(z.unknown()).max(100).optional(), is_active: booleanFromForm.optional(), }); export type CreateSupplierInput = z.infer; export type UpdateSupplierInput = z.infer; // === Locations === export const CreateLocationSchema = z.object({ code: z.string().min(1, "Kód je povinný").max(255), name: z.string().min(1, "Název je povinný").max(255), description: z.string().max(5000).nullish(), is_active: booleanFromForm.optional().default(true), }); export const UpdateLocationSchema = z.object({ code: z.string().min(1, "Kód je povinný").max(255).optional(), name: z.string().min(1, "Název je povinný").max(255).optional(), description: z.string().max(5000).nullish(), is_active: booleanFromForm.optional(), }); export type CreateLocationInput = z.infer; export type UpdateLocationInput = z.infer; // === Items === const UNIT_LIST = ["ks", "m", "kg", "bal", "sada", "m2", "m3", "l"] as const; export const UnitEnum = z.enum(UNIT_LIST); export type Unit = z.infer; export const CreateItemSchema = z.object({ item_number: z.string().max(255).nullish(), name: z.string().min(1, "Název je povinný").max(255), description: z.string().max(5000).nullish(), category_id: nullableIntIdFromForm.nullish(), unit: UnitEnum, min_quantity: nullableNumberFromForm.nullish(), notes: z.string().max(5000).nullish(), is_active: booleanFromForm.optional().default(true), }); export const UpdateItemSchema = z.object({ item_number: z.string().max(255).nullish(), name: z.string().min(1, "Název je povinný").max(255).optional(), description: z.string().max(5000).nullish(), category_id: nullableIntIdFromForm.nullish(), unit: UnitEnum.optional(), min_quantity: nullableNumberFromForm.nullish(), notes: z.string().max(5000).nullish(), is_active: booleanFromForm.optional(), }); export type CreateItemInput = z.infer; export type UpdateItemInput = z.infer; // === Receipts === export const ReceiptItemSchema = z.object({ item_id: intIdFromForm, quantity: positiveNumberFromForm, unit_price: nonNegativeNumberFromForm, location_id: nullableIntIdFromForm.nullish(), notes: z.string().max(5000).nullish(), }); export const CreateReceiptSchema = z.object({ supplier_id: nullableIntIdFromForm.nullish(), delivery_note_number: z.string().max(255).nullish(), delivery_note_date: isoDateString.nullish(), notes: z.string().max(5000).nullish(), items: z .array(ReceiptItemSchema) .min(1, "Příjem musí obsahovat alespoň jednu položku"), }); export const UpdateReceiptSchema = z.object({ supplier_id: nullableIntIdFromForm.nullish(), delivery_note_number: z.string().max(255).nullish(), delivery_note_date: isoDateString.nullish(), notes: z.string().max(5000).nullish(), items: z .array(ReceiptItemSchema) .min(1, "Příjem musí obsahovat alespoň jednu položku") .optional(), }); export type CreateReceiptInput = z.infer; export type UpdateReceiptInput = z.infer; export type ReceiptItemInput = z.infer; // === Issues === export const IssueItemSchema = z.object({ item_id: intIdFromForm, batch_id: nullableIntIdFromForm.nullish(), quantity: positiveNumberFromForm, location_id: nullableIntIdFromForm.nullish(), reservation_id: nullableIntIdFromForm.nullish(), notes: z.string().max(5000).nullish(), }); export const CreateIssueSchema = z.object({ project_id: intIdFromForm, notes: z.string().max(5000).nullish(), items: z .array(IssueItemSchema) .min(1, "Výdej musí obsahovat alespoň jednu položku"), }); export const UpdateIssueSchema = z.object({ project_id: intIdFromForm.optional(), notes: z.string().max(5000).nullish(), items: z .array(IssueItemSchema) .min(1, "Výdej musí obsahovat alespoň jednu položku") .optional(), }); export type CreateIssueInput = z.infer; export type UpdateIssueInput = z.infer; export type IssueItemInput = z.infer; // === Reservations === export const CreateReservationSchema = z.object({ item_id: intIdFromForm, project_id: intIdFromForm, quantity: positiveNumberFromForm, notes: z.string().max(5000).nullish(), }); export type CreateReservationInput = z.infer; // === Inventory === export const InventoryItemSchema = z.object({ item_id: intIdFromForm, location_id: nullableIntIdFromForm.nullish(), actual_qty: nonNegativeNumberFromForm, notes: z.string().max(5000).nullish(), }); export const CreateInventorySessionSchema = z.object({ notes: z.string().max(5000).nullish(), items: z .array(InventoryItemSchema) .min(1, "Inventura musí obsahovat alespoň jednu položku"), }); export const UpdateInventorySessionSchema = z.object({ notes: z.string().max(5000).nullish(), items: z .array(InventoryItemSchema) .min(1, "Inventura musí obsahovat alespoň jednu položku") .optional(), }); export type CreateInventorySessionInput = z.infer< typeof CreateInventorySessionSchema >; export type UpdateInventorySessionInput = z.infer< typeof UpdateInventorySessionSchema >; export type InventoryItemInput = z.infer;