feat(public-booking): add pricing logic to booking slots and update schemas

This commit is contained in:
Jose Selesan
2026-06-02 16:37:11 -03:00
parent 3e314a9b9a
commit 9045a8c017
3 changed files with 62 additions and 1 deletions

View File

@@ -202,6 +202,10 @@ async function getComplexWithBookingData(complexSlug: string) {
availabilities: {
orderBy: [{ dayOfWeek: 'asc' }, { startTime: 'asc' }],
},
priceRules: {
where: { isActive: true },
orderBy: [{ dayOfWeek: 'asc' }, { startTime: 'asc' }],
},
},
orderBy: { createdAt: 'asc' },
},
@@ -226,6 +230,37 @@ async function getComplexWithBookingData(complexSlug: string) {
return complex;
}
function resolveSlotPrice(
court: ComplexWithPublicBookingData['courts'][number],
dayOfWeek: DayOfWeek,
slot: Slot
): number {
const slotStart = toMinutes(slot.startTime);
const slotEnd = toMinutes(slot.endTime);
const matchingRules = court.priceRules
.filter((rule) => {
if (rule.dayOfWeek && rule.dayOfWeek !== dayOfWeek) {
return false;
}
if (!rule.startTime || !rule.endTime) {
return true;
}
return slotStart >= toMinutes(rule.startTime) && slotEnd <= toMinutes(rule.endTime);
})
.sort((first, second) => {
const firstSpecificity =
(first.dayOfWeek ? 1 : 0) + (first.startTime && first.endTime ? 1 : 0);
const secondSpecificity =
(second.dayOfWeek ? 1 : 0) + (second.startTime && second.endTime ? 1 : 0);
return secondSpecificity - firstSpecificity;
});
return Number(matchingRules[0]?.price ?? court.basePrice);
}
function mapBookingResponse(input: {
bookingId: string;
bookingCode: string;
@@ -432,7 +467,10 @@ export async function listPublicAvailability(complexSlug: string, query: PublicA
},
slotDurationMinutes: court.slotDurationMinutes,
availabilityDay: dayOfWeek,
availableSlots,
availableSlots: availableSlots.map((slot) => ({
...slot,
price: resolveSlotPrice(court, dayOfWeek, slot),
})),
};
})
.filter((court) => court.availableSlots.length > 0);