remover booker, that's overdosed

It also brings the problem of consolidating bookers over multiple
bookings. The amount of data is not justifying having it in an own
entity
This commit is contained in:
Thomas Ruoff
2021-06-21 23:21:23 +02:00
parent 3700b5f450
commit 9f3b6bb2e1
13 changed files with 63 additions and 86 deletions

View File

@@ -3,13 +3,11 @@ import { useRouter } from 'next/router'
import { clearBookingData, loadBookingData } from '../helpers/storage'
import { createBooking } from '../helpers/booking'
import { Booker } from '../db/booker'
import { Booking } from '../db/booking'
export type BookFormData = Omit<Booking, 'uuid'> &
Booker & {
storeData?: boolean
}
export type BookFormData = Omit<Booking, 'uuid'> & {
storeData?: boolean
}
type BookingProviderState = {
postData?: boolean

View File

@@ -1,31 +0,0 @@
import * as mongoose from 'mongoose'
export type Booker = {
name: string
email: string
phone: string
street: string
zip: string
city: string
}
export type BookerDocument = Booker &
mongoose.SchemaTimestampsConfig &
mongoose.Document
export type BookerModel = mongoose.Model<BookerDocument>
const BookerSchema = new mongoose.Schema<BookerDocument>(
{
name: { type: String, required: true },
email: { type: String, required: true, unique: true, minlength: 5 },
phone: { type: String, required: false },
street: { type: String, required: true },
zip: { type: String, required: true },
city: { type: String, required: true },
},
{ timestamps: true, collation: { locale: 'de', strength: 1 } }
)
export default <BookerModel>mongoose.models.Booker ||
mongoose.model<BookerDocument, BookerModel>('Booker', BookerSchema)

View File

@@ -3,13 +3,17 @@ import { v4 as uuidv4 } from 'uuid'
import { dateFormatBackend, getDays, nowInTz } from '../helpers/date'
import { Bill } from './bill'
import { Booker } from './booker'
import { BOOKING_STATUS, VALIDATION_ERRORS } from './enums'
import { getBookedDays } from './index'
export type Booking = {
uuid: string
booker?: Booker
name: string
email: string
phone: string
street: string
zip: string
city: string
bill?: Bill
startDate: string
endDate: string
@@ -36,11 +40,12 @@ const BookingSchema = new mongoose.Schema<BookingDocument>(
default: uuidv4,
index: true,
},
booker: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Booker',
required: true,
},
name: { type: String, required: true },
email: { type: String, required: true, minlength: 5 },
phone: { type: String, required: false },
street: { type: String, required: true },
zip: { type: String, required: true },
city: { type: String, required: true },
bill: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Bill',

View File

@@ -1,5 +1,4 @@
import * as mongoose from 'mongoose'
import BookerModel, { Booker } from './booker'
import BookingModel, { Booking, BookingDocument } from './booking'
import BillModel, { Bill } from './bill'
import { BOOKING_STATUS } from './enums'
@@ -20,7 +19,9 @@ function connect(): Promise<typeof mongoose> {
return connectedPromise
}
export async function getBookedDays(uuidsToIngore?: string[]): Promise<string[]> {
export async function getBookedDays(
uuidsToIngore?: string[]
): Promise<string[]> {
await connect()
return BookingModel.findBookedDays(uuidsToIngore)
}
@@ -33,14 +34,14 @@ export async function getBookingByUUID(uuid: string): Promise<BookingDocument> {
export async function getBookings({
status = [BOOKING_STATUS.CONFIRMED, BOOKING_STATUS.REQUESTED],
startDateGreaterThan = '2000-01-01T00:00:00Z',
}: { status?: BOOKING_STATUS[]; startDateGreaterThan?: string } = {}): Promise<BookingDocument[]> {
}: { status?: BOOKING_STATUS[]; startDateGreaterThan?: string } = {}): Promise<
BookingDocument[]
> {
await connect()
return await BookingModel.find({
status: { $in: status },
startDate: { $gte: startDateGreaterThan },
})
.populate('booker')
.exec()
}).exec()
}
export async function createBooking({
@@ -55,7 +56,7 @@ export async function createBooking({
street,
zip,
city,
}: Booking & Booker): Promise<Booking> {
}: Booking): Promise<Booking> {
await connect()
const booking = new BookingModel({
startDate,
@@ -63,17 +64,15 @@ export async function createBooking({
purpose,
org,
destination,
name,
email,
phone,
street,
zip,
city,
})
let booker = await BookerModel.findOne({ email }).exec()
if (!booker) {
booker = new BookerModel({ name, email, phone, street, zip, city })
await booker.save()
}
booking.booker = booker._id
await booking.save()
await booking.populate('booker').execPopulate()
return booking.toJSON()
}

View File

@@ -21,7 +21,7 @@ export function generateCalendarEntry(booking: Booking): string {
duration: { days: booking.days.length },
location: 'Mömpelgardgasse 25, 72348 Rosenfeld, Deutschland',
geo: { lat: 48.287044, lon: 8.726361 },
description: `Gebucht auf ${booking.booker.name}
description: `Gebucht auf ${booking.name}
Buchungs-Link: ${getBaseURL()}/booking/${booking.uuid}
`,
@@ -39,18 +39,27 @@ Buchungs-Link: ${getBaseURL()}/booking/${booking.uuid}
}
export function generateBookedCalendar(bookings: Booking[]): string {
const events = bookings.map((booking): { productId: string; calName: string; start: [number, number, number]; startOutputType: 'local' | 'utc'; duration: { days: number }; title: string; description: string; status: EventStatus } => ({
const events = bookings.map((booking): {
productId: string
calName: string
start: [number, number, number]
startOutputType: 'local' | 'utc'
duration: { days: number }
title: string
description: string
status: EventStatus
} => ({
productId: 'app.vercel.pfadi-bussle/ics',
calName: 'Pfadi-Bussle Buchungen',
start: convertDay(booking.days[0]),
startOutputType: 'local',
duration: { days: booking.days.length },
title: `Buchung ${booking.booker.name}`,
description: `Name: ${booking.booker.name}
title: `Buchung ${booking.name}`,
description: `Name: ${booking.name}
Zeitraum: ${daysFormatFrontend(booking.days)}
Email: ${booking.booker.email}
Telefon: ${booking.booker.phone}
Email: ${booking.email}
Telefon: ${booking.phone}
Link: ${getBaseURL()}/admin/booking/${booking.uuid}
`,

View File

@@ -32,7 +32,7 @@ Tel. 0151/212 253 62
`
function getReceivedBookingBookerText(booking: Booking): string {
return `Hallo liebe/r ${booking.booker.name},
return `Hallo liebe/r ${booking.name},
Vielen Dank für Deine Buchungsanfrage zum ${daysFormatFrontend(booking.days)}!
@@ -49,7 +49,7 @@ ${footer}
}
function getBookingConfirmedText(booking: Booking): string {
return `Hallo liebe/r ${booking.booker.name},
return `Hallo liebe/r ${booking.name},
deine Buchunganfrage zum ${daysFormatFrontend(
booking.days
@@ -65,7 +65,7 @@ ${footer}
`
}
function getBookingRejectedText(booking: Booking): string {
return `Hallo liebe/r ${booking.booker.name},
return `Hallo liebe/r ${booking.name},
es tut uns leid aber deine Buchungsanfrage zum ${daysFormatFrontend(
booking.days
@@ -86,7 +86,9 @@ es ging folgende Buchung ein: ${getBaseURL()}/admin/booking/${booking.uuid}
MfG`
}
export async function sendReceivedBookingAdminMail(booking: Booking): Promise<void> {
export async function sendReceivedBookingAdminMail(
booking: Booking
): Promise<void> {
try {
await sendMail({
to: [{ email: ADMIN_EMAIL }],
@@ -102,10 +104,12 @@ export async function sendReceivedBookingAdminMail(booking: Booking): Promise<vo
}
}
export async function sendReceivedBookingBookerMail(booking: Booking): Promise<void> {
export async function sendReceivedBookingBookerMail(
booking: Booking
): Promise<void> {
try {
await sendMail({
to: [{ email: booking.booker.email, name: booking.booker.name }],
to: [{ email: booking.email, name: booking.name }],
from: { email: FROM_EMAIL, name: 'Pfadi-Bussle Wart' },
subject: `Deine Pfadi-Bussle Buchung ist eingegangen!`,
textPlainContent: getReceivedBookingBookerText(booking),
@@ -121,7 +125,7 @@ export async function sendReceivedBookingBookerMail(booking: Booking): Promise<v
export async function sendBookingConfirmed(booking: Booking): Promise<void> {
try {
await sendMail({
to: [{ email: booking.booker.email, name: booking.booker.name }],
to: [{ email: booking.email, name: booking.name }],
from: { email: FROM_EMAIL, name: 'Pfadi-Bussle Wart' },
subject: `Deine Pfadi-Bussle Buchung wurde bestätigt!`,
textPlainContent: getBookingConfirmedText(booking),
@@ -146,7 +150,7 @@ export async function sendBookingConfirmed(booking: Booking): Promise<void> {
export async function sendBookingRejected(booking: Booking): Promise<void> {
try {
await sendMail({
to: [{ email: booking.booker.email, name: booking.booker.name }],
to: [{ email: booking.email, name: booking.name }],
from: { email: FROM_EMAIL, name: 'Pfadi-Bussle Wart' },
subject: `Deine Pfadi-Bussle Buchung wurde abgelehnt!`,
textPlainContent: getBookingRejectedText(booking),

View File

@@ -7,8 +7,7 @@ function getStorage() {
}
export function storeBookingData(booking: Booking) {
const { name, email, street, zip, city } = booking.booker
const { org } = booking
const { name, email, street, zip, city, org } = booking
getStorage().setItem(
BOOKING_DATA_KEY,

View File

@@ -48,7 +48,6 @@ export const getServerSideBooking = async (
return { props: { booking: null } }
}
await booking.populate('booker').execPopulate()
await booking.populate('bill').execPopulate()
// TODO: hack, not sure why _id is not serilizable

View File

@@ -158,7 +158,7 @@ export default function BookingBillPage({
{daysFormatFrontend(booking.days)}
</div>
<div>
<strong>Bucher:</strong> {booking.booker.name}
<strong>Bucher:</strong> {booking.name}
</div>
<div>
<strong>Buchungsstatus:</strong>{' '}

View File

@@ -74,7 +74,7 @@ export default function ShowBookingAdmin({
<strong>Buchungszeitraum:</strong> {daysFormatFrontend(booking.days)}
</div>
<div>
<strong>Bucher:</strong> {booking.booker.name}
<strong>Bucher:</strong> {booking.name}
</div>
<div>
<strong>Buchungsstatus:</strong> {getBookingStatus(booking.status)}

View File

@@ -59,13 +59,13 @@ export default function AdminRecentBookings({ bookings }) {
<div className="bg-white px-2 py-3 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm font-medium text-gray-500">Bucher</dt>
<dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
{booking.booker.name}
{booking.name}
</dd>
</div>
<div className="bg-gray-100 px-2 py-3 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm font-medium text-gray-500">Email</dt>
<dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
{booking.booker.email}
{booking.email}
</dd>
</div>
<div className="bg-white px-2 py-3 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">

View File

@@ -51,7 +51,6 @@ export default withSession(async function userHandler(
booking.set(req.body)
try {
await booking.save()
await booking.populate('booker').execPopulate()
res.status(200).json(booking.toJSON())
} catch (error) {
res.status(400).end(`Failed to save booking: ${error.message}`)

View File

@@ -30,15 +30,11 @@ export default async function userHandler(
return
}
console.log(
`received booking ${booking.uuid} from {booking.booker.email}`
)
console.log(`received booking ${booking.uuid} from {booking.email}`)
await sendReceivedBookingAdminMail(booking)
console.log(`send booking ${booking.uuid} received to admin`)
await sendReceivedBookingBookerMail(booking)
console.log(
`send booking ${booking.uuid} received to {booking.booker.email}`
)
console.log(`send booking ${booking.uuid} received to {booking.email}`)
break
default:
res.setHeader('Allow', ['POST'])