143 lines
5.2 KiB
TypeScript
143 lines
5.2 KiB
TypeScript
import { ApprovalWorkflow } from "@/interfaces/approval.workflow";
|
|
import client from "@/lib/mongodb";
|
|
import { ObjectId } from "mongodb";
|
|
|
|
const db = client.db(process.env.MONGODB_DB);
|
|
|
|
export const getApprovalWorkflows = async (collection: string, entityIds?: string[], ids?: string[], assignee?: string) => {
|
|
const filters: any = {};
|
|
|
|
if (ids && ids.length > 0) {
|
|
filters.id = { $in: ids };
|
|
}
|
|
|
|
if (entityIds && entityIds.length > 0) {
|
|
filters.entityId = { $in: entityIds };
|
|
}
|
|
|
|
if (assignee) {
|
|
filters["steps.assignees"] = assignee;
|
|
}
|
|
|
|
return await db
|
|
.collection<ApprovalWorkflow>(collection)
|
|
.find(filters)
|
|
.sort({ startDate: -1 })
|
|
.toArray();
|
|
};
|
|
|
|
export const getApprovalWorkflow = async (collection: string, id: string) => {
|
|
return await db.collection<ApprovalWorkflow>(collection).findOne({ _id: new ObjectId(id) });
|
|
};
|
|
|
|
export const getApprovalWorkflowsByEntities = async (collection: string, ids: string[]) => {
|
|
return await db
|
|
.collection<ApprovalWorkflow>(collection)
|
|
.find({ entityId: { $in: ids } })
|
|
.sort({ startDate: -1 })
|
|
.toArray();
|
|
};
|
|
|
|
export const getApprovalWorkflowByFormIntaker = async (entityId: string, formIntakerId: string) => {
|
|
return await db.collection<ApprovalWorkflow>("configured-workflows").findOne({
|
|
entityId,
|
|
steps: {
|
|
$elemMatch: {
|
|
stepNumber: 1,
|
|
assignees: formIntakerId,
|
|
},
|
|
},
|
|
});
|
|
};
|
|
|
|
export const getApprovalWorkflowsByExamId = async (examId: string) => {
|
|
return await db
|
|
.collection<ApprovalWorkflow>("active-workflows")
|
|
.find({
|
|
examId,
|
|
status: { $in: ["pending"] },
|
|
})
|
|
.toArray();
|
|
};
|
|
|
|
export const getFormIntakersByEntity = async (entityId: string) => {
|
|
const results = await db
|
|
.collection<ApprovalWorkflow>("configured-workflows")
|
|
.aggregate([
|
|
// 1. Match workflows with the provided entityId
|
|
{ $match: { entityId } },
|
|
// 2. Unwind the steps array to process each step individually
|
|
{ $unwind: "$steps" },
|
|
// 3. Filter for the first step (you could also check for a "firstStep" flag if you prefer)
|
|
{ $match: { "steps.stepNumber": 1 } },
|
|
// 4. Unwind the assignees array so that each assignee is handled separately
|
|
{ $unwind: "$steps.assignees" },
|
|
// 5. Group by null (i.e. all documents) and add each assignee to a set to remove duplicates
|
|
{ $group: { _id: null, assignees: { $addToSet: "$steps.assignees" } } },
|
|
])
|
|
.toArray();
|
|
|
|
// Return the assignees if the aggregation found any; otherwise return an empty array
|
|
return results.length > 0 ? results[0].assignees : [];
|
|
};
|
|
|
|
export const createApprovalWorkflow = async (collection: string, workflow: ApprovalWorkflow) => {
|
|
const { _id, ...workflowWithoutId } = workflow as ApprovalWorkflow;
|
|
return await db.collection(collection).insertOne(workflowWithoutId);
|
|
};
|
|
|
|
export const createApprovalWorkflows = async (collection: string, workflows: ApprovalWorkflow[]) => {
|
|
if (workflows.length === 0) return;
|
|
const workflowsWithoutIds: ApprovalWorkflow[] = workflows.map(({ _id, ...wfs }) => wfs);
|
|
return await db.collection(collection).insertMany(workflowsWithoutIds);
|
|
};
|
|
|
|
export const updateApprovalWorkflow = async (collection: string, workflow: ApprovalWorkflow) => {
|
|
const { _id, ...workflowWithoutId } = workflow as ApprovalWorkflow;
|
|
return await db.collection(collection).replaceOne({ _id: new ObjectId(_id) }, workflowWithoutId);
|
|
};
|
|
|
|
export const updateApprovalWorkflows = async (collection: string, workflows: ApprovalWorkflow[]) => {
|
|
const bulkOperations = workflows.map((workflow) => {
|
|
const { _id, ...workflowWithoutId } = workflow;
|
|
return {
|
|
replaceOne: {
|
|
filter: { _id: new ObjectId(_id) },
|
|
replacement: workflowWithoutId,
|
|
},
|
|
};
|
|
});
|
|
|
|
return await db.collection(collection).bulkWrite(bulkOperations);
|
|
};
|
|
|
|
export const deleteApprovalWorkflow = async (collection: string, id: string) => {
|
|
return await db.collection(collection).deleteOne({ _id: new ObjectId(id) });
|
|
};
|
|
|
|
export const replaceApprovalWorkflowsByEntities = async (workflows: ApprovalWorkflow[], entityIds: string[]) => {
|
|
// 1. Keep track of the _id values of all workflows we want to end up with
|
|
const finalIds = new Set<string>();
|
|
|
|
// 2. Process incoming workflows
|
|
for (const workflow of workflows) {
|
|
if (workflow._id) {
|
|
// Replace the existing ones
|
|
await updateApprovalWorkflow("configured-workflows", workflow);
|
|
finalIds.add(workflow._id.toString());
|
|
} else {
|
|
// Insert if no _id
|
|
const insertResult = await createApprovalWorkflow("configured-workflows", workflow);
|
|
finalIds.add(insertResult.insertedId.toString());
|
|
}
|
|
}
|
|
|
|
// 3. Delete any existing workflow (within these entityIds) that wasn't in the final list
|
|
await db.collection("configured-workflows").deleteMany({
|
|
_id: {
|
|
$nin: Array.from(finalIds).map((id) => new ObjectId(id)),
|
|
},
|
|
entityId: { $in: entityIds },
|
|
});
|
|
};
|