first commit
This commit is contained in:
173
calcom/apps/web/pages/api/cron/changeTimeZone.ts
Normal file
173
calcom/apps/web/pages/api/cron/changeTimeZone.ts
Normal file
@@ -0,0 +1,173 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
import dayjs from "@calcom/dayjs";
|
||||
import prisma from "@calcom/prisma";
|
||||
import { getDefaultScheduleId } from "@calcom/trpc/server/routers/viewer/availability/util";
|
||||
|
||||
const travelScheduleSelect = {
|
||||
id: true,
|
||||
startDate: true,
|
||||
endDate: true,
|
||||
timeZone: true,
|
||||
prevTimeZone: true,
|
||||
user: {
|
||||
select: {
|
||||
id: true,
|
||||
timeZone: true,
|
||||
defaultScheduleId: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
const apiKey = req.headers.authorization || req.query.apiKey;
|
||||
if (process.env.CRON_API_KEY !== apiKey) {
|
||||
res.status(401).json({ message: "Not authenticated" });
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.method !== "POST") {
|
||||
res.status(405).json({ message: "Invalid method" });
|
||||
return;
|
||||
}
|
||||
|
||||
let timeZonesChanged = 0;
|
||||
|
||||
const setNewTimeZone = async (timeZone: string, user: { id: number; defaultScheduleId: number | null }) => {
|
||||
await prisma.user.update({
|
||||
where: {
|
||||
id: user.id,
|
||||
},
|
||||
data: {
|
||||
timeZone: timeZone,
|
||||
},
|
||||
});
|
||||
|
||||
const defaultScheduleId = await getDefaultScheduleId(user.id, prisma);
|
||||
|
||||
if (!user.defaultScheduleId) {
|
||||
// set default schedule if not already set
|
||||
await prisma.user.update({
|
||||
where: {
|
||||
id: user.id,
|
||||
},
|
||||
data: {
|
||||
defaultScheduleId,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
await prisma.schedule.updateMany({
|
||||
where: {
|
||||
id: defaultScheduleId,
|
||||
},
|
||||
data: {
|
||||
timeZone: timeZone,
|
||||
},
|
||||
});
|
||||
timeZonesChanged++;
|
||||
};
|
||||
|
||||
/* travelSchedules should be deleted automatically when timezone is set back to original tz,
|
||||
but we do this in case there cron job didn't run for some reason
|
||||
*/
|
||||
const schedulesToDelete = await prisma.travelSchedule.findMany({
|
||||
where: {
|
||||
OR: [
|
||||
{
|
||||
startDate: {
|
||||
lt: dayjs.utc().subtract(2, "day").toDate(),
|
||||
},
|
||||
endDate: null,
|
||||
},
|
||||
{
|
||||
endDate: {
|
||||
lt: dayjs.utc().subtract(2, "day").toDate(),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
select: travelScheduleSelect,
|
||||
});
|
||||
|
||||
for (const travelSchedule of schedulesToDelete) {
|
||||
if (travelSchedule.prevTimeZone) {
|
||||
await setNewTimeZone(travelSchedule.prevTimeZone, travelSchedule.user);
|
||||
}
|
||||
await prisma.travelSchedule.delete({
|
||||
where: {
|
||||
id: travelSchedule.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const travelSchedulesCloseToCurrentDate = await prisma.travelSchedule.findMany({
|
||||
where: {
|
||||
OR: [
|
||||
{
|
||||
startDate: {
|
||||
gte: dayjs.utc().subtract(1, "day").toDate(),
|
||||
lte: dayjs.utc().add(1, "day").toDate(),
|
||||
},
|
||||
},
|
||||
{
|
||||
endDate: {
|
||||
gte: dayjs.utc().subtract(1, "day").toDate(),
|
||||
lte: dayjs.utc().add(1, "day").toDate(),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
select: travelScheduleSelect,
|
||||
});
|
||||
|
||||
const travelScheduleIdsToDelete = [];
|
||||
|
||||
for (const travelSchedule of travelSchedulesCloseToCurrentDate) {
|
||||
const userTz = travelSchedule.user.timeZone;
|
||||
const offset = dayjs().tz(userTz).utcOffset();
|
||||
|
||||
// midnight of user's time zone in utc time
|
||||
const startDateUTC = dayjs(travelSchedule.startDate).subtract(offset, "minute");
|
||||
// 23:59 of user's time zone in utc time
|
||||
const endDateUTC = dayjs(travelSchedule.endDate).subtract(offset, "minute");
|
||||
if (
|
||||
!dayjs.utc().isBefore(startDateUTC) &&
|
||||
dayjs.utc().isBefore(endDateUTC) &&
|
||||
!travelSchedule.prevTimeZone
|
||||
) {
|
||||
// if travel schedule has started and prevTimeZone is not yet set, we need to change time zone
|
||||
await setNewTimeZone(travelSchedule.timeZone, travelSchedule.user);
|
||||
|
||||
if (!travelSchedule.endDate) {
|
||||
travelScheduleIdsToDelete.push(travelSchedule.id);
|
||||
} else {
|
||||
await prisma.travelSchedule.update({
|
||||
where: {
|
||||
id: travelSchedule.id,
|
||||
},
|
||||
data: {
|
||||
prevTimeZone: travelSchedule.user.timeZone,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
if (!dayjs.utc().isBefore(endDateUTC)) {
|
||||
if (travelSchedule.prevTimeZone) {
|
||||
// travel schedule ended, change back to original timezone
|
||||
await setNewTimeZone(travelSchedule.prevTimeZone, travelSchedule.user);
|
||||
}
|
||||
travelScheduleIdsToDelete.push(travelSchedule.id);
|
||||
}
|
||||
}
|
||||
|
||||
await prisma.travelSchedule.deleteMany({
|
||||
where: {
|
||||
id: {
|
||||
in: travelScheduleIdsToDelete,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
res.status(200).json({ timeZonesChanged });
|
||||
}
|
||||
Reference in New Issue
Block a user