180 lines
4.6 KiB
TypeScript
180 lines
4.6 KiB
TypeScript
|
import type { Dayjs } from "@calcom/dayjs";
|
||
|
import dayjs from "@calcom/dayjs";
|
||
|
import { prisma } from "@calcom/prisma";
|
||
|
import type { Prisma } from "@calcom/prisma/client";
|
||
|
|
||
|
interface ITimeRange {
|
||
|
start: Dayjs;
|
||
|
end: Dayjs;
|
||
|
}
|
||
|
|
||
|
type TimeViewType = "week" | "month" | "year" | "day";
|
||
|
|
||
|
class EventsInsights {
|
||
|
static getBookingsInTimeRange = async (timeRange: ITimeRange, where: Prisma.BookingWhereInput) => {
|
||
|
const { start, end } = timeRange;
|
||
|
|
||
|
const events = await prisma.booking.count({
|
||
|
where: {
|
||
|
...where,
|
||
|
createdAt: {
|
||
|
gte: start.toISOString(),
|
||
|
lte: end.toISOString(),
|
||
|
},
|
||
|
},
|
||
|
});
|
||
|
|
||
|
return events;
|
||
|
};
|
||
|
|
||
|
static getCreatedEventsInTimeRange = async (timeRange: ITimeRange, where: Prisma.BookingWhereInput) => {
|
||
|
const result = await this.getBookingsInTimeRange(timeRange, where);
|
||
|
|
||
|
return result;
|
||
|
};
|
||
|
|
||
|
static getCancelledEventsInTimeRange = async (timeRange: ITimeRange, where: Prisma.BookingWhereInput) => {
|
||
|
const result = await this.getBookingsInTimeRange(timeRange, {
|
||
|
...where,
|
||
|
status: "CANCELLED",
|
||
|
});
|
||
|
|
||
|
return result;
|
||
|
};
|
||
|
|
||
|
static getCompletedEventsInTimeRange = async (timeRange: ITimeRange, where: Prisma.BookingWhereInput) => {
|
||
|
const result = await this.getBookingsInTimeRange(timeRange, {
|
||
|
...where,
|
||
|
status: "ACCEPTED",
|
||
|
endTime: {
|
||
|
lte: dayjs().toISOString(),
|
||
|
},
|
||
|
});
|
||
|
|
||
|
return result;
|
||
|
};
|
||
|
|
||
|
static getRescheduledEventsInTimeRange = async (timeRange: ITimeRange, where: Prisma.BookingWhereInput) => {
|
||
|
const result = await this.getBookingsInTimeRange(timeRange, {
|
||
|
...where,
|
||
|
rescheduled: true,
|
||
|
});
|
||
|
|
||
|
return result;
|
||
|
};
|
||
|
|
||
|
static getBaseBookingForEventStatus = async (where: Prisma.BookingWhereInput) => {
|
||
|
const baseBookings = await prisma.booking.findMany({
|
||
|
where,
|
||
|
select: {
|
||
|
id: true,
|
||
|
eventType: true,
|
||
|
},
|
||
|
});
|
||
|
|
||
|
return baseBookings;
|
||
|
};
|
||
|
|
||
|
static getTotalRescheduledEvents = async (bookingIds: number[]) => {
|
||
|
return await prisma.booking.count({
|
||
|
where: {
|
||
|
id: {
|
||
|
in: bookingIds,
|
||
|
},
|
||
|
rescheduled: true,
|
||
|
},
|
||
|
});
|
||
|
};
|
||
|
|
||
|
static getTotalCancelledEvents = async (bookingIds: number[]) => {
|
||
|
return await prisma.booking.count({
|
||
|
where: {
|
||
|
id: {
|
||
|
in: bookingIds,
|
||
|
},
|
||
|
status: "CANCELLED",
|
||
|
},
|
||
|
});
|
||
|
};
|
||
|
|
||
|
static getTimeLine = async (timeView: TimeViewType, startDate: Dayjs, endDate: Dayjs) => {
|
||
|
let resultTimeLine: string[] = [];
|
||
|
|
||
|
if (timeView) {
|
||
|
switch (timeView) {
|
||
|
case "week":
|
||
|
resultTimeLine = this.getWeekTimeline(startDate, endDate);
|
||
|
break;
|
||
|
case "month":
|
||
|
resultTimeLine = this.getMonthTimeline(startDate, endDate);
|
||
|
break;
|
||
|
case "year":
|
||
|
resultTimeLine = this.getYearTimeline(startDate, endDate);
|
||
|
break;
|
||
|
default:
|
||
|
resultTimeLine = this.getWeekTimeline(startDate, endDate);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return resultTimeLine;
|
||
|
};
|
||
|
|
||
|
static getTimeView = (timeView: TimeViewType, startDate: Dayjs, endDate: Dayjs) => {
|
||
|
let resultTimeView = timeView;
|
||
|
|
||
|
if (startDate.diff(endDate, "day") > 90) {
|
||
|
resultTimeView = "month";
|
||
|
} else if (startDate.diff(endDate, "day") > 365) {
|
||
|
resultTimeView = "year";
|
||
|
}
|
||
|
|
||
|
return resultTimeView;
|
||
|
};
|
||
|
|
||
|
static getWeekTimeline(startDate: Dayjs, endDate: Dayjs) {
|
||
|
let pivotDate = dayjs(startDate);
|
||
|
const dates = [];
|
||
|
while (pivotDate.isBefore(endDate)) {
|
||
|
pivotDate = pivotDate.add(7, "day");
|
||
|
dates.push(pivotDate.format("YYYY-MM-DD"));
|
||
|
}
|
||
|
return dates;
|
||
|
}
|
||
|
|
||
|
static getMonthTimeline(startDate: Dayjs, endDate: Dayjs) {
|
||
|
let pivotDate = dayjs(startDate);
|
||
|
const dates = [];
|
||
|
while (pivotDate.isBefore(endDate)) {
|
||
|
pivotDate = pivotDate.set("month", pivotDate.get("month") + 1);
|
||
|
|
||
|
dates.push(pivotDate.format("YYYY-MM-DD"));
|
||
|
}
|
||
|
return dates;
|
||
|
}
|
||
|
|
||
|
static getYearTimeline(startDate: Dayjs, endDate: Dayjs) {
|
||
|
const pivotDate = dayjs(startDate);
|
||
|
const dates = [];
|
||
|
while (pivotDate.isBefore(endDate)) {
|
||
|
pivotDate.set("year", pivotDate.get("year") + 1);
|
||
|
dates.push(pivotDate.format("YYYY-MM-DD"));
|
||
|
}
|
||
|
return dates;
|
||
|
}
|
||
|
|
||
|
static getPercentage = (actualMetric: number, previousMetric: number) => {
|
||
|
const differenceActualVsPrevious = actualMetric - previousMetric;
|
||
|
if (differenceActualVsPrevious === 0) {
|
||
|
return 0;
|
||
|
}
|
||
|
const result = (differenceActualVsPrevious * 100) / previousMetric;
|
||
|
if (isNaN(result) || !isFinite(result)) {
|
||
|
return 0;
|
||
|
}
|
||
|
return result;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
export { EventsInsights };
|