cal.pub0.org/packages/features/bookings/lib/handleNewBooking.ts

1281 lines
41 KiB
TypeScript
Raw Normal View History

import {
feat/payment-service-6438-cal-767 (#6677) * WIP paymentService * Changes for payment Service * Fix for stripe payment flow * Remove logs/comments * Refactored refund for stripe app * Move stripe handlePayment to own lib * Move stripe delete payments to paymentService * lint fix * Change handleRefundError as generic function * remove log * remove logs * remove logs * Return stripe default export to lib/server * Fixing types * Fix types * Upgrades typescript * Update yarn lock * Typings * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713) * Adds deployment settings to DB (#6706) * WIP * Adds DeploymentTheme * Add missing migrations * Adds client extensions for deployment * Cleanup * Revert "lint fix" This reverts commit e1a2e4a357e58e6673c47399888ae2e00d1351a6. * Add validation * Revert changes removed in force push * Removing abstract class and just leaving interface implementation * Fix types for handlePayments * Fix payment test appStore import * Fix stripe metadata in event type * Move migration to separate PR * Revert "Move migration to separate PR" This reverts commit 48aa64e0724a522d3cc2fefaaaee5792ee9cd9e6. * Update packages/prisma/migrations/20230125175109_remove_type_from_payment_and_add_app_relationship/migration.sql Co-authored-by: Omar López <zomars@me.com> --------- Co-authored-by: zomars <zomars@me.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-02-08 20:36:22 +00:00
App,
BookingStatus,
Credential,
EventTypeCustomInput,
Prisma,
SchedulingType,
WebhookTriggerEvents,
} from "@prisma/client";
import async from "async";
import { isValidPhoneNumber } from "libphonenumber-js";
import { cloneDeep } from "lodash";
import type { NextApiRequest } from "next";
import short from "short-uuid";
import { v5 as uuidv5 } from "uuid";
import z from "zod";
Google Meet - installable app (#5904) * Abstract app category navigation * Send key schema to frontend Co-authored-by: Omar López <zomars@users.noreply.github.com> * Render keys for apps on admin * Add enabled col for apps * Save app keys to DB * Add checks for admin role * Abstract setup components * Add AdminAppsList to setup wizard * Migrate to v10 tRPC * Default hide keys * Display enabled apps * Merge branch 'main' into admin-apps-ui * Toggle calendars * WIP * Add params and include AppCategoryNavigation * Refactor getEnabledApps * Add warning for disabling apps * Fallback to cal video when a video app is disabled * WIP send disabled email * Send email to all users of event types with payment app * Disable Stripe when app is disabled * Disable apps in event types * Send email to users on disabled apps * Send email based on what app was disabled * WIP type fix * Disable navigation to apps list if already setup * UI import fixes * Waits for session data before redirecting * Updates admin seeded password To comply with admin password requirements * Update yarn.lock * Flex fixes * Adds admin middleware * Clean up * WIP * WIP * NTS * Add dirName to app metadata * Upsert app if not in db * Upsert app if not in db * Add dirName to app metadata * Add keys to app packages w/ keys * Merge with main * Toggle show keys & on enable * Fix empty keys * Fix lark calendar metadata * Fix some type errors * Fix Lark metadata & check for category when upserting * More type fixes * Fix types & add keys to google cal * WIP * WIP * WIP * More type fixes * Fix type errors * Fix type errors * More type fixes * More type fixes * More type fixes * Feedback * Fixes default value * Feedback * Migrate credential invalid col default value "false" * Upsert app on saving keys * Clean up * Validate app keys on frontend * Add nonempty to app keys schemas * Add web3 * Listlocale filter on categories / category * Grab app metadata via category or categories * Show empty screen if no apps are enabled * Fix type checks * Fix type checks * Fix type checks * Fix type checks * Fix type checks * Fix type checks * Replace .nonempty() w/ .min(1) * Fix type error * Address feedback * Draft Google Meet install button * Add install button and warning dialog * WIP * WIP * Display warning when Meet is selected * Display Google Meet warning on email to organizer * Fix email * Fix type errors * Fix type error * Add connected account component * Add warning message * Address comments * Address feedback * Clean up & add MeetLocationType * Use useApp hook * Translate to new API approach * Remove console.log * Refactor * Fix missing backup Cal video link * WIP * Address feedback * Update submodules * Feedback * Submodule sync Co-authored-by: Omar López <zomars@users.noreply.github.com> Co-authored-by: Peer Richelsen <peeroke@gmail.com> Co-authored-by: zomars <zomars@me.com> Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Peer Richelsen <peer@cal.com>
2023-01-10 02:01:57 +00:00
import { metadata as GoogleMeetMetadata } from "@calcom/app-store/googlevideo/_metadata";
import { getLocationValueForDB, LocationObject } from "@calcom/app-store/locations";
Google Meet - installable app (#5904) * Abstract app category navigation * Send key schema to frontend Co-authored-by: Omar López <zomars@users.noreply.github.com> * Render keys for apps on admin * Add enabled col for apps * Save app keys to DB * Add checks for admin role * Abstract setup components * Add AdminAppsList to setup wizard * Migrate to v10 tRPC * Default hide keys * Display enabled apps * Merge branch 'main' into admin-apps-ui * Toggle calendars * WIP * Add params and include AppCategoryNavigation * Refactor getEnabledApps * Add warning for disabling apps * Fallback to cal video when a video app is disabled * WIP send disabled email * Send email to all users of event types with payment app * Disable Stripe when app is disabled * Disable apps in event types * Send email to users on disabled apps * Send email based on what app was disabled * WIP type fix * Disable navigation to apps list if already setup * UI import fixes * Waits for session data before redirecting * Updates admin seeded password To comply with admin password requirements * Update yarn.lock * Flex fixes * Adds admin middleware * Clean up * WIP * WIP * NTS * Add dirName to app metadata * Upsert app if not in db * Upsert app if not in db * Add dirName to app metadata * Add keys to app packages w/ keys * Merge with main * Toggle show keys & on enable * Fix empty keys * Fix lark calendar metadata * Fix some type errors * Fix Lark metadata & check for category when upserting * More type fixes * Fix types & add keys to google cal * WIP * WIP * WIP * More type fixes * Fix type errors * Fix type errors * More type fixes * More type fixes * More type fixes * Feedback * Fixes default value * Feedback * Migrate credential invalid col default value "false" * Upsert app on saving keys * Clean up * Validate app keys on frontend * Add nonempty to app keys schemas * Add web3 * Listlocale filter on categories / category * Grab app metadata via category or categories * Show empty screen if no apps are enabled * Fix type checks * Fix type checks * Fix type checks * Fix type checks * Fix type checks * Fix type checks * Replace .nonempty() w/ .min(1) * Fix type error * Address feedback * Draft Google Meet install button * Add install button and warning dialog * WIP * WIP * Display warning when Meet is selected * Display Google Meet warning on email to organizer * Fix email * Fix type errors * Fix type error * Add connected account component * Add warning message * Address comments * Address feedback * Clean up & add MeetLocationType * Use useApp hook * Translate to new API approach * Remove console.log * Refactor * Fix missing backup Cal video link * WIP * Address feedback * Update submodules * Feedback * Submodule sync Co-authored-by: Omar López <zomars@users.noreply.github.com> Co-authored-by: Peer Richelsen <peeroke@gmail.com> Co-authored-by: zomars <zomars@me.com> Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Peer Richelsen <peer@cal.com>
2023-01-10 02:01:57 +00:00
import { MeetLocationType } from "@calcom/app-store/locations";
import { handleEthSignature } from "@calcom/app-store/rainbow/utils/ethereum";
feat/payment-service-6438-cal-767 (#6677) * WIP paymentService * Changes for payment Service * Fix for stripe payment flow * Remove logs/comments * Refactored refund for stripe app * Move stripe handlePayment to own lib * Move stripe delete payments to paymentService * lint fix * Change handleRefundError as generic function * remove log * remove logs * remove logs * Return stripe default export to lib/server * Fixing types * Fix types * Upgrades typescript * Update yarn lock * Typings * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713) * Adds deployment settings to DB (#6706) * WIP * Adds DeploymentTheme * Add missing migrations * Adds client extensions for deployment * Cleanup * Revert "lint fix" This reverts commit e1a2e4a357e58e6673c47399888ae2e00d1351a6. * Add validation * Revert changes removed in force push * Removing abstract class and just leaving interface implementation * Fix types for handlePayments * Fix payment test appStore import * Fix stripe metadata in event type * Move migration to separate PR * Revert "Move migration to separate PR" This reverts commit 48aa64e0724a522d3cc2fefaaaee5792ee9cd9e6. * Update packages/prisma/migrations/20230125175109_remove_type_from_payment_and_add_app_relationship/migration.sql Co-authored-by: Omar López <zomars@me.com> --------- Co-authored-by: zomars <zomars@me.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-02-08 20:36:22 +00:00
import { EventTypeAppsList, getEventTypeAppData } from "@calcom/app-store/utils";
import { cancelScheduledJobs, scheduleTrigger } from "@calcom/app-store/zapier/lib/nodeScheduler";
import EventManager from "@calcom/core/EventManager";
import { getEventName } from "@calcom/core/event";
import { getUserAvailability } from "@calcom/core/getUserAvailability";
import dayjs, { ConfigType } from "@calcom/dayjs";
import {
sendAttendeeRequestEmail,
sendOrganizerRequestEmail,
sendRescheduledEmails,
sendScheduledEmails,
sendScheduledSeatsEmails,
} from "@calcom/emails";
import { scheduleWorkflowReminders } from "@calcom/features/ee/workflows/lib/reminders/reminderScheduler";
import getWebhooks from "@calcom/features/webhooks/lib/getWebhooks";
import { isPrismaObjOrUndefined, parseRecurringEvent } from "@calcom/lib";
import { getDefaultEvent, getGroupName, getUsernameList } from "@calcom/lib/defaultEvents";
import { getErrorFromUnknown } from "@calcom/lib/errors";
feat/payment-service-6438-cal-767 (#6677) * WIP paymentService * Changes for payment Service * Fix for stripe payment flow * Remove logs/comments * Refactored refund for stripe app * Move stripe handlePayment to own lib * Move stripe delete payments to paymentService * lint fix * Change handleRefundError as generic function * remove log * remove logs * remove logs * Return stripe default export to lib/server * Fixing types * Fix types * Upgrades typescript * Update yarn lock * Typings * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713) * Adds deployment settings to DB (#6706) * WIP * Adds DeploymentTheme * Add missing migrations * Adds client extensions for deployment * Cleanup * Revert "lint fix" This reverts commit e1a2e4a357e58e6673c47399888ae2e00d1351a6. * Add validation * Revert changes removed in force push * Removing abstract class and just leaving interface implementation * Fix types for handlePayments * Fix payment test appStore import * Fix stripe metadata in event type * Move migration to separate PR * Revert "Move migration to separate PR" This reverts commit 48aa64e0724a522d3cc2fefaaaee5792ee9cd9e6. * Update packages/prisma/migrations/20230125175109_remove_type_from_payment_and_add_app_relationship/migration.sql Co-authored-by: Omar López <zomars@me.com> --------- Co-authored-by: zomars <zomars@me.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-02-08 20:36:22 +00:00
import getPaymentAppData from "@calcom/lib/getPaymentAppData";
import { HttpError } from "@calcom/lib/http-error";
import isOutOfBounds, { BookingDateInPastError } from "@calcom/lib/isOutOfBounds";
import logger from "@calcom/lib/logger";
feat/payment-service-6438-cal-767 (#6677) * WIP paymentService * Changes for payment Service * Fix for stripe payment flow * Remove logs/comments * Refactored refund for stripe app * Move stripe handlePayment to own lib * Move stripe delete payments to paymentService * lint fix * Change handleRefundError as generic function * remove log * remove logs * remove logs * Return stripe default export to lib/server * Fixing types * Fix types * Upgrades typescript * Update yarn lock * Typings * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713) * Adds deployment settings to DB (#6706) * WIP * Adds DeploymentTheme * Add missing migrations * Adds client extensions for deployment * Cleanup * Revert "lint fix" This reverts commit e1a2e4a357e58e6673c47399888ae2e00d1351a6. * Add validation * Revert changes removed in force push * Removing abstract class and just leaving interface implementation * Fix types for handlePayments * Fix payment test appStore import * Fix stripe metadata in event type * Move migration to separate PR * Revert "Move migration to separate PR" This reverts commit 48aa64e0724a522d3cc2fefaaaee5792ee9cd9e6. * Update packages/prisma/migrations/20230125175109_remove_type_from_payment_and_add_app_relationship/migration.sql Co-authored-by: Omar López <zomars@me.com> --------- Co-authored-by: zomars <zomars@me.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-02-08 20:36:22 +00:00
import { handlePayment } from "@calcom/lib/payment/handlePayment";
import { checkBookingLimits, getLuckyUser } from "@calcom/lib/server";
import { getTranslation } from "@calcom/lib/server/i18n";
import { updateWebUser as syncServicesUpdateWebUser } from "@calcom/lib/sync/SyncServiceManager";
import prisma, { userSelect } from "@calcom/prisma";
import {
customInputSchema,
EventTypeMetaDataSchema,
extendedBookingCreateBody,
} from "@calcom/prisma/zod-utils";
import type { BufferedBusyTime } from "@calcom/types/BufferedBusyTime";
import type { AdditionalInformation, AppsStatus, CalendarEvent } from "@calcom/types/Calendar";
import type { EventResult, PartialReference } from "@calcom/types/EventManager";
import { WorkingHours } from "@calcom/types/schedule";
import sendPayload, { EventTypeInfo } from "../../webhooks/lib/sendPayload";
const translator = short();
const log = logger.getChildLogger({ prefix: ["[api] book:user"] });
type User = Prisma.UserGetPayload<typeof userSelect>;
type BufferedBusyTimes = BufferedBusyTime[];
feat/payment-service-6438-cal-767 (#6677) * WIP paymentService * Changes for payment Service * Fix for stripe payment flow * Remove logs/comments * Refactored refund for stripe app * Move stripe handlePayment to own lib * Move stripe delete payments to paymentService * lint fix * Change handleRefundError as generic function * remove log * remove logs * remove logs * Return stripe default export to lib/server * Fixing types * Fix types * Upgrades typescript * Update yarn lock * Typings * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713) * Adds deployment settings to DB (#6706) * WIP * Adds DeploymentTheme * Add missing migrations * Adds client extensions for deployment * Cleanup * Revert "lint fix" This reverts commit e1a2e4a357e58e6673c47399888ae2e00d1351a6. * Add validation * Revert changes removed in force push * Removing abstract class and just leaving interface implementation * Fix types for handlePayments * Fix payment test appStore import * Fix stripe metadata in event type * Move migration to separate PR * Revert "Move migration to separate PR" This reverts commit 48aa64e0724a522d3cc2fefaaaee5792ee9cd9e6. * Update packages/prisma/migrations/20230125175109_remove_type_from_payment_and_add_app_relationship/migration.sql Co-authored-by: Omar López <zomars@me.com> --------- Co-authored-by: zomars <zomars@me.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-02-08 20:36:22 +00:00
interface IEventTypePaymentCredentialType {
appId: EventTypeAppsList;
app: {
categories: App["categories"];
dirName: string;
};
key: Prisma.JsonValue;
}
/**
* Refreshes a Credential with fresh data from the database.
*
* @param credential
*/
async function refreshCredential(credential: Credential): Promise<Credential> {
const newCredential = await prisma.credential.findUnique({
where: {
id: credential.id,
},
});
if (!newCredential) {
return credential;
} else {
return newCredential;
}
}
/**
* Refreshes the given set of credentials.
*
* @param credentials
*/
async function refreshCredentials(credentials: Array<Credential>): Promise<Array<Credential>> {
return await async.mapLimit(credentials, 5, refreshCredential);
}
const isWithinAvailableHours = (
timeSlot: { start: ConfigType; end: ConfigType },
{
workingHours,
}: {
workingHours: WorkingHours[];
}
) => {
const timeSlotStart = dayjs(timeSlot.start).utc();
const timeSlotEnd = dayjs(timeSlot.end).utc();
for (const workingHour of workingHours) {
// TODO: Double check & possibly fix timezone conversions.
const startTime = timeSlotStart.startOf("day").add(workingHour.startTime, "minute");
const endTime = timeSlotEnd.startOf("day").add(workingHour.endTime, "minute");
if (
workingHour.days.includes(timeSlotStart.day()) &&
// UTC mode, should be performant.
timeSlotStart.isBetween(startTime, endTime, null, "[)") &&
timeSlotEnd.isBetween(startTime, endTime, null, "(]")
) {
return true;
}
}
return false;
};
// if true, there are conflicts.
function checkForConflicts(busyTimes: BufferedBusyTimes, time: dayjs.ConfigType, length: number) {
// Early return
if (!Array.isArray(busyTimes) || busyTimes.length < 1) {
return false; // guaranteed no conflicts when there is no busy times.
}
for (const busyTime of busyTimes) {
const startTime = dayjs(busyTime.start);
const endTime = dayjs(busyTime.end);
// Check if time is between start and end times
if (dayjs(time).isBetween(startTime, endTime, null, "[)")) {
return true;
}
// Check if slot end time is between start and end time
if (dayjs(time).add(length, "minutes").isBetween(startTime, endTime)) {
return true;
}
// Check if startTime is between slot
if (startTime.isBetween(dayjs(time), dayjs(time).add(length, "minutes"))) {
return true;
}
}
return false;
}
const getEventTypesFromDB = async (eventTypeId: number) => {
const eventType = await prisma.eventType.findUniqueOrThrow({
where: {
id: eventTypeId,
},
select: {
id: true,
customInputs: true,
users: userSelect,
team: {
select: {
id: true,
name: true,
},
},
title: true,
length: true,
eventName: true,
schedulingType: true,
description: true,
periodType: true,
periodStartDate: true,
periodEndDate: true,
periodDays: true,
periodCountCalendarDays: true,
requiresConfirmation: true,
userId: true,
price: true,
currency: true,
metadata: true,
destinationCalendar: true,
hideCalendarNotes: true,
seatsPerTimeSlot: true,
recurringEvent: true,
seatsShowAttendees: true,
bookingLimits: true,
workflows: {
include: {
workflow: {
include: {
steps: true,
},
},
},
},
locations: true,
timeZone: true,
schedule: {
select: {
availability: true,
timeZone: true,
},
},
Feature/fixed hosts (#6423) * Save design updates for fixed round robin support * wip - added Host relation * DRY hostsFixed select * Changes to allow isFixed in the Availability page * Allow booking with fixed hosts * Replace users with hosts if hosts is set * Also prefer hosts over users here * Prevent duplicates when hosts is saved * Accidental slot duplication * Attempt at making isFixed optional * Sydney and Shiraz can live in harmony again * No fixed hosts causes every to be true.. * Make hosts undefinable * Small handleNewBooking fixes * Similar fix to the hosts to check for empty-ness * Default to isFixed false instead of true * Fix event type list avatars * Filter availableTimeSlots, collective ts's wont magically re-enable. * (Further) Fixes to getAggregateWorkingHours * Weird userId artifact that preceeds this branch, investigate later * On user delete, remove host, on event type delete, also remove host * Dynamic event types were incorrectly marked as isFixed=false * Fixed notFound error when there are no users (but hosts) * Fixes userIsOwner * Oops, fixed isFixed users being included correctly * Fixed Button styling on secondary darkmode * Create exclusivity in selectable options * fix: Location dropdown is overflowing #6376 (#6415) * add `menuPlacement` react-select's props to `getReactSelectProps` to avoid dropdown overflow on small screen. By default, set to "auto". * CALCOM-6362 - [CAL-728] App Sidebar. Child items aren't sized/spaced properly (#6424) * [CAL-728] App Sidebar. Child items aren't sized/spaced properly * fix: undo logo size Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com> Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> * Fixing colors (#6429) * Update website * Update console * Update yarn.lock * Uses disable instead of filtering to be more clear * Update EventTeamTab.tsx * Merge conflict cleanup * During test cases the dayjs() utcOffset is local time, this fixes that Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Thomas Brodusch <3238312+thomasbrodusch@users.noreply.github.com> Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com> Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com> Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com>
2023-01-12 21:09:12 +00:00
hosts: {
select: {
isFixed: true,
user: userSelect,
},
},
availability: {
select: {
date: true,
startTime: true,
endTime: true,
days: true,
},
},
},
});
return {
...eventType,
Introduce EventTypeAppCard in app-store and make it super easy to add it through CLI - Also adds Fathom app (#4727) * Add OmniInstall button * Make AppCards configurable by the app itself * Make OmniInstallAppButton not redirect * Fixes * Add extendsFeature support to CLI * Move to automatic file generation approach as dynamic import checking doesnt work correctly * Use zod everywhere consistenly for metadata and fix all TS issues * Fix viewer.eventTypes endpoint. Make prisma base select and _ prefixed models consistent in expecting scalars only * Remove unnecessary zod parsing of event-types as it is making the scope of the PR huge * Fix UI TS errors * wip * Add zod types support in EventTypeAppCard.tsx * Fixes during PR review and other failing tests * Remove unused app * Fix stripe installation flow * More fixes * Fix apps and active apps count * self review * Add loading attribute to OmniInsall button * Handle empty state * Improve types * Fix stripe app installation bug * added fathom app (#4804) * added fathom app wrapper, needs script injection to public booking page * new logo * Add Fathom script support on booking pages and add it as an eventTypeapp * Add automation and analytics apps * Add missing pieces for analytics category * Rename BookingPageScripts to BookingPageTagManager Co-authored-by: Hariom Balhara <hariombalhara@gmail.com> * Fix lint error * Fix runtime error with legayAppData being undefined * Remove duplicate automation key Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2022-10-14 16:24:43 +00:00
metadata: EventTypeMetaDataSchema.parse(eventType.metadata),
recurringEvent: parseRecurringEvent(eventType.recurringEvent),
customInputs: customInputSchema.array().parse(eventType.customInputs),
locations: (eventType.locations ?? []) as LocationObject[],
};
};
Feature/fixed hosts (#6423) * Save design updates for fixed round robin support * wip - added Host relation * DRY hostsFixed select * Changes to allow isFixed in the Availability page * Allow booking with fixed hosts * Replace users with hosts if hosts is set * Also prefer hosts over users here * Prevent duplicates when hosts is saved * Accidental slot duplication * Attempt at making isFixed optional * Sydney and Shiraz can live in harmony again * No fixed hosts causes every to be true.. * Make hosts undefinable * Small handleNewBooking fixes * Similar fix to the hosts to check for empty-ness * Default to isFixed false instead of true * Fix event type list avatars * Filter availableTimeSlots, collective ts's wont magically re-enable. * (Further) Fixes to getAggregateWorkingHours * Weird userId artifact that preceeds this branch, investigate later * On user delete, remove host, on event type delete, also remove host * Dynamic event types were incorrectly marked as isFixed=false * Fixed notFound error when there are no users (but hosts) * Fixes userIsOwner * Oops, fixed isFixed users being included correctly * Fixed Button styling on secondary darkmode * Create exclusivity in selectable options * fix: Location dropdown is overflowing #6376 (#6415) * add `menuPlacement` react-select's props to `getReactSelectProps` to avoid dropdown overflow on small screen. By default, set to "auto". * CALCOM-6362 - [CAL-728] App Sidebar. Child items aren't sized/spaced properly (#6424) * [CAL-728] App Sidebar. Child items aren't sized/spaced properly * fix: undo logo size Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com> Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> * Fixing colors (#6429) * Update website * Update console * Update yarn.lock * Uses disable instead of filtering to be more clear * Update EventTeamTab.tsx * Merge conflict cleanup * During test cases the dayjs() utcOffset is local time, this fixes that Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Thomas Brodusch <3238312+thomasbrodusch@users.noreply.github.com> Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com> Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com> Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com>
2023-01-12 21:09:12 +00:00
type IsFixedAwareUser = User & { isFixed: boolean };
async function ensureAvailableUsers(
eventType: Awaited<ReturnType<typeof getEventTypesFromDB>> & {
Feature/fixed hosts (#6423) * Save design updates for fixed round robin support * wip - added Host relation * DRY hostsFixed select * Changes to allow isFixed in the Availability page * Allow booking with fixed hosts * Replace users with hosts if hosts is set * Also prefer hosts over users here * Prevent duplicates when hosts is saved * Accidental slot duplication * Attempt at making isFixed optional * Sydney and Shiraz can live in harmony again * No fixed hosts causes every to be true.. * Make hosts undefinable * Small handleNewBooking fixes * Similar fix to the hosts to check for empty-ness * Default to isFixed false instead of true * Fix event type list avatars * Filter availableTimeSlots, collective ts's wont magically re-enable. * (Further) Fixes to getAggregateWorkingHours * Weird userId artifact that preceeds this branch, investigate later * On user delete, remove host, on event type delete, also remove host * Dynamic event types were incorrectly marked as isFixed=false * Fixed notFound error when there are no users (but hosts) * Fixes userIsOwner * Oops, fixed isFixed users being included correctly * Fixed Button styling on secondary darkmode * Create exclusivity in selectable options * fix: Location dropdown is overflowing #6376 (#6415) * add `menuPlacement` react-select's props to `getReactSelectProps` to avoid dropdown overflow on small screen. By default, set to "auto". * CALCOM-6362 - [CAL-728] App Sidebar. Child items aren't sized/spaced properly (#6424) * [CAL-728] App Sidebar. Child items aren't sized/spaced properly * fix: undo logo size Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com> Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> * Fixing colors (#6429) * Update website * Update console * Update yarn.lock * Uses disable instead of filtering to be more clear * Update EventTeamTab.tsx * Merge conflict cleanup * During test cases the dayjs() utcOffset is local time, this fixes that Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Thomas Brodusch <3238312+thomasbrodusch@users.noreply.github.com> Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com> Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com> Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com>
2023-01-12 21:09:12 +00:00
users: IsFixedAwareUser[];
},
input: { dateFrom: string; dateTo: string },
recurringDatesInfo?: {
allRecurringDates: string[] | undefined;
currentRecurringIndex: number | undefined;
}
) {
Feature/fixed hosts (#6423) * Save design updates for fixed round robin support * wip - added Host relation * DRY hostsFixed select * Changes to allow isFixed in the Availability page * Allow booking with fixed hosts * Replace users with hosts if hosts is set * Also prefer hosts over users here * Prevent duplicates when hosts is saved * Accidental slot duplication * Attempt at making isFixed optional * Sydney and Shiraz can live in harmony again * No fixed hosts causes every to be true.. * Make hosts undefinable * Small handleNewBooking fixes * Similar fix to the hosts to check for empty-ness * Default to isFixed false instead of true * Fix event type list avatars * Filter availableTimeSlots, collective ts's wont magically re-enable. * (Further) Fixes to getAggregateWorkingHours * Weird userId artifact that preceeds this branch, investigate later * On user delete, remove host, on event type delete, also remove host * Dynamic event types were incorrectly marked as isFixed=false * Fixed notFound error when there are no users (but hosts) * Fixes userIsOwner * Oops, fixed isFixed users being included correctly * Fixed Button styling on secondary darkmode * Create exclusivity in selectable options * fix: Location dropdown is overflowing #6376 (#6415) * add `menuPlacement` react-select's props to `getReactSelectProps` to avoid dropdown overflow on small screen. By default, set to "auto". * CALCOM-6362 - [CAL-728] App Sidebar. Child items aren't sized/spaced properly (#6424) * [CAL-728] App Sidebar. Child items aren't sized/spaced properly * fix: undo logo size Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com> Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> * Fixing colors (#6429) * Update website * Update console * Update yarn.lock * Uses disable instead of filtering to be more clear * Update EventTeamTab.tsx * Merge conflict cleanup * During test cases the dayjs() utcOffset is local time, this fixes that Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Thomas Brodusch <3238312+thomasbrodusch@users.noreply.github.com> Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com> Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com> Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com>
2023-01-12 21:09:12 +00:00
const availableUsers: IsFixedAwareUser[] = [];
/** Let's start checking for availability */
for (const user of eventType.users) {
const { busy: bufferedBusyTimes, workingHours } = await getUserAvailability(
{
userId: user.id,
eventTypeId: eventType.id,
...input,
},
{ user, eventType }
);
// check if time slot is outside of schedule.
if (
!isWithinAvailableHours(
{ start: input.dateFrom, end: input.dateTo },
{
workingHours,
}
)
) {
// user does not have availability at this time, skip user.
continue;
}
console.log("calendarBusyTimes==>>>", bufferedBusyTimes);
2022-11-08 16:12:31 +00:00
let foundConflict = false;
try {
if (
eventType.recurringEvent &&
recurringDatesInfo?.currentRecurringIndex === 0 &&
recurringDatesInfo.allRecurringDates
) {
const allBookingDates = recurringDatesInfo.allRecurringDates.map((strDate) => new Date(strDate));
// Go through each date for the recurring event and check if each one's availability
// DONE: Decreased computational complexity from O(2^n) to O(n) by refactoring this loop to stop
// running at the first unavailable time.
let i = 0;
while (!foundConflict && i < allBookingDates.length) {
foundConflict = checkForConflicts(bufferedBusyTimes, allBookingDates[i++], eventType.length);
}
} else {
foundConflict = checkForConflicts(bufferedBusyTimes, input.dateFrom, eventType.length);
}
} catch {
log.debug({
message: "Unable set isAvailableToBeBooked. Using true. ",
});
}
// no conflicts found, add to available users.
if (!foundConflict) {
availableUsers.push(user);
}
}
if (!availableUsers.length) {
throw new Error("No available users found.");
}
return availableUsers;
}
async function handler(req: NextApiRequest & { userId?: number | undefined }) {
const { userId } = req;
const {
recurringCount,
allRecurringDates,
currentRecurringIndex,
noEmail,
eventTypeSlug,
eventTypeId,
hasHashedBookingLink,
language,
appsStatus: reqAppsStatus,
...reqBody
} = extendedBookingCreateBody.parse(req.body);
// handle dynamic user
const dynamicUserList = Array.isArray(reqBody.user)
? getGroupName(reqBody.user)
: getUsernameList(reqBody.user);
const tAttendees = await getTranslation(language ?? "en", "common");
const tGuests = await getTranslation("en", "common");
log.debug(`Booking eventType ${eventTypeId} started`);
const eventType =
!eventTypeId && !!eventTypeSlug ? getDefaultEvent(eventTypeSlug) : await getEventTypesFromDB(eventTypeId);
if (!eventType) throw new HttpError({ statusCode: 404, message: "eventType.notFound" });
feat/payment-service-6438-cal-767 (#6677) * WIP paymentService * Changes for payment Service * Fix for stripe payment flow * Remove logs/comments * Refactored refund for stripe app * Move stripe handlePayment to own lib * Move stripe delete payments to paymentService * lint fix * Change handleRefundError as generic function * remove log * remove logs * remove logs * Return stripe default export to lib/server * Fixing types * Fix types * Upgrades typescript * Update yarn lock * Typings * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713) * Adds deployment settings to DB (#6706) * WIP * Adds DeploymentTheme * Add missing migrations * Adds client extensions for deployment * Cleanup * Revert "lint fix" This reverts commit e1a2e4a357e58e6673c47399888ae2e00d1351a6. * Add validation * Revert changes removed in force push * Removing abstract class and just leaving interface implementation * Fix types for handlePayments * Fix payment test appStore import * Fix stripe metadata in event type * Move migration to separate PR * Revert "Move migration to separate PR" This reverts commit 48aa64e0724a522d3cc2fefaaaee5792ee9cd9e6. * Update packages/prisma/migrations/20230125175109_remove_type_from_payment_and_add_app_relationship/migration.sql Co-authored-by: Omar López <zomars@me.com> --------- Co-authored-by: zomars <zomars@me.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-02-08 20:36:22 +00:00
const paymentAppData = getPaymentAppData(eventType);
Introduce EventTypeAppCard in app-store and make it super easy to add it through CLI - Also adds Fathom app (#4727) * Add OmniInstall button * Make AppCards configurable by the app itself * Make OmniInstallAppButton not redirect * Fixes * Add extendsFeature support to CLI * Move to automatic file generation approach as dynamic import checking doesnt work correctly * Use zod everywhere consistenly for metadata and fix all TS issues * Fix viewer.eventTypes endpoint. Make prisma base select and _ prefixed models consistent in expecting scalars only * Remove unnecessary zod parsing of event-types as it is making the scope of the PR huge * Fix UI TS errors * wip * Add zod types support in EventTypeAppCard.tsx * Fixes during PR review and other failing tests * Remove unused app * Fix stripe installation flow * More fixes * Fix apps and active apps count * self review * Add loading attribute to OmniInsall button * Handle empty state * Improve types * Fix stripe app installation bug * added fathom app (#4804) * added fathom app wrapper, needs script injection to public booking page * new logo * Add Fathom script support on booking pages and add it as an eventTypeapp * Add automation and analytics apps * Add missing pieces for analytics category * Rename BookingPageScripts to BookingPageTagManager Co-authored-by: Hariom Balhara <hariombalhara@gmail.com> * Fix lint error * Fix runtime error with legayAppData being undefined * Remove duplicate automation key Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2022-10-14 16:24:43 +00:00
// Check if required custom inputs exist
handleCustomInputs(eventType.customInputs as EventTypeCustomInput[], reqBody.customInputs);
let timeOutOfBounds = false;
try {
timeOutOfBounds = isOutOfBounds(reqBody.start, {
periodType: eventType.periodType,
periodDays: eventType.periodDays,
periodEndDate: eventType.periodEndDate,
periodStartDate: eventType.periodStartDate,
periodCountCalendarDays: eventType.periodCountCalendarDays,
});
} catch (error) {
if (error instanceof BookingDateInPastError) {
// TODO: HttpError should not bleed through to the console.
log.info(`Booking eventType ${eventTypeId} failed`, error);
throw new HttpError({ statusCode: 400, message: error.message });
}
log.debug({
message: "Unable set timeOutOfBounds. Using false. ",
});
}
if (timeOutOfBounds) {
const error = {
errorCode: "BookingTimeOutOfBounds",
message: `EventType '${eventType.eventName}' cannot be booked at this time.`,
};
throw new HttpError({ statusCode: 400, message: error.message });
}
Feature/fixed hosts (#6423) * Save design updates for fixed round robin support * wip - added Host relation * DRY hostsFixed select * Changes to allow isFixed in the Availability page * Allow booking with fixed hosts * Replace users with hosts if hosts is set * Also prefer hosts over users here * Prevent duplicates when hosts is saved * Accidental slot duplication * Attempt at making isFixed optional * Sydney and Shiraz can live in harmony again * No fixed hosts causes every to be true.. * Make hosts undefinable * Small handleNewBooking fixes * Similar fix to the hosts to check for empty-ness * Default to isFixed false instead of true * Fix event type list avatars * Filter availableTimeSlots, collective ts's wont magically re-enable. * (Further) Fixes to getAggregateWorkingHours * Weird userId artifact that preceeds this branch, investigate later * On user delete, remove host, on event type delete, also remove host * Dynamic event types were incorrectly marked as isFixed=false * Fixed notFound error when there are no users (but hosts) * Fixes userIsOwner * Oops, fixed isFixed users being included correctly * Fixed Button styling on secondary darkmode * Create exclusivity in selectable options * fix: Location dropdown is overflowing #6376 (#6415) * add `menuPlacement` react-select's props to `getReactSelectProps` to avoid dropdown overflow on small screen. By default, set to "auto". * CALCOM-6362 - [CAL-728] App Sidebar. Child items aren't sized/spaced properly (#6424) * [CAL-728] App Sidebar. Child items aren't sized/spaced properly * fix: undo logo size Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com> Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> * Fixing colors (#6429) * Update website * Update console * Update yarn.lock * Uses disable instead of filtering to be more clear * Update EventTeamTab.tsx * Merge conflict cleanup * During test cases the dayjs() utcOffset is local time, this fixes that Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Thomas Brodusch <3238312+thomasbrodusch@users.noreply.github.com> Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com> Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com> Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com>
2023-01-12 21:09:12 +00:00
const loadUsers = async () =>
!eventTypeId
? await prisma.user.findMany({
where: {
username: {
in: dynamicUserList,
},
},
Feature/fixed hosts (#6423) * Save design updates for fixed round robin support * wip - added Host relation * DRY hostsFixed select * Changes to allow isFixed in the Availability page * Allow booking with fixed hosts * Replace users with hosts if hosts is set * Also prefer hosts over users here * Prevent duplicates when hosts is saved * Accidental slot duplication * Attempt at making isFixed optional * Sydney and Shiraz can live in harmony again * No fixed hosts causes every to be true.. * Make hosts undefinable * Small handleNewBooking fixes * Similar fix to the hosts to check for empty-ness * Default to isFixed false instead of true * Fix event type list avatars * Filter availableTimeSlots, collective ts's wont magically re-enable. * (Further) Fixes to getAggregateWorkingHours * Weird userId artifact that preceeds this branch, investigate later * On user delete, remove host, on event type delete, also remove host * Dynamic event types were incorrectly marked as isFixed=false * Fixed notFound error when there are no users (but hosts) * Fixes userIsOwner * Oops, fixed isFixed users being included correctly * Fixed Button styling on secondary darkmode * Create exclusivity in selectable options * fix: Location dropdown is overflowing #6376 (#6415) * add `menuPlacement` react-select's props to `getReactSelectProps` to avoid dropdown overflow on small screen. By default, set to "auto". * CALCOM-6362 - [CAL-728] App Sidebar. Child items aren't sized/spaced properly (#6424) * [CAL-728] App Sidebar. Child items aren't sized/spaced properly * fix: undo logo size Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com> Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> * Fixing colors (#6429) * Update website * Update console * Update yarn.lock * Uses disable instead of filtering to be more clear * Update EventTeamTab.tsx * Merge conflict cleanup * During test cases the dayjs() utcOffset is local time, this fixes that Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Thomas Brodusch <3238312+thomasbrodusch@users.noreply.github.com> Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com> Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com> Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com>
2023-01-12 21:09:12 +00:00
...userSelect,
})
: !!eventType.hosts?.length
? eventType.hosts.map(({ user, isFixed }) => ({
...user,
isFixed,
}))
: eventType.users;
// loadUsers allows type inferring
let users: (Awaited<ReturnType<typeof loadUsers>>[number] & { isFixed?: boolean })[] = await loadUsers();
const isDynamicAllowed = !users.some((user) => !user.allowDynamicBooking);
if (!isDynamicAllowed && !eventTypeId) {
throw new HttpError({
message: "Some of the users in this group do not allow dynamic booking",
statusCode: 400,
});
}
// If this event was pre-relationship migration
// TODO: Establish whether this is dead code.
if (!users.length && eventType.userId) {
const eventTypeUser = await prisma.user.findUnique({
where: {
id: eventType.userId,
},
...userSelect,
});
if (!eventTypeUser) throw new HttpError({ statusCode: 404, message: "eventTypeUser.notFound" });
users.push(eventTypeUser);
}
if (!users) throw new HttpError({ statusCode: 404, message: "eventTypeUser.notFound" });
Feature/fixed hosts (#6423) * Save design updates for fixed round robin support * wip - added Host relation * DRY hostsFixed select * Changes to allow isFixed in the Availability page * Allow booking with fixed hosts * Replace users with hosts if hosts is set * Also prefer hosts over users here * Prevent duplicates when hosts is saved * Accidental slot duplication * Attempt at making isFixed optional * Sydney and Shiraz can live in harmony again * No fixed hosts causes every to be true.. * Make hosts undefinable * Small handleNewBooking fixes * Similar fix to the hosts to check for empty-ness * Default to isFixed false instead of true * Fix event type list avatars * Filter availableTimeSlots, collective ts's wont magically re-enable. * (Further) Fixes to getAggregateWorkingHours * Weird userId artifact that preceeds this branch, investigate later * On user delete, remove host, on event type delete, also remove host * Dynamic event types were incorrectly marked as isFixed=false * Fixed notFound error when there are no users (but hosts) * Fixes userIsOwner * Oops, fixed isFixed users being included correctly * Fixed Button styling on secondary darkmode * Create exclusivity in selectable options * fix: Location dropdown is overflowing #6376 (#6415) * add `menuPlacement` react-select's props to `getReactSelectProps` to avoid dropdown overflow on small screen. By default, set to "auto". * CALCOM-6362 - [CAL-728] App Sidebar. Child items aren't sized/spaced properly (#6424) * [CAL-728] App Sidebar. Child items aren't sized/spaced properly * fix: undo logo size Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com> Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> * Fixing colors (#6429) * Update website * Update console * Update yarn.lock * Uses disable instead of filtering to be more clear * Update EventTeamTab.tsx * Merge conflict cleanup * During test cases the dayjs() utcOffset is local time, this fixes that Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Thomas Brodusch <3238312+thomasbrodusch@users.noreply.github.com> Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com> Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com> Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com>
2023-01-12 21:09:12 +00:00
users = users.map((user) => ({
...user,
isFixed:
user.isFixed === false
? false
: user.isFixed || eventType.schedulingType !== SchedulingType.ROUND_ROBIN,
}));
if (eventType && eventType.hasOwnProperty("bookingLimits") && eventType?.bookingLimits) {
const startAsDate = dayjs(reqBody.start).toDate();
await checkBookingLimits(eventType.bookingLimits, startAsDate, eventType.id);
}
if (!eventType.seatsPerTimeSlot) {
const availableUsers = await ensureAvailableUsers(
{
...eventType,
Feature/fixed hosts (#6423) * Save design updates for fixed round robin support * wip - added Host relation * DRY hostsFixed select * Changes to allow isFixed in the Availability page * Allow booking with fixed hosts * Replace users with hosts if hosts is set * Also prefer hosts over users here * Prevent duplicates when hosts is saved * Accidental slot duplication * Attempt at making isFixed optional * Sydney and Shiraz can live in harmony again * No fixed hosts causes every to be true.. * Make hosts undefinable * Small handleNewBooking fixes * Similar fix to the hosts to check for empty-ness * Default to isFixed false instead of true * Fix event type list avatars * Filter availableTimeSlots, collective ts's wont magically re-enable. * (Further) Fixes to getAggregateWorkingHours * Weird userId artifact that preceeds this branch, investigate later * On user delete, remove host, on event type delete, also remove host * Dynamic event types were incorrectly marked as isFixed=false * Fixed notFound error when there are no users (but hosts) * Fixes userIsOwner * Oops, fixed isFixed users being included correctly * Fixed Button styling on secondary darkmode * Create exclusivity in selectable options * fix: Location dropdown is overflowing #6376 (#6415) * add `menuPlacement` react-select's props to `getReactSelectProps` to avoid dropdown overflow on small screen. By default, set to "auto". * CALCOM-6362 - [CAL-728] App Sidebar. Child items aren't sized/spaced properly (#6424) * [CAL-728] App Sidebar. Child items aren't sized/spaced properly * fix: undo logo size Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com> Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> * Fixing colors (#6429) * Update website * Update console * Update yarn.lock * Uses disable instead of filtering to be more clear * Update EventTeamTab.tsx * Merge conflict cleanup * During test cases the dayjs() utcOffset is local time, this fixes that Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Thomas Brodusch <3238312+thomasbrodusch@users.noreply.github.com> Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com> Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com> Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com>
2023-01-12 21:09:12 +00:00
users: users as IsFixedAwareUser[],
...(eventType.recurringEvent && {
recurringEvent: {
...eventType.recurringEvent,
count: recurringCount || eventType.recurringEvent.count,
},
}),
},
{
dateFrom: reqBody.start,
dateTo: reqBody.end,
},
{
allRecurringDates,
currentRecurringIndex,
}
);
Feature/fixed hosts (#6423) * Save design updates for fixed round robin support * wip - added Host relation * DRY hostsFixed select * Changes to allow isFixed in the Availability page * Allow booking with fixed hosts * Replace users with hosts if hosts is set * Also prefer hosts over users here * Prevent duplicates when hosts is saved * Accidental slot duplication * Attempt at making isFixed optional * Sydney and Shiraz can live in harmony again * No fixed hosts causes every to be true.. * Make hosts undefinable * Small handleNewBooking fixes * Similar fix to the hosts to check for empty-ness * Default to isFixed false instead of true * Fix event type list avatars * Filter availableTimeSlots, collective ts's wont magically re-enable. * (Further) Fixes to getAggregateWorkingHours * Weird userId artifact that preceeds this branch, investigate later * On user delete, remove host, on event type delete, also remove host * Dynamic event types were incorrectly marked as isFixed=false * Fixed notFound error when there are no users (but hosts) * Fixes userIsOwner * Oops, fixed isFixed users being included correctly * Fixed Button styling on secondary darkmode * Create exclusivity in selectable options * fix: Location dropdown is overflowing #6376 (#6415) * add `menuPlacement` react-select's props to `getReactSelectProps` to avoid dropdown overflow on small screen. By default, set to "auto". * CALCOM-6362 - [CAL-728] App Sidebar. Child items aren't sized/spaced properly (#6424) * [CAL-728] App Sidebar. Child items aren't sized/spaced properly * fix: undo logo size Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com> Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> * Fixing colors (#6429) * Update website * Update console * Update yarn.lock * Uses disable instead of filtering to be more clear * Update EventTeamTab.tsx * Merge conflict cleanup * During test cases the dayjs() utcOffset is local time, this fixes that Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Thomas Brodusch <3238312+thomasbrodusch@users.noreply.github.com> Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com> Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com> Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com>
2023-01-12 21:09:12 +00:00
const luckyUsers: typeof users = [];
const luckyUserPool = availableUsers.filter((user) => !user.isFixed);
// loop through all non-fixed hosts and get the lucky users
while (luckyUserPool.length > 0 && luckyUsers.length < 1 /* TODO: Add variable */) {
const newLuckyUser = await getLuckyUser("MAXIMIZE_AVAILABILITY", {
// find a lucky user that is not already in the luckyUsers array
availableUsers: luckyUserPool.filter(
(user) => !luckyUsers.find((existing) => existing.id === user.id)
),
eventTypeId: eventType.id,
});
if (!newLuckyUser) {
break; // prevent infinite loop
}
Feature/fixed hosts (#6423) * Save design updates for fixed round robin support * wip - added Host relation * DRY hostsFixed select * Changes to allow isFixed in the Availability page * Allow booking with fixed hosts * Replace users with hosts if hosts is set * Also prefer hosts over users here * Prevent duplicates when hosts is saved * Accidental slot duplication * Attempt at making isFixed optional * Sydney and Shiraz can live in harmony again * No fixed hosts causes every to be true.. * Make hosts undefinable * Small handleNewBooking fixes * Similar fix to the hosts to check for empty-ness * Default to isFixed false instead of true * Fix event type list avatars * Filter availableTimeSlots, collective ts's wont magically re-enable. * (Further) Fixes to getAggregateWorkingHours * Weird userId artifact that preceeds this branch, investigate later * On user delete, remove host, on event type delete, also remove host * Dynamic event types were incorrectly marked as isFixed=false * Fixed notFound error when there are no users (but hosts) * Fixes userIsOwner * Oops, fixed isFixed users being included correctly * Fixed Button styling on secondary darkmode * Create exclusivity in selectable options * fix: Location dropdown is overflowing #6376 (#6415) * add `menuPlacement` react-select's props to `getReactSelectProps` to avoid dropdown overflow on small screen. By default, set to "auto". * CALCOM-6362 - [CAL-728] App Sidebar. Child items aren't sized/spaced properly (#6424) * [CAL-728] App Sidebar. Child items aren't sized/spaced properly * fix: undo logo size Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com> Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> * Fixing colors (#6429) * Update website * Update console * Update yarn.lock * Uses disable instead of filtering to be more clear * Update EventTeamTab.tsx * Merge conflict cleanup * During test cases the dayjs() utcOffset is local time, this fixes that Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Thomas Brodusch <3238312+thomasbrodusch@users.noreply.github.com> Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com> Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com> Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com>
2023-01-12 21:09:12 +00:00
luckyUsers.push(newLuckyUser);
}
// ALL fixed users must be available
if (
availableUsers.filter((user) => user.isFixed).length !== users.filter((user) => user.isFixed).length
) {
throw new Error("Some users are unavailable for booking.");
}
Feature/fixed hosts (#6423) * Save design updates for fixed round robin support * wip - added Host relation * DRY hostsFixed select * Changes to allow isFixed in the Availability page * Allow booking with fixed hosts * Replace users with hosts if hosts is set * Also prefer hosts over users here * Prevent duplicates when hosts is saved * Accidental slot duplication * Attempt at making isFixed optional * Sydney and Shiraz can live in harmony again * No fixed hosts causes every to be true.. * Make hosts undefinable * Small handleNewBooking fixes * Similar fix to the hosts to check for empty-ness * Default to isFixed false instead of true * Fix event type list avatars * Filter availableTimeSlots, collective ts's wont magically re-enable. * (Further) Fixes to getAggregateWorkingHours * Weird userId artifact that preceeds this branch, investigate later * On user delete, remove host, on event type delete, also remove host * Dynamic event types were incorrectly marked as isFixed=false * Fixed notFound error when there are no users (but hosts) * Fixes userIsOwner * Oops, fixed isFixed users being included correctly * Fixed Button styling on secondary darkmode * Create exclusivity in selectable options * fix: Location dropdown is overflowing #6376 (#6415) * add `menuPlacement` react-select's props to `getReactSelectProps` to avoid dropdown overflow on small screen. By default, set to "auto". * CALCOM-6362 - [CAL-728] App Sidebar. Child items aren't sized/spaced properly (#6424) * [CAL-728] App Sidebar. Child items aren't sized/spaced properly * fix: undo logo size Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com> Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> * Fixing colors (#6429) * Update website * Update console * Update yarn.lock * Uses disable instead of filtering to be more clear * Update EventTeamTab.tsx * Merge conflict cleanup * During test cases the dayjs() utcOffset is local time, this fixes that Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Thomas Brodusch <3238312+thomasbrodusch@users.noreply.github.com> Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com> Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com> Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com>
2023-01-12 21:09:12 +00:00
users = [...luckyUsers, ...availableUsers.filter((user) => user.isFixed)];
}
Feature/fixed hosts (#6423) * Save design updates for fixed round robin support * wip - added Host relation * DRY hostsFixed select * Changes to allow isFixed in the Availability page * Allow booking with fixed hosts * Replace users with hosts if hosts is set * Also prefer hosts over users here * Prevent duplicates when hosts is saved * Accidental slot duplication * Attempt at making isFixed optional * Sydney and Shiraz can live in harmony again * No fixed hosts causes every to be true.. * Make hosts undefinable * Small handleNewBooking fixes * Similar fix to the hosts to check for empty-ness * Default to isFixed false instead of true * Fix event type list avatars * Filter availableTimeSlots, collective ts's wont magically re-enable. * (Further) Fixes to getAggregateWorkingHours * Weird userId artifact that preceeds this branch, investigate later * On user delete, remove host, on event type delete, also remove host * Dynamic event types were incorrectly marked as isFixed=false * Fixed notFound error when there are no users (but hosts) * Fixes userIsOwner * Oops, fixed isFixed users being included correctly * Fixed Button styling on secondary darkmode * Create exclusivity in selectable options * fix: Location dropdown is overflowing #6376 (#6415) * add `menuPlacement` react-select's props to `getReactSelectProps` to avoid dropdown overflow on small screen. By default, set to "auto". * CALCOM-6362 - [CAL-728] App Sidebar. Child items aren't sized/spaced properly (#6424) * [CAL-728] App Sidebar. Child items aren't sized/spaced properly * fix: undo logo size Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com> Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> * Fixing colors (#6429) * Update website * Update console * Update yarn.lock * Uses disable instead of filtering to be more clear * Update EventTeamTab.tsx * Merge conflict cleanup * During test cases the dayjs() utcOffset is local time, this fixes that Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Thomas Brodusch <3238312+thomasbrodusch@users.noreply.github.com> Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com> Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com> Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com>
2023-01-12 21:09:12 +00:00
Introduce EventTypeAppCard in app-store and make it super easy to add it through CLI - Also adds Fathom app (#4727) * Add OmniInstall button * Make AppCards configurable by the app itself * Make OmniInstallAppButton not redirect * Fixes * Add extendsFeature support to CLI * Move to automatic file generation approach as dynamic import checking doesnt work correctly * Use zod everywhere consistenly for metadata and fix all TS issues * Fix viewer.eventTypes endpoint. Make prisma base select and _ prefixed models consistent in expecting scalars only * Remove unnecessary zod parsing of event-types as it is making the scope of the PR huge * Fix UI TS errors * wip * Add zod types support in EventTypeAppCard.tsx * Fixes during PR review and other failing tests * Remove unused app * Fix stripe installation flow * More fixes * Fix apps and active apps count * self review * Add loading attribute to OmniInsall button * Handle empty state * Improve types * Fix stripe app installation bug * added fathom app (#4804) * added fathom app wrapper, needs script injection to public booking page * new logo * Add Fathom script support on booking pages and add it as an eventTypeapp * Add automation and analytics apps * Add missing pieces for analytics category * Rename BookingPageScripts to BookingPageTagManager Co-authored-by: Hariom Balhara <hariombalhara@gmail.com> * Fix lint error * Fix runtime error with legayAppData being undefined * Remove duplicate automation key Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2022-10-14 16:24:43 +00:00
const rainbowAppData = getEventTypeAppData(eventType, "rainbow") || {};
// @TODO: use the returned address somewhere in booking creation?
// const address: string | undefined = await ...
Introduce EventTypeAppCard in app-store and make it super easy to add it through CLI - Also adds Fathom app (#4727) * Add OmniInstall button * Make AppCards configurable by the app itself * Make OmniInstallAppButton not redirect * Fixes * Add extendsFeature support to CLI * Move to automatic file generation approach as dynamic import checking doesnt work correctly * Use zod everywhere consistenly for metadata and fix all TS issues * Fix viewer.eventTypes endpoint. Make prisma base select and _ prefixed models consistent in expecting scalars only * Remove unnecessary zod parsing of event-types as it is making the scope of the PR huge * Fix UI TS errors * wip * Add zod types support in EventTypeAppCard.tsx * Fixes during PR review and other failing tests * Remove unused app * Fix stripe installation flow * More fixes * Fix apps and active apps count * self review * Add loading attribute to OmniInsall button * Handle empty state * Improve types * Fix stripe app installation bug * added fathom app (#4804) * added fathom app wrapper, needs script injection to public booking page * new logo * Add Fathom script support on booking pages and add it as an eventTypeapp * Add automation and analytics apps * Add missing pieces for analytics category * Rename BookingPageScripts to BookingPageTagManager Co-authored-by: Hariom Balhara <hariombalhara@gmail.com> * Fix lint error * Fix runtime error with legayAppData being undefined * Remove duplicate automation key Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2022-10-14 16:24:43 +00:00
await handleEthSignature(rainbowAppData, reqBody.ethSignature);
const [organizerUser] = users;
const tOrganizer = await getTranslation(organizerUser.locale ?? "en", "common");
const invitee = [
{
email: reqBody.email,
name: reqBody.name,
timeZone: reqBody.timeZone,
language: { translate: tAttendees, locale: language ?? "en" },
},
];
const guests = (reqBody.guests || []).map((guest) => ({
email: guest,
name: "",
timeZone: reqBody.timeZone,
language: { translate: tGuests, locale: "en" },
}));
const seed = `${organizerUser.username}:${dayjs(reqBody.start).utc().format()}:${new Date().getTime()}`;
const uid = translator.fromUUID(uuidv5(seed, uuidv5.URL));
const bookingLocation = getLocationValueForDB(reqBody.location, eventType.locations);
Feature/fixed hosts (#6423) * Save design updates for fixed round robin support * wip - added Host relation * DRY hostsFixed select * Changes to allow isFixed in the Availability page * Allow booking with fixed hosts * Replace users with hosts if hosts is set * Also prefer hosts over users here * Prevent duplicates when hosts is saved * Accidental slot duplication * Attempt at making isFixed optional * Sydney and Shiraz can live in harmony again * No fixed hosts causes every to be true.. * Make hosts undefinable * Small handleNewBooking fixes * Similar fix to the hosts to check for empty-ness * Default to isFixed false instead of true * Fix event type list avatars * Filter availableTimeSlots, collective ts's wont magically re-enable. * (Further) Fixes to getAggregateWorkingHours * Weird userId artifact that preceeds this branch, investigate later * On user delete, remove host, on event type delete, also remove host * Dynamic event types were incorrectly marked as isFixed=false * Fixed notFound error when there are no users (but hosts) * Fixes userIsOwner * Oops, fixed isFixed users being included correctly * Fixed Button styling on secondary darkmode * Create exclusivity in selectable options * fix: Location dropdown is overflowing #6376 (#6415) * add `menuPlacement` react-select's props to `getReactSelectProps` to avoid dropdown overflow on small screen. By default, set to "auto". * CALCOM-6362 - [CAL-728] App Sidebar. Child items aren't sized/spaced properly (#6424) * [CAL-728] App Sidebar. Child items aren't sized/spaced properly * fix: undo logo size Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com> Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> * Fixing colors (#6429) * Update website * Update console * Update yarn.lock * Uses disable instead of filtering to be more clear * Update EventTeamTab.tsx * Merge conflict cleanup * During test cases the dayjs() utcOffset is local time, this fixes that Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Thomas Brodusch <3238312+thomasbrodusch@users.noreply.github.com> Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com> Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com> Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com>
2023-01-12 21:09:12 +00:00
const customInputs = {} as NonNullable<CalendarEvent["customInputs"]>;
const teamMemberPromises =
Feature/fixed hosts (#6423) * Save design updates for fixed round robin support * wip - added Host relation * DRY hostsFixed select * Changes to allow isFixed in the Availability page * Allow booking with fixed hosts * Replace users with hosts if hosts is set * Also prefer hosts over users here * Prevent duplicates when hosts is saved * Accidental slot duplication * Attempt at making isFixed optional * Sydney and Shiraz can live in harmony again * No fixed hosts causes every to be true.. * Make hosts undefinable * Small handleNewBooking fixes * Similar fix to the hosts to check for empty-ness * Default to isFixed false instead of true * Fix event type list avatars * Filter availableTimeSlots, collective ts's wont magically re-enable. * (Further) Fixes to getAggregateWorkingHours * Weird userId artifact that preceeds this branch, investigate later * On user delete, remove host, on event type delete, also remove host * Dynamic event types were incorrectly marked as isFixed=false * Fixed notFound error when there are no users (but hosts) * Fixes userIsOwner * Oops, fixed isFixed users being included correctly * Fixed Button styling on secondary darkmode * Create exclusivity in selectable options * fix: Location dropdown is overflowing #6376 (#6415) * add `menuPlacement` react-select's props to `getReactSelectProps` to avoid dropdown overflow on small screen. By default, set to "auto". * CALCOM-6362 - [CAL-728] App Sidebar. Child items aren't sized/spaced properly (#6424) * [CAL-728] App Sidebar. Child items aren't sized/spaced properly * fix: undo logo size Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com> Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> * Fixing colors (#6429) * Update website * Update console * Update yarn.lock * Uses disable instead of filtering to be more clear * Update EventTeamTab.tsx * Merge conflict cleanup * During test cases the dayjs() utcOffset is local time, this fixes that Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Thomas Brodusch <3238312+thomasbrodusch@users.noreply.github.com> Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com> Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com> Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in> Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com>
2023-01-12 21:09:12 +00:00
users.length > 1
? users.slice(1).map(async function (user) {
return {
email: user.email || "",
name: user.name || "",
timeZone: user.timeZone,
language: {
translate: await getTranslation(user.locale ?? "en", "common"),
locale: user.locale ?? "en",
},
};
})
: [];
const teamMembers = await Promise.all(teamMemberPromises);
const attendeesList = [...invitee, ...guests, ...teamMembers];
const eventNameObject = {
attendeeName: reqBody.name || "Nameless",
eventType: eventType.title,
eventName: eventType.eventName,
host: organizerUser.name || "Nameless",
location: bookingLocation,
t: tOrganizer,
};
const additionalNotes = reqBody.notes;
let requiresConfirmation = eventType?.requiresConfirmation;
const rcThreshold = eventType?.metadata?.requiresConfirmationThreshold;
if (rcThreshold) {
if (dayjs(dayjs(reqBody.start).utc().format()).diff(dayjs(), rcThreshold.unit) > rcThreshold.time) {
requiresConfirmation = false;
}
}
let evt: CalendarEvent = {
type: eventType.title,
title: getEventName(eventNameObject), //this needs to be either forced in english, or fetched for each attendee and organizer separately
description: eventType.description,
additionalNotes,
customInputs,
startTime: dayjs(reqBody.start).utc().format(),
endTime: dayjs(reqBody.end).utc().format(),
organizer: {
id: organizerUser.id,
name: organizerUser.name || "Nameless",
email: organizerUser.email || "Email-less",
timeZone: organizerUser.timeZone,
language: { translate: tOrganizer, locale: organizerUser.locale ?? "en" },
},
attendees: attendeesList,
location: bookingLocation, // Will be processed by the EventManager later.
/** For team events & dynamic collective events, we will need to handle each member destinationCalendar eventually */
destinationCalendar: eventType.destinationCalendar || organizerUser.destinationCalendar,
hideCalendarNotes: eventType.hideCalendarNotes,
requiresConfirmation: requiresConfirmation ?? false,
eventTypeId: eventType.id,
seatsShowAttendees: !!eventType.seatsShowAttendees,
seatsPerTimeSlot: eventType.seatsPerTimeSlot,
};
// For seats, if the booking already exists then we want to add the new attendee to the existing booking
if (reqBody.bookingUid) {
if (!eventType.seatsPerTimeSlot) {
throw new HttpError({ statusCode: 404, message: "Event type does not have seats" });
}
const booking = await prisma.booking.findUnique({
where: {
uid: reqBody.bookingUid,
},
select: {
uid: true,
id: true,
attendees: true,
userId: true,
references: true,
startTime: true,
user: true,
},
});
if (!booking) {
throw new HttpError({ statusCode: 404, message: "Booking not found" });
}
// Need to add translation for attendees to pass type checks. Since these values are never written to the db we can just use the new attendee language
const bookingAttendees = booking.attendees.map((attendee) => {
return { ...attendee, language: { translate: tAttendees, locale: language ?? "en" } };
});
evt = { ...evt, attendees: [...bookingAttendees, invitee[0]] };
if (eventType.seatsPerTimeSlot <= booking.attendees.length) {
throw new HttpError({ statusCode: 409, message: "Booking seats are full" });
}
if (booking.attendees.find((attendee) => attendee.email === invitee[0].email)) {
throw new HttpError({ statusCode: 409, message: "Already signed up for time slot" });
}
const videoCallReference = booking.references.find((reference) => reference.type.includes("_video"));
if (videoCallReference) {
evt.videoCallData = {
type: videoCallReference.type,
id: videoCallReference.meetingId,
password: videoCallReference?.meetingPassword,
url: videoCallReference.meetingUrl,
};
}
await prisma.booking.update({
where: {
uid: reqBody.bookingUid,
},
data: {
attendees: {
create: {
email: invitee[0].email,
name: invitee[0].name,
timeZone: invitee[0].timeZone,
locale: invitee[0].language.locale,
},
},
},
});
const newSeat = booking.attendees.length !== 0;
/**
* Remember objects are passed into functions as references
* so if you modify it in a inner function it will be modified in the outer function
* deep cloning evt to avoid this
*/
const copyEvent = cloneDeep(evt);
await sendScheduledSeatsEmails(copyEvent, invitee[0], newSeat, !!eventType.seatsShowAttendees);
const credentials = await refreshCredentials(organizerUser.credentials);
const eventManager = new EventManager({ ...organizerUser, credentials });
await eventManager.updateCalendarAttendees(evt, booking);
feat/payment-service-6438-cal-767 (#6677) * WIP paymentService * Changes for payment Service * Fix for stripe payment flow * Remove logs/comments * Refactored refund for stripe app * Move stripe handlePayment to own lib * Move stripe delete payments to paymentService * lint fix * Change handleRefundError as generic function * remove log * remove logs * remove logs * Return stripe default export to lib/server * Fixing types * Fix types * Upgrades typescript * Update yarn lock * Typings * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713) * Adds deployment settings to DB (#6706) * WIP * Adds DeploymentTheme * Add missing migrations * Adds client extensions for deployment * Cleanup * Revert "lint fix" This reverts commit e1a2e4a357e58e6673c47399888ae2e00d1351a6. * Add validation * Revert changes removed in force push * Removing abstract class and just leaving interface implementation * Fix types for handlePayments * Fix payment test appStore import * Fix stripe metadata in event type * Move migration to separate PR * Revert "Move migration to separate PR" This reverts commit 48aa64e0724a522d3cc2fefaaaee5792ee9cd9e6. * Update packages/prisma/migrations/20230125175109_remove_type_from_payment_and_add_app_relationship/migration.sql Co-authored-by: Omar López <zomars@me.com> --------- Co-authored-by: zomars <zomars@me.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-02-08 20:36:22 +00:00
if (!Number.isNaN(paymentAppData.price) && paymentAppData.price > 0 && !!booking) {
const credentialPaymentAppCategories = await prisma.credential.findMany({
where: {
userId: organizerUser.id,
app: {
categories: {
hasSome: ["payment"],
},
},
},
select: {
key: true,
appId: true,
app: {
select: {
categories: true,
dirName: true,
},
},
},
});
const eventTypePaymentAppCredential = credentialPaymentAppCategories.find((credential) => {
return credential.appId === paymentAppData.appId;
});
feat/payment-service-6438-cal-767 (#6677) * WIP paymentService * Changes for payment Service * Fix for stripe payment flow * Remove logs/comments * Refactored refund for stripe app * Move stripe handlePayment to own lib * Move stripe delete payments to paymentService * lint fix * Change handleRefundError as generic function * remove log * remove logs * remove logs * Return stripe default export to lib/server * Fixing types * Fix types * Upgrades typescript * Update yarn lock * Typings * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713) * Adds deployment settings to DB (#6706) * WIP * Adds DeploymentTheme * Add missing migrations * Adds client extensions for deployment * Cleanup * Revert "lint fix" This reverts commit e1a2e4a357e58e6673c47399888ae2e00d1351a6. * Add validation * Revert changes removed in force push * Removing abstract class and just leaving interface implementation * Fix types for handlePayments * Fix payment test appStore import * Fix stripe metadata in event type * Move migration to separate PR * Revert "Move migration to separate PR" This reverts commit 48aa64e0724a522d3cc2fefaaaee5792ee9cd9e6. * Update packages/prisma/migrations/20230125175109_remove_type_from_payment_and_add_app_relationship/migration.sql Co-authored-by: Omar López <zomars@me.com> --------- Co-authored-by: zomars <zomars@me.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-02-08 20:36:22 +00:00
if (!eventTypePaymentAppCredential) {
throw new HttpError({ statusCode: 400, message: "Missing payment credentials" });
feat/payment-service-6438-cal-767 (#6677) * WIP paymentService * Changes for payment Service * Fix for stripe payment flow * Remove logs/comments * Refactored refund for stripe app * Move stripe handlePayment to own lib * Move stripe delete payments to paymentService * lint fix * Change handleRefundError as generic function * remove log * remove logs * remove logs * Return stripe default export to lib/server * Fixing types * Fix types * Upgrades typescript * Update yarn lock * Typings * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713) * Adds deployment settings to DB (#6706) * WIP * Adds DeploymentTheme * Add missing migrations * Adds client extensions for deployment * Cleanup * Revert "lint fix" This reverts commit e1a2e4a357e58e6673c47399888ae2e00d1351a6. * Add validation * Revert changes removed in force push * Removing abstract class and just leaving interface implementation * Fix types for handlePayments * Fix payment test appStore import * Fix stripe metadata in event type * Move migration to separate PR * Revert "Move migration to separate PR" This reverts commit 48aa64e0724a522d3cc2fefaaaee5792ee9cd9e6. * Update packages/prisma/migrations/20230125175109_remove_type_from_payment_and_add_app_relationship/migration.sql Co-authored-by: Omar López <zomars@me.com> --------- Co-authored-by: zomars <zomars@me.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-02-08 20:36:22 +00:00
}
if (!eventTypePaymentAppCredential?.appId) {
throw new HttpError({ statusCode: 400, message: "Missing payment app id" });
}
feat/payment-service-6438-cal-767 (#6677) * WIP paymentService * Changes for payment Service * Fix for stripe payment flow * Remove logs/comments * Refactored refund for stripe app * Move stripe handlePayment to own lib * Move stripe delete payments to paymentService * lint fix * Change handleRefundError as generic function * remove log * remove logs * remove logs * Return stripe default export to lib/server * Fixing types * Fix types * Upgrades typescript * Update yarn lock * Typings * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713) * Adds deployment settings to DB (#6706) * WIP * Adds DeploymentTheme * Add missing migrations * Adds client extensions for deployment * Cleanup * Revert "lint fix" This reverts commit e1a2e4a357e58e6673c47399888ae2e00d1351a6. * Add validation * Revert changes removed in force push * Removing abstract class and just leaving interface implementation * Fix types for handlePayments * Fix payment test appStore import * Fix stripe metadata in event type * Move migration to separate PR * Revert "Move migration to separate PR" This reverts commit 48aa64e0724a522d3cc2fefaaaee5792ee9cd9e6. * Update packages/prisma/migrations/20230125175109_remove_type_from_payment_and_add_app_relationship/migration.sql Co-authored-by: Omar López <zomars@me.com> --------- Co-authored-by: zomars <zomars@me.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-02-08 20:36:22 +00:00
const payment = await handlePayment(
evt,
eventType,
eventTypePaymentAppCredential as IEventTypePaymentCredentialType,
booking
);
req.statusCode = 201;
feat/payment-service-6438-cal-767 (#6677) * WIP paymentService * Changes for payment Service * Fix for stripe payment flow * Remove logs/comments * Refactored refund for stripe app * Move stripe handlePayment to own lib * Move stripe delete payments to paymentService * lint fix * Change handleRefundError as generic function * remove log * remove logs * remove logs * Return stripe default export to lib/server * Fixing types * Fix types * Upgrades typescript * Update yarn lock * Typings * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713) * Adds deployment settings to DB (#6706) * WIP * Adds DeploymentTheme * Add missing migrations * Adds client extensions for deployment * Cleanup * Revert "lint fix" This reverts commit e1a2e4a357e58e6673c47399888ae2e00d1351a6. * Add validation * Revert changes removed in force push * Removing abstract class and just leaving interface implementation * Fix types for handlePayments * Fix payment test appStore import * Fix stripe metadata in event type * Move migration to separate PR * Revert "Move migration to separate PR" This reverts commit 48aa64e0724a522d3cc2fefaaaee5792ee9cd9e6. * Update packages/prisma/migrations/20230125175109_remove_type_from_payment_and_add_app_relationship/migration.sql Co-authored-by: Omar López <zomars@me.com> --------- Co-authored-by: zomars <zomars@me.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-02-08 20:36:22 +00:00
return { ...booking, message: "Payment required", paymentUid: payment?.uid };
}
req.statusCode = 201;
return booking;
}
if (reqBody.customInputs.length > 0) {
reqBody.customInputs.forEach(({ label, value }) => {
customInputs[label] = value;
});
}
if (eventType.schedulingType === SchedulingType.COLLECTIVE) {
evt.team = {
members: users.map((user) => user.name || user.username || "Nameless"),
name: eventType.team?.name || "Nameless",
}; // used for invitee emails
}
if (reqBody.recurringEventId && eventType.recurringEvent) {
// Overriding the recurring event configuration count to be the actual number of events booked for
// the recurring event (equal or less than recurring event configuration count)
eventType.recurringEvent = Object.assign({}, eventType.recurringEvent, { count: recurringCount });
evt.recurringEvent = eventType.recurringEvent;
}
// Initialize EventManager with credentials
const rescheduleUid = reqBody.rescheduleUid;
async function getOriginalRescheduledBooking(uid: string) {
return prisma.booking.findFirst({
where: {
uid,
status: {
in: [BookingStatus.ACCEPTED, BookingStatus.CANCELLED, BookingStatus.PENDING],
},
},
include: {
attendees: {
select: {
name: true,
email: true,
locale: true,
timeZone: true,
},
},
user: {
select: {
id: true,
name: true,
email: true,
locale: true,
timeZone: true,
},
},
payment: true,
},
});
}
type BookingType = Prisma.PromiseReturnType<typeof getOriginalRescheduledBooking>;
let originalRescheduledBooking: BookingType = null;
if (rescheduleUid) {
originalRescheduledBooking = await getOriginalRescheduledBooking(rescheduleUid);
}
// If the user is not the owner of the event, new booking should be always pending.
// Otherwise, an owner rescheduling should be always accepted.
// Before comparing make sure that userId is set, otherwise undefined === undefined
const userReschedulingIsOwner = userId && originalRescheduledBooking?.user?.id === userId;
feat/payment-service-6438-cal-767 (#6677) * WIP paymentService * Changes for payment Service * Fix for stripe payment flow * Remove logs/comments * Refactored refund for stripe app * Move stripe handlePayment to own lib * Move stripe delete payments to paymentService * lint fix * Change handleRefundError as generic function * remove log * remove logs * remove logs * Return stripe default export to lib/server * Fixing types * Fix types * Upgrades typescript * Update yarn lock * Typings * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713) * Adds deployment settings to DB (#6706) * WIP * Adds DeploymentTheme * Add missing migrations * Adds client extensions for deployment * Cleanup * Revert "lint fix" This reverts commit e1a2e4a357e58e6673c47399888ae2e00d1351a6. * Add validation * Revert changes removed in force push * Removing abstract class and just leaving interface implementation * Fix types for handlePayments * Fix payment test appStore import * Fix stripe metadata in event type * Move migration to separate PR * Revert "Move migration to separate PR" This reverts commit 48aa64e0724a522d3cc2fefaaaee5792ee9cd9e6. * Update packages/prisma/migrations/20230125175109_remove_type_from_payment_and_add_app_relationship/migration.sql Co-authored-by: Omar López <zomars@me.com> --------- Co-authored-by: zomars <zomars@me.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-02-08 20:36:22 +00:00
const isConfirmedByDefault = (!requiresConfirmation && !paymentAppData.price) || userReschedulingIsOwner;
async function createBooking() {
if (originalRescheduledBooking) {
evt.title = originalRescheduledBooking?.title || evt.title;
evt.description = originalRescheduledBooking?.description || evt.additionalNotes;
evt.location = originalRescheduledBooking?.location;
}
const eventTypeRel = !eventTypeId
? {}
: {
connect: {
id: eventTypeId,
},
};
const dynamicEventSlugRef = !eventTypeId ? eventTypeSlug : null;
const dynamicGroupSlugRef = !eventTypeId ? (reqBody.user as string).toLowerCase() : null;
const newBookingData: Prisma.BookingCreateInput = {
uid,
title: evt.title,
startTime: dayjs.utc(evt.startTime).toDate(),
endTime: dayjs.utc(evt.endTime).toDate(),
description: evt.additionalNotes,
customInputs: isPrismaObjOrUndefined(evt.customInputs),
status: isConfirmedByDefault ? BookingStatus.ACCEPTED : BookingStatus.PENDING,
location: evt.location,
eventType: eventTypeRel,
smsReminderNumber: reqBody.smsReminderNumber,
metadata: reqBody.metadata,
attendees: {
createMany: {
data: evt.attendees.map((attendee) => {
//if attendee is team member, it should fetch their locale not booker's locale
//perhaps make email fetch request to see if his locale is stored, else
const retObj = {
name: attendee.name,
email: attendee.email,
timeZone: attendee.timeZone,
locale: attendee.language.locale,
};
return retObj;
}),
},
},
dynamicEventSlugRef,
dynamicGroupSlugRef,
user: {
connect: {
id: organizerUser.id,
},
},
destinationCalendar: evt.destinationCalendar
? {
connect: { id: evt.destinationCalendar.id },
}
: undefined,
};
if (reqBody.recurringEventId) {
newBookingData.recurringEventId = reqBody.recurringEventId;
}
if (originalRescheduledBooking) {
newBookingData["paid"] = originalRescheduledBooking.paid;
newBookingData["fromReschedule"] = originalRescheduledBooking.uid;
if (newBookingData.attendees?.createMany?.data) {
newBookingData.attendees.createMany.data = originalRescheduledBooking.attendees;
}
if (originalRescheduledBooking.recurringEventId) {
newBookingData.recurringEventId = originalRescheduledBooking.recurringEventId;
}
}
const createBookingObj = {
include: {
user: {
select: { email: true, name: true, timeZone: true },
},
attendees: true,
payment: true,
},
data: newBookingData,
};
if (originalRescheduledBooking?.paid && originalRescheduledBooking?.payment) {
const bookingPayment = originalRescheduledBooking?.payment?.find((payment) => payment.success);
if (bookingPayment) {
createBookingObj.data.payment = {
connect: { id: bookingPayment.id },
};
}
}
feat/payment-service-6438-cal-767 (#6677) * WIP paymentService * Changes for payment Service * Fix for stripe payment flow * Remove logs/comments * Refactored refund for stripe app * Move stripe handlePayment to own lib * Move stripe delete payments to paymentService * lint fix * Change handleRefundError as generic function * remove log * remove logs * remove logs * Return stripe default export to lib/server * Fixing types * Fix types * Upgrades typescript * Update yarn lock * Typings * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713) * Adds deployment settings to DB (#6706) * WIP * Adds DeploymentTheme * Add missing migrations * Adds client extensions for deployment * Cleanup * Revert "lint fix" This reverts commit e1a2e4a357e58e6673c47399888ae2e00d1351a6. * Add validation * Revert changes removed in force push * Removing abstract class and just leaving interface implementation * Fix types for handlePayments * Fix payment test appStore import * Fix stripe metadata in event type * Move migration to separate PR * Revert "Move migration to separate PR" This reverts commit 48aa64e0724a522d3cc2fefaaaee5792ee9cd9e6. * Update packages/prisma/migrations/20230125175109_remove_type_from_payment_and_add_app_relationship/migration.sql Co-authored-by: Omar López <zomars@me.com> --------- Co-authored-by: zomars <zomars@me.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-02-08 20:36:22 +00:00
if (typeof paymentAppData.price === "number" && paymentAppData.price > 0) {
/* Validate if there is any stripe_payment credential for this user */
/* note: removes custom error message about stripe */
await prisma.credential.findFirstOrThrow({
where: {
type: "stripe_payment",
userId: organizerUser.id,
},
select: {
id: true,
},
});
}
return prisma.booking.create(createBookingObj);
}
let results: EventResult<AdditionalInformation>[] = [];
let referencesToCreate: PartialReference[] = [];
type Booking = Prisma.PromiseReturnType<typeof createBooking>;
let booking: (Booking & { appsStatus?: AppsStatus[] }) | null = null;
try {
booking = await createBooking();
// Sync Services
await syncServicesUpdateWebUser(
await prisma.user.findFirst({
where: { id: userId },
select: { id: true, email: true, name: true, username: true, createdDate: true },
})
);
evt.uid = booking?.uid ?? null;
} catch (_err) {
const err = getErrorFromUnknown(_err);
log.error(`Booking ${eventTypeId} failed`, "Error when saving booking to db", err.message);
if (err.code === "P2002") {
throw new HttpError({ statusCode: 409, message: "booking.conflict" });
}
throw err;
}
// After polling videoBusyTimes, credentials might have been changed due to refreshment, so query them again.
const credentials = await refreshCredentials(organizerUser.credentials);
const eventManager = new EventManager({ ...organizerUser, credentials });
function handleAppsStatus(
results: EventResult<AdditionalInformation>[],
booking: (Booking & { appsStatus?: AppsStatus[] }) | null
) {
// Taking care of apps status
const resultStatus: AppsStatus[] = results.map((app) => ({
appName: app.appName,
type: app.type,
success: app.success ? 1 : 0,
failures: !app.success ? 1 : 0,
errors: app.calError ? [app.calError] : [],
warnings: app.calWarnings,
}));
if (reqAppsStatus === undefined) {
if (booking !== null) {
booking.appsStatus = resultStatus;
}
evt.appsStatus = resultStatus;
return;
}
// From down here we can assume reqAppsStatus is not undefined anymore
// Other status exist, so this is the last booking of a series,
// proceeding to prepare the info for the event
const calcAppsStatus = reqAppsStatus.concat(resultStatus).reduce((prev, curr) => {
if (prev[curr.type]) {
prev[curr.type].success += curr.success;
prev[curr.type].errors = prev[curr.type].errors.concat(curr.errors);
prev[curr.type].warnings = prev[curr.type].warnings?.concat(curr.warnings || []);
} else {
prev[curr.type] = curr;
}
return prev;
}, {} as { [key: string]: AppsStatus });
evt.appsStatus = Object.values(calcAppsStatus);
}
let videoCallUrl;
if (originalRescheduledBooking?.uid) {
// Use EventManager to conditionally use all needed integrations.
const updateManager = await eventManager.reschedule(
evt,
originalRescheduledBooking.uid,
booking?.id,
reqBody.rescheduleReason
);
// This gets overridden when updating the event - to check if notes have been hidden or not. We just reset this back
// to the default description when we are sending the emails.
evt.description = eventType.description;
results = updateManager.results;
referencesToCreate = updateManager.referencesToCreate;
if (results.length > 0 && results.some((res) => !res.success)) {
const error = {
errorCode: "BookingReschedulingMeetingFailed",
message: "Booking Rescheduling failed",
};
log.error(`Booking ${organizerUser.name} failed`, error, results);
} else {
const metadata: AdditionalInformation = {};
if (results.length) {
// TODO: Handle created event metadata more elegantly
const [updatedEvent] = Array.isArray(results[0].updatedEvent)
? results[0].updatedEvent
: [results[0].updatedEvent];
if (updatedEvent) {
metadata.hangoutLink = updatedEvent.hangoutLink;
metadata.conferenceData = updatedEvent.conferenceData;
metadata.entryPoints = updatedEvent.entryPoints;
handleAppsStatus(results, booking);
videoCallUrl = metadata.hangoutLink || videoCallUrl;
}
}
if (noEmail !== true) {
await sendRescheduledEmails({
...evt,
additionalInformation: metadata,
additionalNotes, // Resets back to the additionalNote input and not the override value
2022-10-16 17:46:10 +00:00
cancellationReason: "$RCH$" + reqBody.rescheduleReason, // Removable code prefix to differentiate cancellation from rescheduling for email
});
}
}
// If it's not a reschedule, doesn't require confirmation and there's no price,
// Create a booking
feat/payment-service-6438-cal-767 (#6677) * WIP paymentService * Changes for payment Service * Fix for stripe payment flow * Remove logs/comments * Refactored refund for stripe app * Move stripe handlePayment to own lib * Move stripe delete payments to paymentService * lint fix * Change handleRefundError as generic function * remove log * remove logs * remove logs * Return stripe default export to lib/server * Fixing types * Fix types * Upgrades typescript * Update yarn lock * Typings * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713) * Adds deployment settings to DB (#6706) * WIP * Adds DeploymentTheme * Add missing migrations * Adds client extensions for deployment * Cleanup * Revert "lint fix" This reverts commit e1a2e4a357e58e6673c47399888ae2e00d1351a6. * Add validation * Revert changes removed in force push * Removing abstract class and just leaving interface implementation * Fix types for handlePayments * Fix payment test appStore import * Fix stripe metadata in event type * Move migration to separate PR * Revert "Move migration to separate PR" This reverts commit 48aa64e0724a522d3cc2fefaaaee5792ee9cd9e6. * Update packages/prisma/migrations/20230125175109_remove_type_from_payment_and_add_app_relationship/migration.sql Co-authored-by: Omar López <zomars@me.com> --------- Co-authored-by: zomars <zomars@me.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-02-08 20:36:22 +00:00
} else if (!requiresConfirmation && !paymentAppData.price) {
// Use EventManager to conditionally use all needed integrations.
const createManager = await eventManager.create(evt);
// This gets overridden when creating the event - to check if notes have been hidden or not. We just reset this back
// to the default description when we are sending the emails.
evt.description = eventType.description;
results = createManager.results;
referencesToCreate = createManager.referencesToCreate;
videoCallUrl = evt.videoCallData && evt.videoCallData.url ? evt.videoCallData.url : null;
if (results.length > 0 && results.every((res) => !res.success)) {
const error = {
errorCode: "BookingCreatingMeetingFailed",
message: "Booking failed",
};
log.error(`Booking ${organizerUser.username} failed`, error, results);
} else {
const metadata: AdditionalInformation = {};
if (results.length) {
Google Meet - installable app (#5904) * Abstract app category navigation * Send key schema to frontend Co-authored-by: Omar López <zomars@users.noreply.github.com> * Render keys for apps on admin * Add enabled col for apps * Save app keys to DB * Add checks for admin role * Abstract setup components * Add AdminAppsList to setup wizard * Migrate to v10 tRPC * Default hide keys * Display enabled apps * Merge branch 'main' into admin-apps-ui * Toggle calendars * WIP * Add params and include AppCategoryNavigation * Refactor getEnabledApps * Add warning for disabling apps * Fallback to cal video when a video app is disabled * WIP send disabled email * Send email to all users of event types with payment app * Disable Stripe when app is disabled * Disable apps in event types * Send email to users on disabled apps * Send email based on what app was disabled * WIP type fix * Disable navigation to apps list if already setup * UI import fixes * Waits for session data before redirecting * Updates admin seeded password To comply with admin password requirements * Update yarn.lock * Flex fixes * Adds admin middleware * Clean up * WIP * WIP * NTS * Add dirName to app metadata * Upsert app if not in db * Upsert app if not in db * Add dirName to app metadata * Add keys to app packages w/ keys * Merge with main * Toggle show keys & on enable * Fix empty keys * Fix lark calendar metadata * Fix some type errors * Fix Lark metadata & check for category when upserting * More type fixes * Fix types & add keys to google cal * WIP * WIP * WIP * More type fixes * Fix type errors * Fix type errors * More type fixes * More type fixes * More type fixes * Feedback * Fixes default value * Feedback * Migrate credential invalid col default value "false" * Upsert app on saving keys * Clean up * Validate app keys on frontend * Add nonempty to app keys schemas * Add web3 * Listlocale filter on categories / category * Grab app metadata via category or categories * Show empty screen if no apps are enabled * Fix type checks * Fix type checks * Fix type checks * Fix type checks * Fix type checks * Fix type checks * Replace .nonempty() w/ .min(1) * Fix type error * Address feedback * Draft Google Meet install button * Add install button and warning dialog * WIP * WIP * Display warning when Meet is selected * Display Google Meet warning on email to organizer * Fix email * Fix type errors * Fix type error * Add connected account component * Add warning message * Address comments * Address feedback * Clean up & add MeetLocationType * Use useApp hook * Translate to new API approach * Remove console.log * Refactor * Fix missing backup Cal video link * WIP * Address feedback * Update submodules * Feedback * Submodule sync Co-authored-by: Omar López <zomars@users.noreply.github.com> Co-authored-by: Peer Richelsen <peeroke@gmail.com> Co-authored-by: zomars <zomars@me.com> Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Peer Richelsen <peer@cal.com>
2023-01-10 02:01:57 +00:00
// Handle Google Meet results
// We use the original booking location since the evt location changes to daily
if (bookingLocation === MeetLocationType) {
const googleMeetResult = {
appName: GoogleMeetMetadata.name,
type: "conferencing",
uid: results[0].uid,
originalEvent: results[0].originalEvent,
};
const googleCalResult = results.find((result) => result.type === "google_calendar");
if (!googleCalResult) {
results.push({
...googleMeetResult,
success: false,
calWarnings: [tOrganizer("google_meet_warning")],
});
}
if (googleCalResult?.createdEvent?.hangoutLink) {
results.push({
...googleMeetResult,
success: true,
});
} else if (googleCalResult && !googleCalResult.createdEvent?.hangoutLink) {
results.push({
...googleMeetResult,
success: false,
});
}
}
// TODO: Handle created event metadata more elegantly
metadata.hangoutLink = results[0].createdEvent?.hangoutLink;
metadata.conferenceData = results[0].createdEvent?.conferenceData;
metadata.entryPoints = results[0].createdEvent?.entryPoints;
handleAppsStatus(results, booking);
videoCallUrl = metadata.hangoutLink || videoCallUrl;
}
if (noEmail !== true) {
await sendScheduledEmails({
...evt,
additionalInformation: metadata,
additionalNotes,
customInputs,
});
}
}
}
if (!isConfirmedByDefault && noEmail !== true) {
await sendOrganizerRequestEmail({ ...evt, additionalNotes });
await sendAttendeeRequestEmail({ ...evt, additionalNotes }, attendeesList[0]);
}
if (
feat/payment-service-6438-cal-767 (#6677) * WIP paymentService * Changes for payment Service * Fix for stripe payment flow * Remove logs/comments * Refactored refund for stripe app * Move stripe handlePayment to own lib * Move stripe delete payments to paymentService * lint fix * Change handleRefundError as generic function * remove log * remove logs * remove logs * Return stripe default export to lib/server * Fixing types * Fix types * Upgrades typescript * Update yarn lock * Typings * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713) * Adds deployment settings to DB (#6706) * WIP * Adds DeploymentTheme * Add missing migrations * Adds client extensions for deployment * Cleanup * Revert "lint fix" This reverts commit e1a2e4a357e58e6673c47399888ae2e00d1351a6. * Add validation * Revert changes removed in force push * Removing abstract class and just leaving interface implementation * Fix types for handlePayments * Fix payment test appStore import * Fix stripe metadata in event type * Move migration to separate PR * Revert "Move migration to separate PR" This reverts commit 48aa64e0724a522d3cc2fefaaaee5792ee9cd9e6. * Update packages/prisma/migrations/20230125175109_remove_type_from_payment_and_add_app_relationship/migration.sql Co-authored-by: Omar López <zomars@me.com> --------- Co-authored-by: zomars <zomars@me.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-02-08 20:36:22 +00:00
!Number.isNaN(paymentAppData.price) &&
paymentAppData.price > 0 &&
!originalRescheduledBooking?.paid &&
!!booking
) {
feat/payment-service-6438-cal-767 (#6677) * WIP paymentService * Changes for payment Service * Fix for stripe payment flow * Remove logs/comments * Refactored refund for stripe app * Move stripe handlePayment to own lib * Move stripe delete payments to paymentService * lint fix * Change handleRefundError as generic function * remove log * remove logs * remove logs * Return stripe default export to lib/server * Fixing types * Fix types * Upgrades typescript * Update yarn lock * Typings * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713) * Adds deployment settings to DB (#6706) * WIP * Adds DeploymentTheme * Add missing migrations * Adds client extensions for deployment * Cleanup * Revert "lint fix" This reverts commit e1a2e4a357e58e6673c47399888ae2e00d1351a6. * Add validation * Revert changes removed in force push * Removing abstract class and just leaving interface implementation * Fix types for handlePayments * Fix payment test appStore import * Fix stripe metadata in event type * Move migration to separate PR * Revert "Move migration to separate PR" This reverts commit 48aa64e0724a522d3cc2fefaaaee5792ee9cd9e6. * Update packages/prisma/migrations/20230125175109_remove_type_from_payment_and_add_app_relationship/migration.sql Co-authored-by: Omar López <zomars@me.com> --------- Co-authored-by: zomars <zomars@me.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-02-08 20:36:22 +00:00
// Load credentials.app.categories
const credentialPaymentAppCategories = await prisma.credential.findMany({
where: {
userId: organizerUser.id,
app: {
categories: {
hasSome: ["payment"],
},
},
},
select: {
key: true,
appId: true,
app: {
select: {
categories: true,
dirName: true,
},
},
},
});
const eventTypePaymentAppCredential = credentialPaymentAppCategories.find((credential) => {
return credential.appId === paymentAppData.appId;
});
feat/payment-service-6438-cal-767 (#6677) * WIP paymentService * Changes for payment Service * Fix for stripe payment flow * Remove logs/comments * Refactored refund for stripe app * Move stripe handlePayment to own lib * Move stripe delete payments to paymentService * lint fix * Change handleRefundError as generic function * remove log * remove logs * remove logs * Return stripe default export to lib/server * Fixing types * Fix types * Upgrades typescript * Update yarn lock * Typings * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713) * Adds deployment settings to DB (#6706) * WIP * Adds DeploymentTheme * Add missing migrations * Adds client extensions for deployment * Cleanup * Revert "lint fix" This reverts commit e1a2e4a357e58e6673c47399888ae2e00d1351a6. * Add validation * Revert changes removed in force push * Removing abstract class and just leaving interface implementation * Fix types for handlePayments * Fix payment test appStore import * Fix stripe metadata in event type * Move migration to separate PR * Revert "Move migration to separate PR" This reverts commit 48aa64e0724a522d3cc2fefaaaee5792ee9cd9e6. * Update packages/prisma/migrations/20230125175109_remove_type_from_payment_and_add_app_relationship/migration.sql Co-authored-by: Omar López <zomars@me.com> --------- Co-authored-by: zomars <zomars@me.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-02-08 20:36:22 +00:00
if (!eventTypePaymentAppCredential) {
throw new HttpError({ statusCode: 400, message: "Missing payment credentials" });
feat/payment-service-6438-cal-767 (#6677) * WIP paymentService * Changes for payment Service * Fix for stripe payment flow * Remove logs/comments * Refactored refund for stripe app * Move stripe handlePayment to own lib * Move stripe delete payments to paymentService * lint fix * Change handleRefundError as generic function * remove log * remove logs * remove logs * Return stripe default export to lib/server * Fixing types * Fix types * Upgrades typescript * Update yarn lock * Typings * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713) * Adds deployment settings to DB (#6706) * WIP * Adds DeploymentTheme * Add missing migrations * Adds client extensions for deployment * Cleanup * Revert "lint fix" This reverts commit e1a2e4a357e58e6673c47399888ae2e00d1351a6. * Add validation * Revert changes removed in force push * Removing abstract class and just leaving interface implementation * Fix types for handlePayments * Fix payment test appStore import * Fix stripe metadata in event type * Move migration to separate PR * Revert "Move migration to separate PR" This reverts commit 48aa64e0724a522d3cc2fefaaaee5792ee9cd9e6. * Update packages/prisma/migrations/20230125175109_remove_type_from_payment_and_add_app_relationship/migration.sql Co-authored-by: Omar López <zomars@me.com> --------- Co-authored-by: zomars <zomars@me.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-02-08 20:36:22 +00:00
}
feat/payment-service-6438-cal-767 (#6677) * WIP paymentService * Changes for payment Service * Fix for stripe payment flow * Remove logs/comments * Refactored refund for stripe app * Move stripe handlePayment to own lib * Move stripe delete payments to paymentService * lint fix * Change handleRefundError as generic function * remove log * remove logs * remove logs * Return stripe default export to lib/server * Fixing types * Fix types * Upgrades typescript * Update yarn lock * Typings * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713) * Adds deployment settings to DB (#6706) * WIP * Adds DeploymentTheme * Add missing migrations * Adds client extensions for deployment * Cleanup * Revert "lint fix" This reverts commit e1a2e4a357e58e6673c47399888ae2e00d1351a6. * Add validation * Revert changes removed in force push * Removing abstract class and just leaving interface implementation * Fix types for handlePayments * Fix payment test appStore import * Fix stripe metadata in event type * Move migration to separate PR * Revert "Move migration to separate PR" This reverts commit 48aa64e0724a522d3cc2fefaaaee5792ee9cd9e6. * Update packages/prisma/migrations/20230125175109_remove_type_from_payment_and_add_app_relationship/migration.sql Co-authored-by: Omar López <zomars@me.com> --------- Co-authored-by: zomars <zomars@me.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-02-08 20:36:22 +00:00
// Convert type of eventTypePaymentAppCredential to appId: EventTypeAppList
if (!booking.user) booking.user = organizerUser;
feat/payment-service-6438-cal-767 (#6677) * WIP paymentService * Changes for payment Service * Fix for stripe payment flow * Remove logs/comments * Refactored refund for stripe app * Move stripe handlePayment to own lib * Move stripe delete payments to paymentService * lint fix * Change handleRefundError as generic function * remove log * remove logs * remove logs * Return stripe default export to lib/server * Fixing types * Fix types * Upgrades typescript * Update yarn lock * Typings * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713) * Adds deployment settings to DB (#6706) * WIP * Adds DeploymentTheme * Add missing migrations * Adds client extensions for deployment * Cleanup * Revert "lint fix" This reverts commit e1a2e4a357e58e6673c47399888ae2e00d1351a6. * Add validation * Revert changes removed in force push * Removing abstract class and just leaving interface implementation * Fix types for handlePayments * Fix payment test appStore import * Fix stripe metadata in event type * Move migration to separate PR * Revert "Move migration to separate PR" This reverts commit 48aa64e0724a522d3cc2fefaaaee5792ee9cd9e6. * Update packages/prisma/migrations/20230125175109_remove_type_from_payment_and_add_app_relationship/migration.sql Co-authored-by: Omar López <zomars@me.com> --------- Co-authored-by: zomars <zomars@me.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-02-08 20:36:22 +00:00
const payment = await handlePayment(
evt,
eventType,
eventTypePaymentAppCredential as IEventTypePaymentCredentialType,
booking
);
req.statusCode = 201;
feat/payment-service-6438-cal-767 (#6677) * WIP paymentService * Changes for payment Service * Fix for stripe payment flow * Remove logs/comments * Refactored refund for stripe app * Move stripe handlePayment to own lib * Move stripe delete payments to paymentService * lint fix * Change handleRefundError as generic function * remove log * remove logs * remove logs * Return stripe default export to lib/server * Fixing types * Fix types * Upgrades typescript * Update yarn lock * Typings * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713) * Adds deployment settings to DB (#6706) * WIP * Adds DeploymentTheme * Add missing migrations * Adds client extensions for deployment * Cleanup * Revert "lint fix" This reverts commit e1a2e4a357e58e6673c47399888ae2e00d1351a6. * Add validation * Revert changes removed in force push * Removing abstract class and just leaving interface implementation * Fix types for handlePayments * Fix payment test appStore import * Fix stripe metadata in event type * Move migration to separate PR * Revert "Move migration to separate PR" This reverts commit 48aa64e0724a522d3cc2fefaaaee5792ee9cd9e6. * Update packages/prisma/migrations/20230125175109_remove_type_from_payment_and_add_app_relationship/migration.sql Co-authored-by: Omar López <zomars@me.com> --------- Co-authored-by: zomars <zomars@me.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-02-08 20:36:22 +00:00
return { ...booking, message: "Payment required", paymentUid: payment?.uid };
}
log.debug(`Booking ${organizerUser.username} completed`);
const metadata = videoCallUrl ? { videoCallUrl } : undefined;
if (isConfirmedByDefault) {
const eventTrigger: WebhookTriggerEvents = rescheduleUid
? WebhookTriggerEvents.BOOKING_RESCHEDULED
: WebhookTriggerEvents.BOOKING_CREATED;
const subscriberOptions = {
userId: organizerUser.id,
eventTypeId,
triggerEvent: eventTrigger,
};
const subscriberOptionsMeetingEnded = {
userId: organizerUser.id,
eventTypeId,
triggerEvent: WebhookTriggerEvents.MEETING_ENDED,
};
try {
const subscribersMeetingEnded = await getWebhooks(subscriberOptionsMeetingEnded);
subscribersMeetingEnded.forEach((subscriber) => {
if (rescheduleUid && originalRescheduledBooking) {
cancelScheduledJobs(originalRescheduledBooking, undefined, true);
}
if (booking && booking.status === BookingStatus.ACCEPTED) {
scheduleTrigger(booking, subscriber.subscriberUrl, subscriber);
}
});
} catch (error) {
log.error("Error while running scheduledJobs for booking", error);
}
try {
// Send Webhook call if hooked to BOOKING_CREATED & BOOKING_RESCHEDULED
const subscribers = await getWebhooks(subscriberOptions);
console.log("evt:", {
...evt,
metadata: reqBody.metadata,
});
const bookingId = booking?.id;
const eventTypeInfo: EventTypeInfo = {
eventTitle: eventType.title,
eventDescription: eventType.description,
requiresConfirmation: requiresConfirmation || null,
feat/payment-service-6438-cal-767 (#6677) * WIP paymentService * Changes for payment Service * Fix for stripe payment flow * Remove logs/comments * Refactored refund for stripe app * Move stripe handlePayment to own lib * Move stripe delete payments to paymentService * lint fix * Change handleRefundError as generic function * remove log * remove logs * remove logs * Return stripe default export to lib/server * Fixing types * Fix types * Upgrades typescript * Update yarn lock * Typings * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) * Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713) * Adds deployment settings to DB (#6706) * WIP * Adds DeploymentTheme * Add missing migrations * Adds client extensions for deployment * Cleanup * Revert "lint fix" This reverts commit e1a2e4a357e58e6673c47399888ae2e00d1351a6. * Add validation * Revert changes removed in force push * Removing abstract class and just leaving interface implementation * Fix types for handlePayments * Fix payment test appStore import * Fix stripe metadata in event type * Move migration to separate PR * Revert "Move migration to separate PR" This reverts commit 48aa64e0724a522d3cc2fefaaaee5792ee9cd9e6. * Update packages/prisma/migrations/20230125175109_remove_type_from_payment_and_add_app_relationship/migration.sql Co-authored-by: Omar López <zomars@me.com> --------- Co-authored-by: zomars <zomars@me.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-02-08 20:36:22 +00:00
price: paymentAppData.price,
currency: eventType.currency,
length: eventType.length,
};
const promises = subscribers.map((sub) =>
sendPayload(sub.secret, eventTrigger, new Date().toISOString(), sub, {
...evt,
...eventTypeInfo,
bookingId,
rescheduleUid,
rescheduleStartTime: originalRescheduledBooking?.startTime
? dayjs(originalRescheduledBooking?.startTime).utc().format()
: undefined,
rescheduleEndTime: originalRescheduledBooking?.endTime
? dayjs(originalRescheduledBooking?.endTime).utc().format()
: undefined,
metadata: { ...metadata, ...reqBody.metadata },
eventTypeId,
status: "ACCEPTED",
smsReminderNumber: booking?.smsReminderNumber || undefined,
}).catch((e) => {
console.error(`Error executing webhook for event: ${eventTrigger}, URL: ${sub.subscriberUrl}`, e);
})
);
await Promise.all(promises);
} catch (error) {
log.error("Error while sending webhook", error);
}
}
// Avoid passing referencesToCreate with id unique constrain values
// refresh hashed link if used
const urlSeed = `${organizerUser.username}:${dayjs(reqBody.start).utc().format()}`;
const hashedUid = translator.fromUUID(uuidv5(urlSeed, uuidv5.URL));
try {
if (hasHashedBookingLink) {
await prisma.hashedLink.update({
where: {
link: reqBody.hashedLink as string,
},
data: {
link: hashedUid,
},
});
}
} catch (error) {
log.error("Error while updating hashed link", error);
}
if (!booking) throw new HttpError({ statusCode: 400, message: "Booking failed" });
try {
await prisma.booking.update({
where: {
uid: booking.uid,
},
data: {
metadata: { ...(typeof booking.metadata === "object" && booking.metadata), ...metadata },
references: {
createMany: {
data: referencesToCreate,
},
},
},
});
} catch (error) {
log.error("Error while creating booking references", error);
}
try {
await scheduleWorkflowReminders(
eventType.workflows,
reqBody.smsReminderNumber as string | null,
{ ...evt, ...{ metadata } },
evt.requiresConfirmation || false,
rescheduleUid ? true : false,
true
);
} catch (error) {
log.error("Error while scheduling workflow reminders", error);
}
// booking successful
req.statusCode = 201;
return booking;
}
export default handler;
function handleCustomInputs(
eventTypeCustomInputs: EventTypeCustomInput[],
reqCustomInputs: {
value: string | boolean;
label: string;
}[]
) {
eventTypeCustomInputs.forEach((etcInput) => {
if (etcInput.required) {
const input = reqCustomInputs.find((i) => i.label === etcInput.label);
if (etcInput.type === "BOOL") {
z.literal(true, {
errorMap: () => ({ message: `Missing ${etcInput.type} customInput: '${etcInput.label}'` }),
}).parse(input?.value);
} else if (etcInput.type === "PHONE") {
z.string({
errorMap: () => ({
message: `Missing ${etcInput.type} customInput: '${etcInput.label}'`,
}),
})
.refine((val) => isValidPhoneNumber(val), {
message: "Phone number is invalid",
})
.parse(input?.value);
} else {
// type: NUMBER are also passed as string
z.string({
errorMap: () => ({ message: `Missing ${etcInput.type} customInput: '${etcInput.label}'` }),
})
.min(1)
.parse(input?.value);
}
}
});
}