Files
calendar/packages/lib/raqb/getAttributes.ts
T
Joe Au-YeungandGitHub ff79e5c70e feat: Record assignment reasons for routing form and reassignment (#17767)
* Add assignment reason table

* Increment id

* Update migration

* Record assignment when manual reassignment is used

* Add comment to `getAttributesQueryValue`

* Add `getUsersAttributes`

* Record routing form routing reason

* Type fixes

* Remove unique property from bookingId

* Handle nested values
2024-11-21 16:27:19 +00:00

156 lines
4.1 KiB
TypeScript

// TODO: Queries in this file are not optimized. Need to optimize them.
import logger from "@calcom/lib/logger";
import { safeStringify } from "@calcom/lib/safeStringify";
import prisma from "@calcom/prisma";
import type { Attribute } from "./types";
async function getAttributeToUserWithMembershipAndAttributesForTeam({ teamId }: { teamId: number }) {
const log = logger.getSubLogger({ prefix: ["getAttributeToUserWithMembershipAndAttributes"] });
const whereClauseForAttributesAssignedToMembersOfTeam = {
member: {
user: {
teams: {
some: {
teamId,
},
},
},
},
};
log.debug(
safeStringify({
teamId,
whereClauseForAttributesAssignedToMembersOfTeam,
})
);
const attributesToUser = await prisma.attributeToUser.findMany({
where: whereClauseForAttributesAssignedToMembersOfTeam,
select: {
member: {
select: {
userId: true,
},
},
attributeOption: {
select: {
id: true,
value: true,
slug: true,
attribute: {
select: { id: true, name: true, type: true, slug: true },
},
},
},
},
});
log.debug("Returned attributesToUser", safeStringify({ attributesToUser }));
return attributesToUser;
}
async function getAttributesAssignedToMembersOfTeam({ teamId, userId }: { teamId: number; userId?: number }) {
const log = logger.getSubLogger({ prefix: ["getAttributeToUserWithMembershipAndAttributes"] });
const whereClauseForAttributesAssignedToMembersOfTeam = {
options: {
some: {
assignedUsers: {
some: {
member: {
userId,
user: {
teams: {
some: {
teamId,
},
},
},
},
},
},
},
},
};
log.debug(
safeStringify({
teamId,
whereClauseForAttributesAssignedToMembersOfTeam,
})
);
const attributesToUser = await prisma.attribute.findMany({
where: whereClauseForAttributesAssignedToMembersOfTeam,
select: {
id: true,
name: true,
type: true,
options: {
select: {
id: true,
value: true,
slug: true,
},
},
slug: true,
},
});
return attributesToUser;
}
export async function getAttributesForTeam({ teamId }: { teamId: number }) {
const attributes = await getAttributesAssignedToMembersOfTeam({ teamId });
return attributes satisfies Attribute[];
}
type AttributeId = string;
type AttributeOptionValueWithType = {
type: Attribute["type"];
value: string | string[];
};
type UserId = number;
export async function getTeamMembersWithAttributeOptionValuePerAttribute({ teamId }: { teamId: number }) {
const attributesToUser = await getAttributeToUserWithMembershipAndAttributesForTeam({ teamId });
const teamMembers = attributesToUser.reduce((acc, attributeToUser) => {
const { userId } = attributeToUser.member;
const { attribute, value } = attributeToUser.attributeOption;
if (!acc[userId]) {
acc[userId] = { userId, attributes: {} };
}
const attributes = acc[userId].attributes;
const attributeValue = attributes[attribute.id]?.value;
if (attributeValue instanceof Array) {
// Value already exists, so push to it
attributeValue.push(value);
} else if (attributeValue) {
// Value already exists, so push to it and also make it an array before pushing
attributes[attribute.id] = {
type: attribute.type,
value: [attributeValue, value],
};
} else {
// Set the first value
attributes[attribute.id] = {
type: attribute.type,
value,
};
}
return acc;
}, {} as Record<UserId, { userId: UserId; attributes: Record<AttributeId, AttributeOptionValueWithType> }>);
return Object.values(teamMembers);
}
export async function getUsersAttributes({ userId, teamId }: { userId: number; teamId: number }) {
return await getAttributesAssignedToMembersOfTeam({ teamId, userId });
}