* 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
156 lines
4.1 KiB
TypeScript
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 });
|
|
}
|