fix double booked day validation

This commit is contained in:
Thomas Ruoff
2020-12-23 23:38:53 +01:00
parent b723fc5660
commit 2a5c9b8638
4 changed files with 37 additions and 21 deletions

View File

@@ -1,5 +1,16 @@
import { VALIDATION_ERRORS } from '../../../db/enums'
interface ValidationErrors { 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 { export class ValidationError extends Error {
@@ -16,9 +27,12 @@ export class ValidationError extends Error {
} }
get message() { get message() {
return Object.entries<{ properties: { message: string } }>(this.errors) return Object.entries<{ properties: { message: string }; kind: string }>(
this.errors
)
.map(([_key, value]) => { .map(([_key, value]) => {
return `${value?.properties?.message}` const validationMessage = getDefinedValidationMessage(value.kind)
return validationMessage || `${value?.properties?.message}`
}) })
.join(',') .join(',')
} }

View File

@@ -4,7 +4,8 @@ import { dateFormatBackend, getDays, nowInTz } from '../helpers/date'
import { Bill } from './bill' import { Bill } from './bill'
import { Booker } from './booker' import { Booker } from './booker'
import { BOOKING_STATUS } from './enums' import { BOOKING_STATUS, VALIDATION_ERRORS } from './enums'
import { getBookedDays } from './index'
export interface Booking { export interface Booking {
uuid: string uuid: string
@@ -71,6 +72,19 @@ const BookingSchema = new mongoose.Schema<BookingDocument>(
days: { days: {
type: [String], type: [String],
required: true, 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: { status: {
type: String, type: String,
@@ -89,7 +103,7 @@ const BookingSchema = new mongoose.Schema<BookingDocument>(
} }
) )
BookingSchema.pre('save', function (next) { BookingSchema.pre('validate', function (next: () => void) {
const booking = this as BookingDocument const booking = this as BookingDocument
booking.days = getDays({ booking.days = getDays({
startDate: new Date(booking.startDate), startDate: new Date(booking.startDate),

View File

@@ -16,3 +16,7 @@ export enum MILAGE_TARIFS {
EXTERN = 'extern', EXTERN = 'extern',
NOCHARGE = 'nocharge', NOCHARGE = 'nocharge',
} }
export enum VALIDATION_ERRORS {
AT_LEAST_ONE_DAY_BOOKED = 'atLeastOneDayBooked',
}

View File

@@ -1,9 +1,7 @@
import * as mongoose from 'mongoose' import * as mongoose from 'mongoose'
import { getYear } from 'date-fns'
import BookerModel, { Booker } from './booker' import BookerModel, { Booker } from './booker'
import BookingModel, { Booking } from './booking' import BookingModel, { Booking } from './booking'
import BillModel, { Bill } from './bill' import BillModel, { Bill } from './bill'
import { dateFormatFrontend } from '../helpers/date'
import { BOOKING_STATUS } from './enums' import { BOOKING_STATUS } from './enums'
let connectedPromise: Promise<typeof mongoose> let connectedPromise: Promise<typeof mongoose>
@@ -66,20 +64,6 @@ export async function createBooking({
org, org,
destination, 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() let booker = await BookerModel.findOne({ email }).exec()
if (!booker) { if (!booker) {