feat: make assignedTo field accept multiple values for all collections
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import mongoose from "mongoose";
|
import mongoose, { Schema } from "mongoose";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { files } from "../file/file.schema";
|
import { files } from "../file/file.schema";
|
||||||
import { buildJsonSchemas } from "fastify-zod";
|
import { buildJsonSchemas } from "fastify-zod";
|
||||||
@@ -25,7 +25,7 @@ const taskSchema = new mongoose.Schema({
|
|||||||
ref: "user",
|
ref: "user",
|
||||||
},
|
},
|
||||||
assignedTo: {
|
assignedTo: {
|
||||||
type: mongoose.Types.ObjectId,
|
type: [Schema.Types.ObjectId],
|
||||||
ref: "user",
|
ref: "user",
|
||||||
},
|
},
|
||||||
taggedUsers: Array,
|
taggedUsers: Array,
|
||||||
@@ -41,7 +41,7 @@ const createTaskInput = z.object({
|
|||||||
title: z.string(),
|
title: z.string(),
|
||||||
dueDate: z.date().optional(),
|
dueDate: z.date().optional(),
|
||||||
files: z.array(files).optional(),
|
files: z.array(files).optional(),
|
||||||
assignedTo: z.string().optional(),
|
assignedTo: z.array(z.string()).optional(),
|
||||||
labels: z.array(z.string()).optional(),
|
labels: z.array(z.string()).optional(),
|
||||||
priority: z.string().optional(),
|
priority: z.string().optional(),
|
||||||
stage: z
|
stage: z
|
||||||
@@ -64,7 +64,7 @@ const updateTaskInput = z.object({
|
|||||||
title: z.string().optional(),
|
title: z.string().optional(),
|
||||||
dueDate: z.date().optional(),
|
dueDate: z.date().optional(),
|
||||||
files: z.array(files).optional(),
|
files: z.array(files).optional(),
|
||||||
assignedTo: z.string().optional(),
|
assignedTo: z.array(z.string()).optional(),
|
||||||
labels: z.array(z.string()).optional(),
|
labels: z.array(z.string()).optional(),
|
||||||
priority: z.string().optional(),
|
priority: z.string().optional(),
|
||||||
stage: z
|
stage: z
|
||||||
|
|||||||
@@ -163,12 +163,14 @@ export async function listTasks(
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
assignedTo: {
|
assignedTo: {
|
||||||
$let: {
|
$map: {
|
||||||
vars: { assignedTo: { $arrayElemAt: ["$assignedTo", 0] } },
|
input: "$assignedTo",
|
||||||
|
as: "user",
|
||||||
in: {
|
in: {
|
||||||
_id: "$$assignedTo._id",
|
_id: "$$user._id",
|
||||||
pid: "$$assignedTo.pid",
|
pid: "$$user.pid",
|
||||||
name: "$$assignedTo.name",
|
name: "$$user.name",
|
||||||
|
avatar: "$$user.avatar",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -272,12 +274,14 @@ export async function searchTasks(
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
assignedTo: {
|
assignedTo: {
|
||||||
$let: {
|
$map: {
|
||||||
vars: { assignedTo: { $arrayElemAt: ["$assignedTo", 0] } },
|
input: "$assignedTo",
|
||||||
|
as: "user",
|
||||||
in: {
|
in: {
|
||||||
_id: "$$assignedTo._id",
|
_id: "$$user._id",
|
||||||
pid: "$$assignedTo.pid",
|
pid: "$$user.pid",
|
||||||
name: "$$assignedTo.name",
|
name: "$$user.name",
|
||||||
|
avatar: "$$user.avatar",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -46,7 +46,10 @@ export async function createNote(
|
|||||||
if (!obj.taggedUsers) {
|
if (!obj.taggedUsers) {
|
||||||
await model.updateOne(
|
await model.updateOne(
|
||||||
{ pid: resourceId },
|
{ pid: resourceId },
|
||||||
{ $set: { taggedUsers: taggedUsers, assignedTo: userIds[0] } }
|
{
|
||||||
|
$set: { taggedUsers: taggedUsers },
|
||||||
|
$addToSet: { assignedTo: userIds[0] },
|
||||||
|
}
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
for (const user of taggedUsers) {
|
for (const user of taggedUsers) {
|
||||||
@@ -57,7 +60,11 @@ export async function createNote(
|
|||||||
else obj.taggedUsers.push(user);
|
else obj.taggedUsers.push(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
obj.assignedTo = userIds[0];
|
const assignee = obj.assignedTo.find(
|
||||||
|
(item) => item.toString() == userIds[0]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!assignee) obj.assignedTo.push(userIds[0]);
|
||||||
|
|
||||||
obj.markModified("taggedUsers", "assignedTo");
|
obj.markModified("taggedUsers", "assignedTo");
|
||||||
await obj.save();
|
await obj.save();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { buildJsonSchemas } from "fastify-zod";
|
import { buildJsonSchemas } from "fastify-zod";
|
||||||
import mongoose from "mongoose";
|
import mongoose, { Schema } from "mongoose";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { pageQueryParams } from "../pagination";
|
import { pageQueryParams } from "../pagination";
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ const notificationSchema = new mongoose.Schema({
|
|||||||
createdAt: Date,
|
createdAt: Date,
|
||||||
updatedAt: Date,
|
updatedAt: Date,
|
||||||
assignedTo: {
|
assignedTo: {
|
||||||
type: mongoose.Types.ObjectId,
|
type: [Schema.Types.ObjectId],
|
||||||
ref: "user",
|
ref: "user",
|
||||||
},
|
},
|
||||||
taggedUsers: Array,
|
taggedUsers: Array,
|
||||||
@@ -52,12 +52,12 @@ const createNotificationInput = z.object({
|
|||||||
county: z.object({}).passthrough(),
|
county: z.object({}).passthrough(),
|
||||||
client: z.string(),
|
client: z.string(),
|
||||||
clientData: z.object({}).passthrough(),
|
clientData: z.object({}).passthrough(),
|
||||||
assignedTo: z.string().optional(),
|
assignedTo: z.array(z.string()).optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const updateNotificationInput = z.object({
|
const updateNotificationInput = z.object({
|
||||||
status: z.string().optional(),
|
status: z.string().optional(),
|
||||||
assignedTo: z.string().optional(),
|
assignedTo: z.array(z.string()).optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export type CreateNotificationInput = z.infer<typeof createNotificationInput>;
|
export type CreateNotificationInput = z.infer<typeof createNotificationInput>;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import {
|
|||||||
import { getUser } from "../user/user.service";
|
import { getUser } from "../user/user.service";
|
||||||
import { createNote } from "../note/note.service";
|
import { createNote } from "../note/note.service";
|
||||||
import { createAlert } from "../alert/alert.service";
|
import { createAlert } from "../alert/alert.service";
|
||||||
|
import { arrayDiff } from "../utils/diff";
|
||||||
|
|
||||||
export async function createNotification(
|
export async function createNotification(
|
||||||
input: CreateNotificationInput,
|
input: CreateNotificationInput,
|
||||||
@@ -51,6 +52,11 @@ export async function updateNotification(
|
|||||||
input: UpdateNotificationInput,
|
input: UpdateNotificationInput,
|
||||||
user: AuthenticatedUser
|
user: AuthenticatedUser
|
||||||
) {
|
) {
|
||||||
|
const oldNotification = await notificationModel.findOne(
|
||||||
|
{ pid: notifId },
|
||||||
|
{ assignedTo: 1 }
|
||||||
|
);
|
||||||
|
|
||||||
const updateNotificationResult = await notificationModel
|
const updateNotificationResult = await notificationModel
|
||||||
.findOneAndUpdate(
|
.findOneAndUpdate(
|
||||||
{ $and: [{ tenantId: user.tenantId }, { pid: notifId }] },
|
{ $and: [{ tenantId: user.tenantId }, { pid: notifId }] },
|
||||||
@@ -64,16 +70,11 @@ export async function updateNotification(
|
|||||||
|
|
||||||
if (updateNotificationResult) {
|
if (updateNotificationResult) {
|
||||||
for (const key in input) {
|
for (const key in input) {
|
||||||
if (["status", "assignedTo"].includes(key)) {
|
if (["status"].includes(key)) {
|
||||||
let msg = "";
|
let msg = "";
|
||||||
|
|
||||||
if (input[key] === null) {
|
if (input[key] === null) {
|
||||||
msg = `Cleared ${key}`;
|
msg = `Cleared ${key}`;
|
||||||
} else if (key == "assignedTo") {
|
|
||||||
const user = await getUser(input.assignedTo);
|
|
||||||
if (!user) continue;
|
|
||||||
|
|
||||||
msg = `Assigned to ${user.firstName + " " + user.lastName}`;
|
|
||||||
} else {
|
} else {
|
||||||
msg = `Updated ${key} to '${input[key]}'`;
|
msg = `Updated ${key} to '${input[key]}'`;
|
||||||
}
|
}
|
||||||
@@ -86,23 +87,39 @@ export async function updateNotification(
|
|||||||
"notifications",
|
"notifications",
|
||||||
user
|
user
|
||||||
);
|
);
|
||||||
|
} else if (key == "assignedTo") {
|
||||||
|
const newAssignees = arrayDiff(
|
||||||
|
updateNotificationResult.assignedTo.map((item) => item._id),
|
||||||
|
oldNotification.assignedTo
|
||||||
|
);
|
||||||
|
|
||||||
|
if (newAssignees.length > 0) {
|
||||||
|
let msg = "Assigned to:\n\n";
|
||||||
|
|
||||||
|
for (const assignee of newAssignees) {
|
||||||
|
const user = await getUser(assignee);
|
||||||
|
if (!user) continue;
|
||||||
|
|
||||||
|
msg += `${user.firstName + " " + user.lastName}\n`;
|
||||||
|
|
||||||
|
await createAlert(
|
||||||
|
user.tenantId,
|
||||||
|
`You are assigned to ${updateNotificationResult.permitNumber}`,
|
||||||
|
"user",
|
||||||
|
assignee,
|
||||||
|
updateNotificationResult.pid,
|
||||||
|
"permits"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (key === "assignedTo") {
|
|
||||||
await createNote(
|
await createNote(
|
||||||
{ content: msg },
|
{
|
||||||
updateNotificationResult.permitId,
|
content: msg,
|
||||||
|
},
|
||||||
|
notifId,
|
||||||
"notifications",
|
"notifications",
|
||||||
user
|
user
|
||||||
);
|
);
|
||||||
|
|
||||||
await createAlert(
|
|
||||||
user.tenantId,
|
|
||||||
`You are assigned to ${updateNotificationResult.permitNumber}`,
|
|
||||||
"user",
|
|
||||||
input.assignedTo,
|
|
||||||
updateNotificationResult.permitId,
|
|
||||||
"permits"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -190,13 +207,14 @@ export async function listNotifications(
|
|||||||
updatedAt: 1,
|
updatedAt: 1,
|
||||||
taggedUsers: 1,
|
taggedUsers: 1,
|
||||||
assignedTo: {
|
assignedTo: {
|
||||||
$let: {
|
$map: {
|
||||||
vars: { assignedTo: { $arrayElemAt: ["$assignedTo", 0] } },
|
input: "$assignedTo",
|
||||||
|
as: "user",
|
||||||
in: {
|
in: {
|
||||||
_id: "$$assignedTo._id",
|
_id: "$$user._id",
|
||||||
pid: "$$assignedTo.pid",
|
pid: "$$user.pid",
|
||||||
name: "$$assignedTo.name",
|
name: "$$user.name",
|
||||||
avatar: "$$assignedTo.avatar",
|
avatar: "$$user.avatar",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ const permitCore = {
|
|||||||
recordId: z.string().optional(),
|
recordId: z.string().optional(),
|
||||||
relatedRecords: z
|
relatedRecords: z
|
||||||
.object({
|
.object({
|
||||||
custon_id: z.string(),
|
custom_id: z.string(),
|
||||||
relationship: z.string(),
|
relationship: z.string(),
|
||||||
type_text: z.string(),
|
type_text: z.string(),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import z from "zod";
|
import z from "zod";
|
||||||
import mongoose from "mongoose";
|
import mongoose, { Schema } from "mongoose";
|
||||||
import { pageQueryParams } from "../pagination";
|
import { pageQueryParams } from "../pagination";
|
||||||
import { buildJsonSchemas } from "fastify-zod";
|
import { buildJsonSchemas } from "fastify-zod";
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ const processedSchema = new mongoose.Schema({
|
|||||||
permitType: String,
|
permitType: String,
|
||||||
utility: String,
|
utility: String,
|
||||||
assignedTo: {
|
assignedTo: {
|
||||||
type: mongoose.Types.ObjectId,
|
type: [Schema.Types.ObjectId],
|
||||||
ref: "user",
|
ref: "user",
|
||||||
},
|
},
|
||||||
link: String,
|
link: String,
|
||||||
@@ -131,13 +131,13 @@ const updateProcessedInput = z.object({
|
|||||||
block: z.string().nullable().optional(),
|
block: z.string().nullable().optional(),
|
||||||
jobNumber: z.string().nullable().optional(),
|
jobNumber: z.string().nullable().optional(),
|
||||||
startDate: z.date().nullable().optional(),
|
startDate: z.date().nullable().optional(),
|
||||||
assignedTo: z.string().nullable().optional(),
|
assignedTo: z.array(z.string()).nullable().optional(),
|
||||||
noc: z.string().optional(),
|
noc: z.string().optional(),
|
||||||
deed: z.string().optional(),
|
deed: z.string().optional(),
|
||||||
requests: z.array(z.string()).optional(),
|
requests: z.array(z.string()).optional(),
|
||||||
relatedRecords: z
|
relatedRecords: z
|
||||||
.object({
|
.object({
|
||||||
custon_id: z.string(),
|
custom_id: z.string(),
|
||||||
relationship: z.string(),
|
relationship: z.string(),
|
||||||
type_text: z.string(),
|
type_text: z.string(),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import { createNote } from "../note/note.service";
|
|||||||
import { createAlert } from "../alert/alert.service";
|
import { createAlert } from "../alert/alert.service";
|
||||||
import { getUser } from "../user/user.service";
|
import { getUser } from "../user/user.service";
|
||||||
import { orgModel } from "../organization/organization.schema";
|
import { orgModel } from "../organization/organization.schema";
|
||||||
|
import { arrayDiff } from "../utils/diff";
|
||||||
|
|
||||||
export async function getProcessedPermit(
|
export async function getProcessedPermit(
|
||||||
permitId: String,
|
permitId: String,
|
||||||
@@ -38,6 +39,10 @@ export async function updateProcessed(
|
|||||||
permitId: string,
|
permitId: string,
|
||||||
user: AuthenticatedUser
|
user: AuthenticatedUser
|
||||||
) {
|
) {
|
||||||
|
const oldPermitResult = await processedModel.findOne(
|
||||||
|
{ pid: permitId },
|
||||||
|
{ assignedTo: 1 }
|
||||||
|
);
|
||||||
const updateProcessedResult = await processedModel
|
const updateProcessedResult = await processedModel
|
||||||
.findOneAndUpdate(
|
.findOneAndUpdate(
|
||||||
{
|
{
|
||||||
@@ -52,16 +57,11 @@ export async function updateProcessed(
|
|||||||
|
|
||||||
if (updateProcessedResult) {
|
if (updateProcessedResult) {
|
||||||
for (const key in input) {
|
for (const key in input) {
|
||||||
if (["manualStatus", "utility", "assignedTo"].includes(key)) {
|
if (["manualStatus", "utility"].includes(key)) {
|
||||||
let msg = "";
|
let msg = "";
|
||||||
|
|
||||||
if (input[key] === null) {
|
if (input[key] === null) {
|
||||||
msg = `Cleared ${key}`;
|
msg = `Cleared ${key}`;
|
||||||
} else if (key == "assignedTo") {
|
|
||||||
const user = await getUser(input.assignedTo);
|
|
||||||
if (!user) continue;
|
|
||||||
|
|
||||||
msg = `Assigned to ${user.firstName + " " + user.lastName}`;
|
|
||||||
} else {
|
} else {
|
||||||
msg = `Updated ${key} to '${input[key]}'`;
|
msg = `Updated ${key} to '${input[key]}'`;
|
||||||
}
|
}
|
||||||
@@ -74,17 +74,6 @@ export async function updateProcessed(
|
|||||||
"processed",
|
"processed",
|
||||||
user
|
user
|
||||||
);
|
);
|
||||||
|
|
||||||
if (key == "assignedTo" && input[key] != null) {
|
|
||||||
await createAlert(
|
|
||||||
user.tenantId,
|
|
||||||
`You are assigned to ${updateProcessedResult.permitNumber}`,
|
|
||||||
"user",
|
|
||||||
input.assignedTo,
|
|
||||||
updateProcessedResult.pid,
|
|
||||||
"processed"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else if (key == "client") {
|
} else if (key == "client") {
|
||||||
const orgInDb = await orgModel.findById(input.client);
|
const orgInDb = await orgModel.findById(input.client);
|
||||||
if (orgInDb) {
|
if (orgInDb) {
|
||||||
@@ -98,6 +87,40 @@ export async function updateProcessed(
|
|||||||
updateProcessedResult.markModified("clientData");
|
updateProcessedResult.markModified("clientData");
|
||||||
await updateProcessedResult.save();
|
await updateProcessedResult.save();
|
||||||
}
|
}
|
||||||
|
} else if (key == "assignedTo") {
|
||||||
|
const newAssignees = arrayDiff(
|
||||||
|
updateProcessedResult.assignedTo.map((item) => item._id),
|
||||||
|
oldPermitResult.assignedTo
|
||||||
|
);
|
||||||
|
|
||||||
|
if (newAssignees.length == 0) continue;
|
||||||
|
|
||||||
|
let msg = "Assigned to:\n\n";
|
||||||
|
|
||||||
|
for (const assignee of newAssignees) {
|
||||||
|
const user = await getUser(assignee);
|
||||||
|
if (!user) continue;
|
||||||
|
|
||||||
|
msg += `${user.firstName + " " + user.lastName}\n`;
|
||||||
|
|
||||||
|
await createAlert(
|
||||||
|
user.tenantId,
|
||||||
|
`You are assigned to ${updateProcessedResult.permitNumber}`,
|
||||||
|
"user",
|
||||||
|
assignee,
|
||||||
|
updateProcessedResult.pid,
|
||||||
|
"processed"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await createNote(
|
||||||
|
{
|
||||||
|
content: msg,
|
||||||
|
},
|
||||||
|
permitId,
|
||||||
|
"processed",
|
||||||
|
user
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,7 +175,7 @@ export async function listProcessedPermits(
|
|||||||
from: "users",
|
from: "users",
|
||||||
localField: "assignedTo",
|
localField: "assignedTo",
|
||||||
foreignField: "_id",
|
foreignField: "_id",
|
||||||
as: "assignedRec",
|
as: "assignedTo",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -205,13 +228,14 @@ export async function listProcessedPermits(
|
|||||||
deed: 1,
|
deed: 1,
|
||||||
requests: 1,
|
requests: 1,
|
||||||
assignedTo: {
|
assignedTo: {
|
||||||
$let: {
|
$map: {
|
||||||
vars: { assigned: { $arrayElemAt: ["$assignedRec", 0] } },
|
input: "$assignedTo",
|
||||||
|
as: "user",
|
||||||
in: {
|
in: {
|
||||||
_id: "$$assigned._id",
|
_id: "$$user._id",
|
||||||
pid: "$$assigned.pid",
|
pid: "$$user.pid",
|
||||||
name: "$$assigned.name",
|
name: "$$user.name",
|
||||||
avatar: "$$assigned.avatar",
|
avatar: "$$user.avatar",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { buildJsonSchemas } from "fastify-zod";
|
import { buildJsonSchemas } from "fastify-zod";
|
||||||
import mongoose from "mongoose";
|
import mongoose, { Schema } from "mongoose";
|
||||||
import z from "zod";
|
import z from "zod";
|
||||||
import { files } from "../file/file.schema";
|
import { files } from "../file/file.schema";
|
||||||
import { pageQueryParams } from "../pagination";
|
import { pageQueryParams } from "../pagination";
|
||||||
@@ -51,7 +51,7 @@ const rtsSchema = new mongoose.Schema({
|
|||||||
ref: "user",
|
ref: "user",
|
||||||
},
|
},
|
||||||
assignedTo: {
|
assignedTo: {
|
||||||
type: mongoose.Types.ObjectId,
|
type: [Schema.Types.ObjectId],
|
||||||
ref: "user",
|
ref: "user",
|
||||||
},
|
},
|
||||||
taggedUsers: Array,
|
taggedUsers: Array,
|
||||||
@@ -85,7 +85,7 @@ const rtsCreateInput = z.object({
|
|||||||
currentStage: z.number(),
|
currentStage: z.number(),
|
||||||
})
|
})
|
||||||
.optional(),
|
.optional(),
|
||||||
assignedTo: z.string().optional(),
|
assignedTo: z.array(z.string()).optional(),
|
||||||
status: z.string().optional(),
|
status: z.string().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ const rtsUpdateInput = z.object({
|
|||||||
currentStage: z.number(),
|
currentStage: z.number(),
|
||||||
})
|
})
|
||||||
.optional(),
|
.optional(),
|
||||||
assignedTo: z.string().optional(),
|
assignedTo: z.array(z.string()).optional(),
|
||||||
status: z.string().optional(),
|
status: z.string().optional(),
|
||||||
fileValidationStatus: z.string().optional(),
|
fileValidationStatus: z.string().optional(),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -13,11 +13,12 @@ import {
|
|||||||
getTaggedUsersFilter,
|
getTaggedUsersFilter,
|
||||||
PageQueryParams,
|
PageQueryParams,
|
||||||
} from "../pagination";
|
} from "../pagination";
|
||||||
import { getUserWithoutPopulate } from "../user/user.service";
|
import { getUser, getUserWithoutPopulate } from "../user/user.service";
|
||||||
import mongoose from "mongoose";
|
import mongoose from "mongoose";
|
||||||
import { rtsPipeline } from "../utils/pipeline";
|
import { rtsPipeline } from "../utils/pipeline";
|
||||||
import { createAlert } from "../alert/alert.service";
|
import { createAlert } from "../alert/alert.service";
|
||||||
import { createNote } from "../note/note.service";
|
import { createNote } from "../note/note.service";
|
||||||
|
import { arrayDiff } from "../utils/diff";
|
||||||
|
|
||||||
export async function createRts(
|
export async function createRts(
|
||||||
input: CreateRtsInput,
|
input: CreateRtsInput,
|
||||||
@@ -126,7 +127,7 @@ export async function listRts(
|
|||||||
from: "users",
|
from: "users",
|
||||||
localField: "assignedTo",
|
localField: "assignedTo",
|
||||||
foreignField: "_id",
|
foreignField: "_id",
|
||||||
as: "assignedToRec",
|
as: "assignedTo",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -180,13 +181,14 @@ export async function listRts(
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
assignedTo: {
|
assignedTo: {
|
||||||
$let: {
|
$map: {
|
||||||
vars: { assignedTo: { $arrayElemAt: ["$assignedToRec", 0] } },
|
input: "$assignedTo",
|
||||||
|
as: "user",
|
||||||
in: {
|
in: {
|
||||||
_id: "$$assignedTo._id",
|
_id: "$$user._id",
|
||||||
pid: "$$assignedTo.pid",
|
pid: "$$user.pid",
|
||||||
name: "$$assignedTo.name",
|
name: "$$user.name",
|
||||||
avatar: "$$assignedTo.avatar",
|
avatar: "$$user.avatar",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -222,6 +224,7 @@ export async function updateRts(
|
|||||||
input: UpdateRtsInput,
|
input: UpdateRtsInput,
|
||||||
user: AuthenticatedUser
|
user: AuthenticatedUser
|
||||||
) {
|
) {
|
||||||
|
const oldRts = await rtsModel.findOne({ pid: id }, { assignedTo: 1 });
|
||||||
const updatedRts = await rtsModel
|
const updatedRts = await rtsModel
|
||||||
.findOneAndUpdate({ pid: id, tenantId: user.tenantId }, input, {
|
.findOneAndUpdate({ pid: id, tenantId: user.tenantId }, input, {
|
||||||
new: true,
|
new: true,
|
||||||
@@ -241,14 +244,39 @@ export async function updateRts(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (updatedRts && input.assignedTo) {
|
if (updatedRts && input.assignedTo) {
|
||||||
await createAlert(
|
const newAssignees = arrayDiff(
|
||||||
user.tenantId,
|
updatedRts.assignedTo.map((item) => item._id),
|
||||||
`You are assigned to RTS`,
|
oldRts.assignedTo
|
||||||
"user",
|
|
||||||
input.assignedTo,
|
|
||||||
updatedRts.pid,
|
|
||||||
"rts"
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (newAssignees.length > 0) {
|
||||||
|
let msg = "Assigned to:\n\n";
|
||||||
|
|
||||||
|
for (const assignee of newAssignees) {
|
||||||
|
const user = await getUser(assignee);
|
||||||
|
if (!user) continue;
|
||||||
|
|
||||||
|
msg += `${user.firstName + " " + user.lastName}\n`;
|
||||||
|
|
||||||
|
await createAlert(
|
||||||
|
user.tenantId,
|
||||||
|
`You are assigned to RTS`,
|
||||||
|
"user",
|
||||||
|
assignee,
|
||||||
|
updatedRts.pid,
|
||||||
|
"rts"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await createNote(
|
||||||
|
{
|
||||||
|
content: msg,
|
||||||
|
},
|
||||||
|
id,
|
||||||
|
"rts",
|
||||||
|
user
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return updatedRts;
|
return updatedRts;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import mongoose from "mongoose";
|
import mongoose, { Schema } from "mongoose";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { files } from "../file/file.schema";
|
import { files } from "../file/file.schema";
|
||||||
import { buildJsonSchemas } from "fastify-zod";
|
import { buildJsonSchemas } from "fastify-zod";
|
||||||
@@ -37,7 +37,7 @@ const taskSchema = new mongoose.Schema({
|
|||||||
ref: "user",
|
ref: "user",
|
||||||
},
|
},
|
||||||
assignedTo: {
|
assignedTo: {
|
||||||
type: mongoose.Types.ObjectId,
|
type: [Schema.Types.ObjectId],
|
||||||
ref: "user",
|
ref: "user",
|
||||||
},
|
},
|
||||||
taggedUsers: Array,
|
taggedUsers: Array,
|
||||||
@@ -53,7 +53,7 @@ const createTaskInput = z.object({
|
|||||||
title: z.string(),
|
title: z.string(),
|
||||||
dueDate: z.date().optional(),
|
dueDate: z.date().optional(),
|
||||||
files: z.array(files).optional(),
|
files: z.array(files).optional(),
|
||||||
assignedTo: z.string().optional(),
|
assignedTo: z.array(z.string()).optional(),
|
||||||
labels: z.array(z.string()).optional(),
|
labels: z.array(z.string()).optional(),
|
||||||
priority: z.string().optional(),
|
priority: z.string().optional(),
|
||||||
stage: z
|
stage: z
|
||||||
@@ -76,7 +76,7 @@ const updateTaskInput = z.object({
|
|||||||
title: z.string().optional(),
|
title: z.string().optional(),
|
||||||
dueDate: z.date().optional(),
|
dueDate: z.date().optional(),
|
||||||
files: z.array(files).optional(),
|
files: z.array(files).optional(),
|
||||||
assignedTo: z.string().optional(),
|
assignedTo: z.array(z.string()).optional(),
|
||||||
labels: z.array(z.string()).optional(),
|
labels: z.array(z.string()).optional(),
|
||||||
priority: z.string().optional(),
|
priority: z.string().optional(),
|
||||||
stage: z
|
stage: z
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
getTaggedUsersFilter,
|
getTaggedUsersFilter,
|
||||||
PageQueryParams,
|
PageQueryParams,
|
||||||
} from "../pagination";
|
} from "../pagination";
|
||||||
|
import { arrayDiff } from "../utils/diff";
|
||||||
import { generateId } from "../utils/id";
|
import { generateId } from "../utils/id";
|
||||||
import { taskPipeline } from "../utils/pipeline";
|
import { taskPipeline } from "../utils/pipeline";
|
||||||
import {
|
import {
|
||||||
@@ -58,6 +59,7 @@ export async function updateTask(
|
|||||||
input: UpdateTaskInput,
|
input: UpdateTaskInput,
|
||||||
user: AuthenticatedUser
|
user: AuthenticatedUser
|
||||||
) {
|
) {
|
||||||
|
const oldTask = await taskModel.findOne({ pid: taskId }, { assignedTo: 1 });
|
||||||
const updatedTask = await taskModel
|
const updatedTask = await taskModel
|
||||||
.findOneAndUpdate({ tenantId: user.tenantId, pid: taskId }, input, {
|
.findOneAndUpdate({ tenantId: user.tenantId, pid: taskId }, input, {
|
||||||
new: true,
|
new: true,
|
||||||
@@ -66,14 +68,23 @@ export async function updateTask(
|
|||||||
.populate({ path: "assignedTo", select: "pid name avatar" });
|
.populate({ path: "assignedTo", select: "pid name avatar" });
|
||||||
|
|
||||||
if (updatedTask && input.assignedTo) {
|
if (updatedTask && input.assignedTo) {
|
||||||
await createAlert(
|
const newAssignees = arrayDiff(
|
||||||
user.tenantId,
|
updatedTask.assignedTo.map((item) => item._id),
|
||||||
`You are assigned to ${updatedTask.title}`,
|
oldTask.assignedTo
|
||||||
"user",
|
|
||||||
input.assignedTo,
|
|
||||||
updatedTask.pid,
|
|
||||||
"tasks"
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (newAssignees.length > 0) {
|
||||||
|
for (const assignee of newAssignees) {
|
||||||
|
await createAlert(
|
||||||
|
user.tenantId,
|
||||||
|
`You are assigned to ${updatedTask.title}`,
|
||||||
|
"user",
|
||||||
|
assignee,
|
||||||
|
updatedTask.pid,
|
||||||
|
"tasks"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return updatedTask;
|
return updatedTask;
|
||||||
@@ -146,12 +157,14 @@ export async function listTasks(
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
assignedTo: {
|
assignedTo: {
|
||||||
$let: {
|
$map: {
|
||||||
vars: { assignedTo: { $arrayElemAt: ["$assignedTo", 0] } },
|
input: "$assignedTo",
|
||||||
|
as: "user",
|
||||||
in: {
|
in: {
|
||||||
_id: "$$assignedTo._id",
|
_id: "$$user._id",
|
||||||
pid: "$$assignedTo.pid",
|
pid: "$$user.pid",
|
||||||
name: "$$assignedTo.name",
|
name: "$$user.name",
|
||||||
|
avatar: "$$user.avatar",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user