import { CreateRtsInput, rtsFields, rtsModel, UpdateRtsInput, UploadRtsInput, } from "./rts.schema"; import { AuthenticatedUser } from "../auth"; import { generateId } from "../utils/id"; import { getFilterObject, getSortObject, PageQueryParams } from "../pagination"; import { getUser } from "../user/user.service"; import { orgModel } from "../organization/organization.schema"; import { userModel } from "../user/user.schema"; import mongoose from "mongoose"; export async function createRts( input: CreateRtsInput, user: AuthenticatedUser ) { let defaultClient = input.client; const userInDb = await getUser(user.userId); if (userInDb && userInDb.orgId) { defaultClient = userInDb.orgId.toString(); } return await rtsModel.create({ ...input, tenantId: user.tenantId, pid: generateId(), client: defaultClient, createdAt: new Date(), createdBy: user.userId ?? null, }); } export async function getRts(id: string, tenantId: string) { return await rtsModel .findOne({ pid: id, tenantId: tenantId }) .populate({ path: "county", select: "pid name avatar" }) .populate({ path: "client", select: "pid name avatar" }) .populate({ path: "createdBy", select: "pid name avatar" }) .populate({ path: "assignedTo", select: "pid name avatar" }); } export async function listRts( params: PageQueryParams, user: AuthenticatedUser ) { const page = params.page || 1; const pageSize = params.pageSize || 10; const sortObj = getSortObject(params, rtsFields); const filterObj = getFilterObject(params) || []; if (user.role === "client") { filterObj.push({ client: new mongoose.Types.ObjectId(user.orgId) }); } const rtsList = await rtsModel.aggregate([ { $match: { $and: [{ tenantId: user.tenantId }, ...filterObj] }, }, { $lookup: { from: "organizations", localField: "county", foreignField: "_id", as: "countyRec", }, }, { $lookup: { from: "organizations", localField: "client", foreignField: "_id", as: "clientRec", }, }, { $lookup: { from: "users", localField: "createdBy", foreignField: "_id", as: "createdRec", }, }, { $lookup: { from: "users", localField: "assignedTo", foreignField: "_id", as: "assignedToRec", }, }, { $project: { _id: 1, pid: 1, permitType: 1, documents: 1, statusPipeline: 1, createdAt: 1, county: { $let: { vars: { county: { $arrayElemAt: ["$countyRec", 0] } }, in: { _id: "$$county._id", pid: "$$county.pid", name: "$$county.name", type: "$$county.type", avatar: "$$county.avatar", }, }, }, client: { $let: { vars: { client: { $arrayElemAt: ["$clientRec", 0] } }, in: { _id: "$$client._id", pid: "$$client.pid", name: "$$client.name", type: "$$client.type", avatar: "$$client.avatar", }, }, }, createdBy: { $let: { vars: { created: { $arrayElemAt: ["$createdRec", 0] } }, in: { _id: "$$created._id", pid: "$$created.pid", name: "$$created.name", avatar: "$$created.avatar", }, }, }, assignedTo: { $let: { vars: { assignedTo: { $arrayElemAt: ["$assignedToRec", 0] } }, in: { _id: "$$assignedTo._id", pid: "$$assignedTo.pid", name: "$$assignedTo.name", avatar: "$$assignedTo.avatar", }, }, }, }, }, { $facet: { metadata: [{ $count: "count" }], data: [ { $sort: sortObj }, { $skip: (page - 1) * pageSize }, { $limit: pageSize }, ], }, }, ]); if (rtsList[0].data.length === 0) return { rts: [], metadata: { count: 0, page, pageSize } }; return { rts: rtsList[0]?.data, metadata: { count: rtsList[0].metadata[0].count, page, pageSize, }, }; } export async function updateRts( id: string, input: UpdateRtsInput, tenantId: string ) { const updatedRts = await rtsModel .findOneAndUpdate({ pid: id, tenantId: tenantId }, input, { new: true }) .populate({ path: "createdBy", select: "pid name avatar" }) .populate({ path: "county", select: "pid name avatar" }) .populate({ path: "client", select: "pid name avatar" }) .populate({ path: "assignedTo", select: "pid name avatar" }); return updatedRts; } export async function deleteRts(id: string, tenantId: string) { return await rtsModel.deleteOne({ pid: id, tenantId: tenantId }); } export async function newUpload( id: string, newUpload: UploadRtsInput, user: AuthenticatedUser ) { return await rtsModel.findOneAndUpdate( { pid: id, tenantId: user.tenantId }, { $push: { documents: { files: newUpload.files, createdAt: new Date(), createdBy: user.userId, }, }, } ); } export async function getUniqueValuesRTS(field: string, tenenatId: string) { let values = await rtsModel.distinct(field, { tenantId: tenenatId }); let matchedValues = []; if (field === "county") { matchedValues = await orgModel.find().where("_id").in(values).exec(); } else if (field === "client") { matchedValues = await orgModel.find().where("_id").in(values).exec(); } else if (field === "createdBy") { matchedValues = await userModel.find().where("_id").in(values).exec(); } else if (field === "assignedTo") { matchedValues = await userModel.find().where("_id").in(values).exec(); } if (matchedValues.length > 0) { const newValues = {}; for (const item of matchedValues) { newValues[item.id] = item.name; } return newValues; } return values; }