Replace hardcoded event details and ticket types with dynamic DB records Add booking-config API endpoint to serve active event settings
66 lines
2.3 KiB
TypeScript
66 lines
2.3 KiB
TypeScript
import type { BookingMode, CreateBookingResponse, TicketType } from '~~/shared/booking'
|
|
|
|
import { getSeatCount } from '~~/shared/booking'
|
|
|
|
import { buildAppUrl } from '../../utils/app-url'
|
|
import {
|
|
createBooking,
|
|
getActiveBookingModeOptionByCode,
|
|
getActiveTicketCatalogItemByCode
|
|
} from '../../utils/booking-repository'
|
|
import { buildBookingMessage, parseCreateBookingInput } from '../../utils/bookings'
|
|
import { assertBadRequest } from '../../utils/http'
|
|
import { getPublicContactById } from '../../utils/user-repository'
|
|
import { buildWhatsAppDeepLink } from '../../utils/whatsapp'
|
|
|
|
export default defineEventHandler(async (event): Promise<CreateBookingResponse> => {
|
|
const body = await readBody<{
|
|
customerName?: string
|
|
customerPhone?: string
|
|
bookingMode?: BookingMode | string | null
|
|
quantity?: number
|
|
ticketType?: TicketType
|
|
personInChargeId?: string
|
|
}>(event)
|
|
|
|
const input = parseCreateBookingInput(body)
|
|
const [personInCharge, bookingMode, ticket] = await Promise.all([
|
|
getPublicContactById(input.personInChargeId),
|
|
getActiveBookingModeOptionByCode(input.bookingMode),
|
|
getActiveTicketCatalogItemByCode(input.ticketType)
|
|
])
|
|
|
|
assertBadRequest(personInCharge, 'Selected person in charge is not available')
|
|
assertBadRequest(bookingMode, 'Booking mode is invalid')
|
|
assertBadRequest(ticket, 'Ticket category is invalid')
|
|
assertBadRequest(bookingMode.eventId === ticket.eventId, 'Booking mode and ticket category must belong to the same event')
|
|
|
|
const seatCount = getSeatCount(bookingMode, input.quantity)
|
|
const totalPrice = seatCount * ticket.price
|
|
|
|
const { booking, confirmationToken } = await createBooking({
|
|
eventId: bookingMode.eventId,
|
|
customerName: input.customerName,
|
|
customerPhone: input.customerPhone,
|
|
bookingModeId: bookingMode.id,
|
|
bookingMode: bookingMode.value,
|
|
quantity: input.quantity,
|
|
seatCount,
|
|
ticketTypeId: ticket.id,
|
|
ticketType: ticket.value,
|
|
unitPrice: ticket.price,
|
|
totalPrice,
|
|
personInChargeId: personInCharge.id
|
|
})
|
|
|
|
const confirmationUrl = buildAppUrl(event, `/confirmation/${confirmationToken}`)
|
|
const whatsappMessage = buildBookingMessage(booking, confirmationUrl)
|
|
const whatsappUrl = buildWhatsAppDeepLink(booking.personInChargePhoneNumber, whatsappMessage)
|
|
|
|
return {
|
|
booking,
|
|
confirmationUrl,
|
|
whatsappUrl
|
|
}
|
|
})
|