import { z } from "zod"; import { paginationModel } from "../../../core/pagination.utils"; import { encodeCursor } from "../../../core/string.utils"; import { customerInfoModel } from "../../customerinfo/data"; import { paymentDetailsPayloadModel } from "../../paymentinfo/data/entities"; import { productModel } from "../../product/data"; export enum OrderCreationStep { ACCOUNT_SELECTION = 0, TICKET_SELECTION = 1, // TODO: only keep these remove the above 2 steps CUSTOMER_INFO = 2, PAYMENT = 2, SUMMARY = 3, } export enum OrderStatus { PENDING_FULFILLMENT = "PENDING_FULFILLMENT", PARTIALLY_FULFILLED = "PARTIALLY_FULFILLED", FULFILLED = "FULFILLED", CANCELLED = "CANCELLED", } export const orderModel = z.object({ id: z.coerce.number().int().positive(), discountAmount: z.coerce.number().min(0), basePrice: z.coerce.number().min(0), displayPrice: z.coerce.number().min(0), orderPrice: z.coerce.number().min(0), fullfilledPrice: z.coerce.number().min(0), status: z.nativeEnum(OrderStatus), productId: z.number(), customerInfoId: z.number().nullish().optional(), emailAccountId: z.number().nullish().optional(), paymentDetailsId: z.number().nullish().optional(), createdAt: z.coerce.string(), updatedAt: z.coerce.string(), }); export type OrderModel = z.infer; export const limitedOrderWithProductModel = orderModel .pick({ id: true, basePrice: true, discountAmount: true, displayPrice: true, fullfilledPrice: true, status: true, }) .merge( z.object({ product: productModel.pick({ id: true, title: true, description: true, price: true, discountPrice: true, }), }), ); export type LimitedOrderWithProductModel = z.infer< typeof limitedOrderWithProductModel >; export const fullOrderModel = orderModel.merge( z.object({ product: productModel, customerInfo: customerInfoModel.optional().nullable(), }), ); export type FullOrderModel = z.infer; export const orderCursorModel = z.object({ firstItemId: z.number(), lastItemId: z.number(), query: z.string().default(""), }); export type OrderCursorModel = z.infer; export function getDefaultOrderCursor() { return orderCursorModel.parse({ firstItemId: 0, lastItemId: 0, query: "" }); } export const paginatedOrderInfoModel = paginationModel.merge( z.object({ data: z.array(orderModel) }), ); export type PaginatedOrderInfoModel = z.infer; export function getDefaultPaginatedOrderInfoModel(): PaginatedOrderInfoModel { return { data: [], cursor: encodeCursor(getDefaultOrderCursor()), limit: 20, asc: true, totalItemCount: 0, totalPages: 0, page: 0, }; } export const newOrderModel = orderModel.pick({ basePrice: true, displayPrice: true, discountAmount: true, orderPrice: true, fullfilledPrice: true, productId: true, customerInfoId: true, paymentDetailsId: true, emailAccountId: true, }); export type NewOrderModel = z.infer; export const createOrderPayloadModel = z.object({ product: productModel.optional(), productId: z.number().optional(), customerInfo: customerInfoModel, paymentDetails: paymentDetailsPayloadModel.optional(), orderModel: newOrderModel, }); export type CreateOrderModel = z.infer;