Files
eventsphere/apps/api/src/modules/calendar/calendar.service.ts
2026-04-25 21:57:48 +01:00

93 lines
3.5 KiB
TypeScript

import { BadRequestException, Injectable, NotFoundException } from "@nestjs/common";
import { PrismaService } from "../../prisma/prisma.service";
@Injectable()
export class CalendarService {
constructor(private readonly prisma: PrismaService) {}
routingForms(tenantId: string) {
return this.prisma.calendarRoutingForm.findMany({
where: { tenantId },
orderBy: { createdAt: "desc" },
include: { event: true, _count: { select: { slots: true, bookings: true } } }
});
}
createRoutingForm(tenantId: string, payload: any) {
return this.prisma.calendarRoutingForm.create({
data: {
tenantId,
eventId: payload.eventId || null,
name: String(payload.name ?? ""),
slug: String(payload.slug ?? "").toLowerCase().trim(),
description: payload.description ? String(payload.description) : null,
durationMinutes: Number(payload.durationMinutes ?? 30),
active: payload.active === undefined ? true : Boolean(payload.active)
}
});
}
slots(tenantId: string, routingFormId?: string) {
return this.prisma.calendarSlot.findMany({
where: { tenantId, ...(routingFormId ? { routingFormId } : {}) },
orderBy: { startsAt: "asc" },
include: { routingForm: true }
});
}
async createSlot(tenantId: string, payload: any) {
const routingForm = await this.prisma.calendarRoutingForm.findFirst({ where: { tenantId, id: String(payload.routingFormId ?? "") } });
if (!routingForm) throw new NotFoundException("Routing form not found");
const startsAt = new Date(String(payload.startsAt ?? ""));
const endsAt = new Date(String(payload.endsAt ?? ""));
if (!Number.isFinite(startsAt.getTime()) || !Number.isFinite(endsAt.getTime()) || endsAt <= startsAt) {
throw new BadRequestException("Invalid slot time");
}
return this.prisma.calendarSlot.create({
data: {
tenantId,
routingFormId: routingForm.id,
startsAt,
endsAt,
capacity: Number(payload.capacity ?? 1),
active: payload.active === undefined ? true : Boolean(payload.active)
},
include: { routingForm: true }
});
}
bookings(tenantId: string) {
return this.prisma.booking.findMany({
where: { tenantId },
orderBy: { startsAt: "desc" },
include: { routingForm: true, event: true, attendee: true }
});
}
async createBooking(tenantId: string, payload: any) {
const routingForm = await this.prisma.calendarRoutingForm.findFirst({ where: { tenantId, id: String(payload.routingFormId ?? "") } });
if (!routingForm) throw new NotFoundException("Routing form not found");
const startsAt = new Date(String(payload.startsAt ?? ""));
const endsAt = new Date(String(payload.endsAt ?? ""));
if (!Number.isFinite(startsAt.getTime()) || !Number.isFinite(endsAt.getTime()) || endsAt <= startsAt) {
throw new BadRequestException("Invalid booking time");
}
return this.prisma.booking.create({
data: {
tenantId,
routingFormId: routingForm.id,
eventId: payload.eventId || routingForm.eventId || null,
attendeeId: payload.attendeeId || null,
fullName: String(payload.fullName ?? ""),
email: String(payload.email ?? "").toLowerCase().trim(),
phone: payload.phone ? String(payload.phone) : null,
startsAt,
endsAt,
status: payload.status ? String(payload.status) : "booked",
notes: payload.notes ? String(payload.notes) : null
},
include: { routingForm: true, event: true, attendee: true }
});
}
}