feat(public-booking): enhance booking confirmation with price and address details

This commit is contained in:
Jose Selesan
2026-06-02 16:55:47 -03:00
parent 9045a8c017
commit 07496e6673
4 changed files with 162 additions and 54 deletions

View File

@@ -13,6 +13,16 @@ type Slot = {
endTime: string;
};
type PriceableCourt = {
basePrice: unknown;
priceRules: Array<{
dayOfWeek: DayOfWeek | null;
startTime: string | null;
endTime: string | null;
price: unknown;
}>;
};
type ComplexWithPublicBookingData = Awaited<ReturnType<typeof getComplexWithBookingData>>;
const DAY_OF_WEEK_BY_INDEX: DayOfWeek[] = [
@@ -230,11 +240,7 @@ async function getComplexWithBookingData(complexSlug: string) {
return complex;
}
function resolveSlotPrice(
court: ComplexWithPublicBookingData['courts'][number],
dayOfWeek: DayOfWeek,
slot: Slot
): number {
function resolveSlotPrice(court: PriceableCourt, dayOfWeek: DayOfWeek, slot: Slot): number {
const slotStart = toMinutes(slot.startTime);
const slotEnd = toMinutes(slot.endTime);
const matchingRules = court.priceRules
@@ -251,9 +257,9 @@ function resolveSlotPrice(
})
.sort((first, second) => {
const firstSpecificity =
(first.dayOfWeek ? 1 : 0) + (first.startTime && first.endTime ? 1 : 0);
(first.dayOfWeek ? 2 : 0) + (first.startTime && first.endTime ? 1 : 0);
const secondSpecificity =
(second.dayOfWeek ? 1 : 0) + (second.startTime && second.endTime ? 1 : 0);
(second.dayOfWeek ? 2 : 0) + (second.startTime && second.endTime ? 1 : 0);
return secondSpecificity - firstSpecificity;
});
@@ -324,6 +330,11 @@ export async function getPublicBookingConfirmation(complexSlug: string, bookingC
court: {
select: {
name: true,
basePrice: true,
priceRules: {
where: { isActive: true },
orderBy: [{ dayOfWeek: 'asc' }, { startTime: 'asc' }],
},
sport: {
select: {
id: true,
@@ -334,6 +345,7 @@ export async function getPublicBookingConfirmation(complexSlug: string, bookingC
complex: {
select: {
complexName: true,
physicalAddress: true,
complexSlug: true,
},
},
@@ -346,13 +358,22 @@ export async function getPublicBookingConfirmation(complexSlug: string, bookingC
throw new PublicBookingServiceError('Reserva no encontrada.', 404);
}
const date = formatIsoDate(booking.bookingDate);
const { dayOfWeek } = parseIsoDate(date);
const price = resolveSlotPrice(booking.court, dayOfWeek, {
startTime: booking.startTime,
endTime: booking.endTime,
});
return {
bookingCode: booking.bookingCode,
complexName: booking.court.complex.complexName,
complexAddress: booking.court.complex.physicalAddress ?? undefined,
complexSlug: booking.court.complex.complexSlug,
date: formatIsoDate(booking.bookingDate),
date,
startTime: booking.startTime,
endTime: booking.endTime,
price,
courtName: booking.court.name,
sport: {
id: booking.court.sport.id,