feat(warehouse): add Zod validation schemas
This commit is contained in:
242
src/schemas/warehouse.schema.ts
Normal file
242
src/schemas/warehouse.schema.ts
Normal file
@@ -0,0 +1,242 @@
|
|||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
// === Categories ===
|
||||||
|
export const CreateCategorySchema = z.object({
|
||||||
|
name: z.string().min(1, "Název je povinný"),
|
||||||
|
description: z.string().nullish(),
|
||||||
|
sort_order: z
|
||||||
|
.union([z.number(), z.string()])
|
||||||
|
.transform((v) => Number(v))
|
||||||
|
.optional()
|
||||||
|
.default(0),
|
||||||
|
});
|
||||||
|
export const UpdateCategorySchema = z.object({
|
||||||
|
name: z.string().min(1, "Název je povinný").optional(),
|
||||||
|
description: z.string().nullish(),
|
||||||
|
sort_order: z
|
||||||
|
.union([z.number(), z.string()])
|
||||||
|
.transform((v) => Number(v))
|
||||||
|
.optional(),
|
||||||
|
});
|
||||||
|
export type CreateCategoryInput = z.infer<typeof CreateCategorySchema>;
|
||||||
|
export type UpdateCategoryInput = z.infer<typeof UpdateCategorySchema>;
|
||||||
|
|
||||||
|
// === Suppliers ===
|
||||||
|
export const CreateSupplierSchema = z.object({
|
||||||
|
name: z.string().min(1, "Název je povinný"),
|
||||||
|
ico: z.string().nullish(),
|
||||||
|
dic: z.string().nullish(),
|
||||||
|
contact_person: z.string().nullish(),
|
||||||
|
email: z.string().nullish(),
|
||||||
|
phone: z.string().nullish(),
|
||||||
|
address: z.string().nullish(),
|
||||||
|
notes: z.string().nullish(),
|
||||||
|
is_active: z
|
||||||
|
.preprocess((v) => v === true || v === 1 || v === "1", z.boolean())
|
||||||
|
.optional()
|
||||||
|
.default(true),
|
||||||
|
});
|
||||||
|
export const UpdateSupplierSchema = z.object({
|
||||||
|
name: z.string().min(1, "Název je povinný").optional(),
|
||||||
|
ico: z.string().nullish(),
|
||||||
|
dic: z.string().nullish(),
|
||||||
|
contact_person: z.string().nullish(),
|
||||||
|
email: z.string().nullish(),
|
||||||
|
phone: z.string().nullish(),
|
||||||
|
address: z.string().nullish(),
|
||||||
|
notes: z.string().nullish(),
|
||||||
|
is_active: z
|
||||||
|
.preprocess((v) => v === true || v === 1 || v === "1", z.boolean())
|
||||||
|
.optional(),
|
||||||
|
});
|
||||||
|
export type CreateSupplierInput = z.infer<typeof CreateSupplierSchema>;
|
||||||
|
export type UpdateSupplierInput = z.infer<typeof UpdateSupplierSchema>;
|
||||||
|
|
||||||
|
// === Locations ===
|
||||||
|
export const CreateLocationSchema = z.object({
|
||||||
|
code: z.string().min(1, "Kód je povinný"),
|
||||||
|
name: z.string().min(1, "Název je povinný"),
|
||||||
|
description: z.string().nullish(),
|
||||||
|
is_active: z
|
||||||
|
.preprocess((v) => v === true || v === 1 || v === "1", z.boolean())
|
||||||
|
.optional()
|
||||||
|
.default(true),
|
||||||
|
});
|
||||||
|
export const UpdateLocationSchema = z.object({
|
||||||
|
code: z.string().min(1, "Kód je povinný").optional(),
|
||||||
|
name: z.string().min(1, "Název je povinný").optional(),
|
||||||
|
description: z.string().nullish(),
|
||||||
|
is_active: z
|
||||||
|
.preprocess((v) => v === true || v === 1 || v === "1", z.boolean())
|
||||||
|
.optional(),
|
||||||
|
});
|
||||||
|
export type CreateLocationInput = z.infer<typeof CreateLocationSchema>;
|
||||||
|
export type UpdateLocationInput = z.infer<typeof UpdateLocationSchema>;
|
||||||
|
|
||||||
|
// === 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<typeof UnitEnum>;
|
||||||
|
|
||||||
|
export const CreateItemSchema = z.object({
|
||||||
|
item_number: z.string().nullish(),
|
||||||
|
name: z.string().min(1, "Název je povinný"),
|
||||||
|
description: z.string().nullish(),
|
||||||
|
category_id: z
|
||||||
|
.union([z.number(), z.string(), z.null()])
|
||||||
|
.transform((v) => (v === null ? null : Number(v)))
|
||||||
|
.nullish(),
|
||||||
|
unit: UnitEnum,
|
||||||
|
min_quantity: z
|
||||||
|
.union([z.number(), z.string(), z.null()])
|
||||||
|
.transform((v) => (v === null ? null : Number(v)))
|
||||||
|
.nullish(),
|
||||||
|
notes: z.string().nullish(),
|
||||||
|
is_active: z
|
||||||
|
.preprocess((v) => v === true || v === 1 || v === "1", z.boolean())
|
||||||
|
.optional()
|
||||||
|
.default(true),
|
||||||
|
});
|
||||||
|
export const UpdateItemSchema = z.object({
|
||||||
|
item_number: z.string().nullish(),
|
||||||
|
name: z.string().min(1, "Název je povinný").optional(),
|
||||||
|
description: z.string().nullish(),
|
||||||
|
category_id: z
|
||||||
|
.union([z.number(), z.string(), z.null()])
|
||||||
|
.transform((v) => (v === null ? null : Number(v)))
|
||||||
|
.nullish(),
|
||||||
|
unit: UnitEnum.optional(),
|
||||||
|
min_quantity: z
|
||||||
|
.union([z.number(), z.string(), z.null()])
|
||||||
|
.transform((v) => (v === null ? null : Number(v)))
|
||||||
|
.nullish(),
|
||||||
|
notes: z.string().nullish(),
|
||||||
|
is_active: z
|
||||||
|
.preprocess((v) => v === true || v === 1 || v === "1", z.boolean())
|
||||||
|
.optional(),
|
||||||
|
});
|
||||||
|
export type CreateItemInput = z.infer<typeof CreateItemSchema>;
|
||||||
|
export type UpdateItemInput = z.infer<typeof UpdateItemSchema>;
|
||||||
|
|
||||||
|
// === Receipts ===
|
||||||
|
export const ReceiptLineSchema = z.object({
|
||||||
|
item_id: z.union([z.number(), z.string()]).transform((v) => Number(v)),
|
||||||
|
quantity: z.union([z.number(), z.string()]).transform((v) => Number(v)),
|
||||||
|
unit_price: z.union([z.number(), z.string()]).transform((v) => Number(v)),
|
||||||
|
location_id: z
|
||||||
|
.union([z.number(), z.string(), z.null()])
|
||||||
|
.transform((v) => (v === null ? null : Number(v)))
|
||||||
|
.nullish(),
|
||||||
|
notes: z.string().nullish(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const CreateReceiptSchema = z.object({
|
||||||
|
supplier_id: z
|
||||||
|
.union([z.number(), z.string(), z.null()])
|
||||||
|
.transform((v) => (v === null ? null : Number(v)))
|
||||||
|
.nullish(),
|
||||||
|
delivery_note_number: z.string().nullish(),
|
||||||
|
delivery_note_date: z.union([z.string(), z.null()]).nullish(),
|
||||||
|
notes: z.string().nullish(),
|
||||||
|
lines: z
|
||||||
|
.array(ReceiptLineSchema)
|
||||||
|
.min(1, "Příjem musí obsahovat alespoň jednu položku"),
|
||||||
|
});
|
||||||
|
export const UpdateReceiptSchema = z.object({
|
||||||
|
supplier_id: z
|
||||||
|
.union([z.number(), z.string(), z.null()])
|
||||||
|
.transform((v) => (v === null ? null : Number(v)))
|
||||||
|
.nullish(),
|
||||||
|
delivery_note_number: z.string().nullish(),
|
||||||
|
delivery_note_date: z.union([z.string(), z.null()]).nullish(),
|
||||||
|
notes: z.string().nullish(),
|
||||||
|
lines: z
|
||||||
|
.array(ReceiptLineSchema)
|
||||||
|
.min(1, "Příjem musí obsahovat alespoň jednu položku")
|
||||||
|
.optional(),
|
||||||
|
});
|
||||||
|
export type CreateReceiptInput = z.infer<typeof CreateReceiptSchema>;
|
||||||
|
export type UpdateReceiptInput = z.infer<typeof UpdateReceiptSchema>;
|
||||||
|
export type ReceiptLineInput = z.infer<typeof ReceiptLineSchema>;
|
||||||
|
|
||||||
|
// === Issues ===
|
||||||
|
export const IssueLineSchema = z.object({
|
||||||
|
item_id: z.union([z.number(), z.string()]).transform((v) => Number(v)),
|
||||||
|
batch_id: z
|
||||||
|
.union([z.number(), z.string()])
|
||||||
|
.transform((v) => Number(v))
|
||||||
|
.nullish(),
|
||||||
|
quantity: z.union([z.number(), z.string()]).transform((v) => Number(v)),
|
||||||
|
location_id: z
|
||||||
|
.union([z.number(), z.string(), z.null()])
|
||||||
|
.transform((v) => (v === null ? null : Number(v)))
|
||||||
|
.nullish(),
|
||||||
|
reservation_id: z
|
||||||
|
.union([z.number(), z.string(), z.null()])
|
||||||
|
.transform((v) => (v === null ? null : Number(v)))
|
||||||
|
.nullish(),
|
||||||
|
notes: z.string().nullish(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const CreateIssueSchema = z.object({
|
||||||
|
project_id: z.union([z.number(), z.string()]).transform((v) => Number(v)),
|
||||||
|
notes: z.string().nullish(),
|
||||||
|
lines: z
|
||||||
|
.array(IssueLineSchema)
|
||||||
|
.min(1, "Výdej musí obsahovat alespoň jednu položku"),
|
||||||
|
});
|
||||||
|
export const UpdateIssueSchema = z.object({
|
||||||
|
project_id: z
|
||||||
|
.union([z.number(), z.string()])
|
||||||
|
.transform((v) => Number(v))
|
||||||
|
.optional(),
|
||||||
|
notes: z.string().nullish(),
|
||||||
|
lines: z
|
||||||
|
.array(IssueLineSchema)
|
||||||
|
.min(1, "Výdej musí obsahovat alespoň jednu položku")
|
||||||
|
.optional(),
|
||||||
|
});
|
||||||
|
export type CreateIssueInput = z.infer<typeof CreateIssueSchema>;
|
||||||
|
export type UpdateIssueInput = z.infer<typeof UpdateIssueSchema>;
|
||||||
|
export type IssueLineInput = z.infer<typeof IssueLineSchema>;
|
||||||
|
|
||||||
|
// === Reservations ===
|
||||||
|
export const CreateReservationSchema = z.object({
|
||||||
|
item_id: z.union([z.number(), z.string()]).transform((v) => Number(v)),
|
||||||
|
project_id: z.union([z.number(), z.string()]).transform((v) => Number(v)),
|
||||||
|
quantity: z.union([z.number(), z.string()]).transform((v) => Number(v)),
|
||||||
|
notes: z.string().nullish(),
|
||||||
|
});
|
||||||
|
export type CreateReservationInput = z.infer<typeof CreateReservationSchema>;
|
||||||
|
|
||||||
|
// === Inventory ===
|
||||||
|
export const InventoryLineSchema = z.object({
|
||||||
|
item_id: z.union([z.number(), z.string()]).transform((v) => Number(v)),
|
||||||
|
location_id: z
|
||||||
|
.union([z.number(), z.string(), z.null()])
|
||||||
|
.transform((v) => (v === null ? null : Number(v)))
|
||||||
|
.nullish(),
|
||||||
|
actual_qty: z.union([z.number(), z.string()]).transform((v) => Number(v)),
|
||||||
|
notes: z.string().nullish(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const CreateInventorySessionSchema = z.object({
|
||||||
|
notes: z.string().nullish(),
|
||||||
|
lines: z
|
||||||
|
.array(InventoryLineSchema)
|
||||||
|
.min(1, "Inventura musí obsahovat alespoň jednu položku"),
|
||||||
|
});
|
||||||
|
export const UpdateInventorySessionSchema = z.object({
|
||||||
|
notes: z.string().nullish(),
|
||||||
|
lines: z
|
||||||
|
.array(InventoryLineSchema)
|
||||||
|
.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 InventoryLineInput = z.infer<typeof InventoryLineSchema>;
|
||||||
Reference in New Issue
Block a user