diff --git a/components/wizard/context/validationError.ts b/components/wizard/context/validationError.ts index 6153d99..121b4e8 100644 --- a/components/wizard/context/validationError.ts +++ b/components/wizard/context/validationError.ts @@ -1,5 +1,16 @@ +import { VALIDATION_ERRORS } from '../../../db/enums' + interface ValidationErrors { - [key: string]: { properties: { message: string } } + [key: string]: { properties: { message: string }; kind: string } +} + +function getDefinedValidationMessage(kind: string) { + switch (kind) { + case VALIDATION_ERRORS.AT_LEAST_ONE_DAY_BOOKED: + return 'Mindestens ein angefragter Tag ist nicht mehr verfügbar' + default: + return null + } } export class ValidationError extends Error { @@ -16,9 +27,12 @@ export class ValidationError extends Error { } get message() { - return Object.entries<{ properties: { message: string } }>(this.errors) + return Object.entries<{ properties: { message: string }; kind: string }>( + this.errors + ) .map(([_key, value]) => { - return `${value?.properties?.message}` + const validationMessage = getDefinedValidationMessage(value.kind) + return validationMessage || `${value?.properties?.message}` }) .join(',') } diff --git a/db/booking.ts b/db/booking.ts index fd5f131..731ce7f 100644 --- a/db/booking.ts +++ b/db/booking.ts @@ -4,7 +4,8 @@ import { dateFormatBackend, getDays, nowInTz } from '../helpers/date' import { Bill } from './bill' import { Booker } from './booker' -import { BOOKING_STATUS } from './enums' +import { BOOKING_STATUS, VALIDATION_ERRORS } from './enums' +import { getBookedDays } from './index' export interface Booking { uuid: string @@ -71,6 +72,19 @@ const BookingSchema = new mongoose.Schema( days: { type: [String], required: true, + validate: { + validator: async function (days: string[]) { + const bookedDays = await getBookedDays() + + const doubleBookedDays = days.filter((day: string) => + bookedDays.includes(day) + ) + return doubleBookedDays.length === 0 + }, + message: (props: { value: string[] }) => + `At least one day is of ${props.value.join(',')} is already booked`, + type: VALIDATION_ERRORS.AT_LEAST_ONE_DAY_BOOKED, + }, }, status: { type: String, @@ -89,7 +103,7 @@ const BookingSchema = new mongoose.Schema( } ) -BookingSchema.pre('save', function (next) { +BookingSchema.pre('validate', function (next: () => void) { const booking = this as BookingDocument booking.days = getDays({ startDate: new Date(booking.startDate), diff --git a/db/enums.ts b/db/enums.ts index da6040c..2e57aba 100644 --- a/db/enums.ts +++ b/db/enums.ts @@ -16,3 +16,7 @@ export enum MILAGE_TARIFS { EXTERN = 'extern', NOCHARGE = 'nocharge', } + +export enum VALIDATION_ERRORS { + AT_LEAST_ONE_DAY_BOOKED = 'atLeastOneDayBooked', +} diff --git a/db/index.ts b/db/index.ts index 9df41ac..d877a4f 100644 --- a/db/index.ts +++ b/db/index.ts @@ -1,9 +1,7 @@ import * as mongoose from 'mongoose' -import { getYear } from 'date-fns' import BookerModel, { Booker } from './booker' import BookingModel, { Booking } from './booking' import BillModel, { Bill } from './bill' -import { dateFormatFrontend } from '../helpers/date' import { BOOKING_STATUS } from './enums' let connectedPromise: Promise @@ -66,20 +64,6 @@ export async function createBooking({ org, destination, }) - const bookedDays = await getBookedDays() - - const doubleBookedDays = booking.days.filter((day: string) => - bookedDays.includes(day) - ) - if (doubleBookedDays.length) { - const error = new mongoose.Error.ValidationError(booking.uuid) - error.errors.days = new mongoose.Error.ValidatorError( - `${doubleBookedDays - .map((dateString) => dateFormatFrontend(new Date(dateString))) - .join(', ')} schon gebucht` - ) - throw error - } let booker = await BookerModel.findOne({ email }).exec() if (!booker) {