diff --git a/apps/web/components/dialog/RerouteDialog.tsx b/apps/web/components/dialog/RerouteDialog.tsx index ca72e40dc83ad2..d5e8e0d5528082 100644 --- a/apps/web/components/dialog/RerouteDialog.tsx +++ b/apps/web/components/dialog/RerouteDialog.tsx @@ -1,4 +1,5 @@ import { useMutation } from "@tanstack/react-query"; +import { useSession } from "next-auth/react"; import Link from "next/link"; import { useRouter } from "next/navigation"; import { useState } from "react"; @@ -277,6 +278,7 @@ const NewRoutingManager = ({ const { t } = useLocale(); const router = useRouter(); const bookerUrl = useBookerUrl(); + const session = useSession(); const teamMemberIdsMatchingAttributeLogic = teamMembersMatchingAttributeLogic?.data ?.map((member) => member.id) @@ -467,6 +469,7 @@ const NewRoutingManager = ({ // TODO: Long term, we should refactor handleNewBooking and use a different route specific for this purpose, createBookingMutation.mutate({ rescheduleUid: booking.uid, + rescheduledBy: session?.data?.user?.email ?? undefined, // rescheduleReason, reroutingFormResponses: reroutingFormResponses, ...getTimeslotFields(), diff --git a/apps/web/components/dialog/__tests__/RerouteDialog.test.tsx b/apps/web/components/dialog/__tests__/RerouteDialog.test.tsx index e5c68d786e9a73..368141a76180d3 100644 --- a/apps/web/components/dialog/__tests__/RerouteDialog.test.tsx +++ b/apps/web/components/dialog/__tests__/RerouteDialog.test.tsx @@ -1,4 +1,6 @@ import { act, fireEvent, render, screen } from "@testing-library/react"; +import type { Session } from "next-auth"; +import { SessionProvider } from "next-auth/react"; import { vi } from "vitest"; import { RouteActionType } from "@calcom/app-store/routing-forms/zod"; @@ -36,6 +38,15 @@ const mockOpen = vi.fn((_url: string) => { vi.stubGlobal("open", mockOpen); +const mockSession = { + expires: new Date(Date.now() + 2 * 86400).toISOString(), + user: { + id: 1, + name: "Test User", + email: "user@example.com", + }, +} as Session; + vi.mock("@calcom/app-store/routing-forms/components/FormInputFields", () => ({ default: vi.fn(({ response, form, setResponse, disabledFields }) => { return ( @@ -383,7 +394,9 @@ describe("RerouteDialog", () => { describe("New Routing tests", () => { test("when verify_new_route is clicked, the form is submitted", async () => { render( - + + + ); fireEvent.click(screen.getByText("verify_new_route")); @@ -402,7 +415,9 @@ describe("RerouteDialog", () => { describe("New tab rescheduling", () => { test("new tab is closed when new booking is rerouted", async () => { render( - + + + ); clickVerifyNewRouteButton(); clickRescheduleToTheNewEventWithDifferentTimeslotButton(); @@ -441,7 +456,9 @@ describe("RerouteDialog", () => { test("Rescheduling with same timeslot works", async () => { render( - + + + ); clickVerifyNewRouteButton(); clickRescheduleWithSameTimeslotOfChosenEventButton(); diff --git a/packages/features/bookings/lib/handleNewBooking.ts b/packages/features/bookings/lib/handleNewBooking.ts index a30ad16c143dc2..194158086b479d 100644 --- a/packages/features/bookings/lib/handleNewBooking.ts +++ b/packages/features/bookings/lib/handleNewBooking.ts @@ -1220,6 +1220,8 @@ async function handler( routingFormResponseId, organizerId: organizerUser.id, teamId, + isRerouting: isReroutingCase, + reroutedByEmail: reqBody.rescheduledBy, }); } } diff --git a/packages/features/ee/round-robin/assignmentReason/AssignmentReasonRecorder.ts b/packages/features/ee/round-robin/assignmentReason/AssignmentReasonRecorder.ts index 65e39761295694..0810464f4f057f 100644 --- a/packages/features/ee/round-robin/assignmentReason/AssignmentReasonRecorder.ts +++ b/packages/features/ee/round-robin/assignmentReason/AssignmentReasonRecorder.ts @@ -13,11 +13,15 @@ export default class AssignmentReasonRecorder { routingFormResponseId, organizerId, teamId, + isRerouting, + reroutedByEmail, }: { bookingId: number; routingFormResponseId: number; organizerId: number; teamId: number; + isRerouting: boolean; + reroutedByEmail?: string | null; }) { // Get the routing form data const routingFormResponse = await prisma.app_RoutingForms_FormResponse.findFirst({ @@ -98,11 +102,29 @@ export default class AssignmentReasonRecorder { } } + let reroutedByUserId: number | null = null; + if (isRerouting && reroutedByEmail) { + const userQuery = await prisma.user.findFirst({ + where: { + email: reroutedByEmail, + }, + select: { + id: true, + }, + }); + + if (userQuery) { + reroutedByUserId = userQuery.id; + } + } + await prisma.assignmentReason.create({ data: { bookingId: bookingId, - reasonEnum: AssignmentReasonEnum.ROUTING_FORM_ROUTING, - reasonString: attributeValues.join(", "), + reasonEnum: isRerouting ? AssignmentReasonEnum.REROUTED : AssignmentReasonEnum.ROUTING_FORM_ROUTING, + reasonString: `${ + reroutedByUserId ? `Rerouted by user: ${reroutedByUserId}` : "" + } ${attributeValues.join(", ")}`, }, }); }