import { z } from "zod" import { ChildBedTypeEnum } from "@/constants/booking" import { phoneValidator } from "@/utils/zod/phoneValidator" import { nullableStringValidator } from "@/utils/zod/stringValidator" // MUTATION export const createBookingSchema = z .object({ data: z.object({ attributes: z.object({ reservationStatus: z.string(), paymentUrl: z.string().nullable().optional(), rooms: z .array( z.object({ confirmationNumber: z.string(), cancellationNumber: z.string().nullable(), priceChangedMetadata: z .object({ roomPrice: z.number(), totalPrice: z.number(), }) .nullable() .optional(), }) ) .default([]), errors: z .array( z.object({ confirmationNumber: z.string().nullable().optional(), errorCode: z.string(), description: z.string().nullable().optional(), meta: z .record(z.string(), z.union([z.string(), z.number()])) .nullable() .optional(), }) ) .default([]), }), type: z.string(), id: z.string(), links: z.object({ self: z.object({ href: z.string().url(), meta: z.object({ method: z.string(), }), }), }), }), }) .transform((d) => ({ id: d.data.id, links: d.data.links, type: d.data.type, reservationStatus: d.data.attributes.reservationStatus, paymentUrl: d.data.attributes.paymentUrl, rooms: d.data.attributes.rooms, errors: d.data.attributes.errors, })) // QUERY const childBedPreferencesSchema = z.object({ bedType: z.nativeEnum(ChildBedTypeEnum), quantity: z.number().int(), code: z.string().nullable().default(""), }) const guestSchema = z.object({ email: z.string().email().nullable().default(""), firstName: z.string().nullable().default(""), lastName: z.string().nullable().default(""), membershipNumber: z.string().nullable().default(""), phoneNumber: phoneValidator().nullable().default(""), }) const packageSchema = z .object({ description: z.string().nullable().default(""), type: z.string().nullable().default(""), code: z.string().nullable().default(""), price: z.object({ unit: z.number().int().nullable(), unitPrice: z.number(), totalPrice: z.number().nullable(), totalUnit: z.number().int().nullable(), currency: z.string().default(""), points: z.number().int().nullable(), }), }) .transform((packageData) => ({ description: packageData.description, code: packageData.code, type: packageData.type, currency: packageData.price.currency, points: packageData.price.points, totalPrice: packageData.price.totalPrice ?? 0, totalUnit: packageData.price.totalUnit ?? 0, unit: packageData.price.unit ?? 0, unitPrice: packageData.price.unitPrice, })) const ancillarySchema = z .object({ comment: z.string().default(""), deliveryTime: z.string().default(""), }) .nullable() .default({ comment: "", deliveryTime: "", }) const rateDefinitionSchema = z.object({ breakfastIncluded: z.boolean().default(false), cancellationRule: z.string().nullable().default(""), cancellationText: z.string().nullable().default(""), generalTerms: z.array(z.string()).default([]), isMemberRate: z.boolean().default(false), mustBeGuaranteed: z.boolean().default(false), rateCode: z.string().nullable().default(""), title: z.string().nullable().default(""), }) export const linkedReservationsSchema = z.object({ confirmationNumber: z.string().default(""), hotelId: z.string().default(""), checkinDate: z.string(), checkoutDate: z.string(), cancellationNumber: nullableStringValidator, roomTypeCode: z.string().default(""), adults: z.number().int(), children: z.number().int(), profileId: z.string().default(""), }) const linksSchema = z.object({ addAncillary: z .object({ href: z.string(), meta: z.object({ method: z.string(), }), }) .nullable(), cancel: z .object({ href: z.string(), meta: z.object({ method: z.string(), }), }) .nullable(), guarantee: z .object({ href: z.string(), meta: z.object({ method: z.string(), }), }) .nullable(), modify: z .object({ href: z.string(), meta: z.object({ method: z.string(), }), }) .nullable(), self: z .object({ href: z.string(), meta: z.object({ method: z.string(), }), }) .nullable(), }) export const bookingConfirmationSchema = z .object({ data: z.object({ attributes: z.object({ adults: z.number().int(), ancillary: ancillarySchema, checkInDate: z.date({ coerce: true }), checkOutDate: z.date({ coerce: true }), childBedPreferences: z.array(childBedPreferencesSchema).default([]), childrenAges: z.array(z.number().int()).default([]), canChangeDate: z.boolean(), computedReservationStatus: z.string().nullable().default(""), confirmationNumber: z.string().nullable().default(""), createDateTime: z.date({ coerce: true }), currencyCode: z.string(), guest: guestSchema, isGuaranteedForLateArrival: z.boolean().optional(), linkedReservations: z.array(linkedReservationsSchema).default([]), hotelId: z.string(), packages: z.array(packageSchema).default([]), rateDefinition: rateDefinitionSchema, reservationStatus: z.string().nullable().default(""), roomPrice: z.number(), roomTypeCode: z.string().nullable().default(""), totalPrice: z.number(), totalPriceExVat: z.number(), vatAmount: z.number(), vatPercentage: z.number(), }), id: z.string(), type: z.literal("booking"), links: linksSchema, }), }) .transform(({ data }) => ({ ...data.attributes, showAncillaries: !!data.links.addAncillary, isCancelable: !!data.links.cancel, isModifiable: !!data.links.modify, }))