@openinc/parse-server-opendash
Version:
Parse Server Cloud Code for open.INC Stack.
353 lines (352 loc) • 12.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.init = init;
exports.getTicketMaterial = getTicketMaterial;
exports.getTicketSource = getTicketSource;
exports.arrayToDistinct = arrayToDistinct;
const catchError_1 = require("../helper/catchError");
const types_1 = require("../types");
async function init(name) {
Parse.Cloud.define(name, handleRequest, {
requireUser: true,
});
}
async function handleRequest(request) {
if (request.user === undefined) {
return { success: false, error: "User not found" };
}
console.log("openinc-openservice-ticket-data: Handling request with", request.params);
try {
const queries = [];
for await (const config of request.params.config) {
let ticketQuery = new Parse.Query(types_1.Maintenance_Ticket)
.equalTo("enabled", true)
.includeAll();
// apply filters defined in the filterQueryMap depending on the request
if (config.filterBy?.filter.length) {
const filterQueries = [];
for await (const filter of config.filterBy.filter) {
const query = new Parse.Query(types_1.Maintenance_Ticket).equalTo("enabled", true);
await filterQueryMap[filter.attribute](query, filter.value);
filterQueries.push(query);
}
if (config.filterBy.junction === "or") {
ticketQuery = Parse.Query.or(...filterQueries);
}
else {
ticketQuery = Parse.Query.and(...filterQueries);
}
}
queries.push(ticketQuery);
}
let ticketQuery = request.params.junction === "or"
? Parse.Query.or(...queries)
: Parse.Query.and(...queries);
if (request.params.config[0].sortBy && request.params.config[0].order) {
ticketQuery = ticketQuery.includeAll();
if (request.params.config[0].order === "asc") {
ticketQuery = ticketQuery.ascending(request.params.config[0].sortBy);
}
else {
ticketQuery = ticketQuery.descending(request.params.config[0].sortBy);
}
}
// get total count of tickets before applying pagination
const totalCount = await ticketQuery.count({
sessionToken: request.user.getSessionToken(),
});
if (request.params.config[0].skip !== undefined &&
request.params.config[0].limit !== undefined) {
ticketQuery = ticketQuery
.skip(request.params.config[0].skip)
.limit(request.params.config[0].limit);
}
const [ticketError, ticketsResult] = await (0, catchError_1.catchError)(ticketQuery.find({ sessionToken: request.user.getSessionToken() }));
if (ticketError) {
throw ticketError;
}
// fetch ticket data for those tickets
const ticketData = await getTicketData(ticketsResult);
return {
success: true,
data: ticketData,
total: totalCount,
};
}
catch (error) {
console.error("Error while fetching ticket data", error);
return {
success: false,
error: error,
};
}
}
async function getTicketData(tickets) {
const ticketDataPromises = tickets.map(async (ticket) => {
let assignedusers = [];
let assignedroles = [];
if (ticket.assignedusers !== undefined) {
assignedusers = await ticket.assignedusers
.query()
.find({ useMasterKey: true });
}
if (ticket.assignedroles !== undefined) {
assignedroles = await ticket.assignedroles
.query()
.find({ useMasterKey: true });
}
const downtimes = getDowntime(ticket);
const duedate = getDueDate(ticket);
const frequency = getFrequency(ticket);
const restriction = getRestriction(ticket);
const issuecategory = getIssueCategory(ticket);
const priority = getPriority(ticket);
const source = getTicketSource(ticket);
const state = getState(ticket);
const messages = getMessages(ticket);
const material = getTicketMaterial(ticket);
const project = (0, catchError_1.catchError)(ticket.get("project")?.fetch({ useMasterKey: true }) ??
new Promise((res) => res(undefined)));
const dataPromises = await Promise.all([
downtimes,
duedate,
frequency,
restriction,
issuecategory,
priority,
source,
state,
messages,
material,
project,
]);
return {
ticket: ticket,
downtime: dataPromises[0],
duedate: dataPromises[1],
frequency: dataPromises[2],
restriction: dataPromises[3],
issuecategory: dataPromises[4]?.get("issuecategory"),
priority: dataPromises[5],
source: dataPromises[6]?.get("source"),
state: dataPromises[7]?.get("state"),
messages: dataPromises[8]?.messages,
todos: dataPromises[8]?.todos,
assignedTo: [...assignedusers, ...assignedroles],
material: dataPromises[9],
project: dataPromises[10]?.[1],
};
});
return await Promise.all(ticketDataPromises);
}
/**
* Fetches the downtime for a ticket
* @param ticket
* @param ticketIds
* @returns
*/
async function getDowntime(ticket) {
return await new Parse.Query(types_1.Maintenance_Downtime)
.descending("updatedAt")
.equalTo("ticket", ticket)
// .containedIn("ticket", ticketIds)
// .limit(1_000_000)
.first({ useMasterKey: true });
// .filter((downtime) => downtime.get("ticket").id === ticket.id, {
// useMasterKey: true,
// });
}
/**
* Fetches the duedate for a ticket
* @param ticket
* @param ticketIds
* @returns
*/
async function getDueDate(ticket) {
return await new Parse.Query(types_1.Maintenance_Duedate)
.descending("updatedAt")
.equalTo("ticket", ticket)
.first({ useMasterKey: true });
}
/**
* Fetches the frequency for a ticket
* @param ticket
* @param ticketIds
*/
async function getFrequency(ticket) {
return await new Parse.Query(types_1.Maintenance_Frequency)
.descending("updatedAt")
.equalTo("ticket", ticket)
.first({ useMasterKey: true });
}
/**
* Fetches the restriction for a ticket
* @param ticket
* @param ticketIds
*/
async function getRestriction(ticket) {
return await new Parse.Query(types_1.Maintenance_Restriction)
.descending("updatedAt")
.equalTo("ticket", ticket)
.first({ useMasterKey: true });
}
/**
* Fetches the priority for a ticket
* @param ticket
* @param ticketIds
* @returns
*/
async function getPriority(ticket) {
return await new Parse.Query(types_1.Maintenance_Priority)
.descending("updatedAt")
.equalTo("ticket", ticket)
.equalTo("ticket", ticket)
.first({ useMasterKey: true });
}
/**
* Fetches the state for a ticket
* @param ticket
* @param ticketIds
*/
async function getState(ticket) {
return await new Parse.Query(types_1.Maintenance_Ticket_Kanban_State_Current)
.descending("updatedAt")
.includeAll()
.matchesQuery("ticket", new Parse.Query(types_1.Maintenance_Ticket).equalTo("objectId", ticket.id))
.first({ useMasterKey: true });
}
/**
* Fetches the messages for a ticket
* @param ticket
* @param ticketIds
*/
async function getMessages(ticket) {
const allMessages = await new Parse.Query(types_1.Maintenance_Message)
.descending("updatedAt")
.equalTo("referencedObjectId", ticket.id)
.find({ useMasterKey: true });
const messages = [];
const todos = [];
for (const msg of allMessages) {
if (!msg.data)
continue;
if (msg.data.type !== "todo") {
messages.push(msg);
continue;
}
todos.push(msg);
}
return { messages, todos };
}
/**
* Fetches the issuecategory for a ticket
* @param ticket
* @param ticketIds
* @returns
*/
async function getIssueCategory(ticket) {
return await new Parse.Query(types_1.Maintenance_Ticket_Issuecategory)
.includeAll()
.descending("updatedAt")
.equalTo("ticket", ticket)
.first({ useMasterKey: true });
}
/**
* Fetches the material for a ticket
* @param ticket
*/
async function getTicketMaterial(ticket) {
return await new Parse.Query(types_1.Maintenance_Ticket_Material)
.includeAll()
.descending("updatedAt")
.equalTo("ticket", ticket)
.first({ useMasterKey: true });
}
/**
* Fetches the source for a ticket
* @param ticket
*/
async function getTicketSource(ticket) {
return await new Parse.Query(types_1.Maintenance_Ticket_Source)
.includeAll()
.descending("updatedAt")
.equalTo("ticket", ticket)
.first({ useMasterKey: true });
}
/**
* Used to filter tickets based on the filterBy attribute
*/
const filterQueryMap = {
objectId: async (query, value) => {
query.equalTo("objectId", value);
},
state: async (query, value) => {
const stateQuery = new Parse.Query(types_1.Maintenance_Ticket_Kanban_State_Current).equalTo("state", new types_1.Maintenance_Kanban_State({ objectId: value }));
// @ts-ignore
query.matchesKeyInQuery("objectId", "ticket.objectId", stateQuery);
},
source: async (query, value) => {
const allTicketSources = await new Parse.Query(types_1.Maintenance_Ticket_Source)
.descending("createdAt")
.matchesQuery("ticket", query)
.includeAll()
.find({ useMasterKey: true });
const filteredTicketSources = arrayToDistinct(allTicketSources, (ts) => ts?.get("ticket")?.id, (ts) => ts?.get("source")?.id === value);
// @ts-ignore
query.containedIn("objectId", filteredTicketSources.map((ts) => ts.get("ticket")?.id));
},
issuecategory: async (query, value) => {
const ticketIssuecategories = await new Parse.Query(types_1.Maintenance_Ticket_Issuecategory)
.matchesQuery("ticket", query)
.descending("createdAt")
.includeAll()
.find({ useMasterKey: true });
const filteredTicketIssuecategories = arrayToDistinct(ticketIssuecategories, (tic) => tic.get("ticket")?.id, (tic) => tic.get("issuecategory")?.id === value &&
tic.get("ticket")?.id !== undefined);
// @ts-ignore
query.containedIn("objectId", filteredTicketIssuecategories.map((tic) => tic.get("ticket")?.id));
},
user: async (query, value) => {
const userQuery = new Parse.Query(Parse.User).equalTo("objectId", value);
query.matchesQuery("assignedusers", userQuery);
},
role: async (query, value) => {
const roleQuery = new Parse.Query(Parse.Role).equalTo("objectId", value);
query.include("assignedroles").matchesQuery("assignedroles", roleQuery);
},
userRole: async (query, value) => {
const userQuery = new Parse.Query(Parse.User).equalTo("objectId", value);
const roleQuery = new Parse.Query(Parse.Role)
.include("users")
.matchesQuery("users", userQuery);
query.include("assignedroles").matchesQuery("assignedroles", roleQuery);
},
createdUser: async (query, value) => {
query.include("user");
query.equalTo("user", new Parse.User({ objectId: value }));
},
project: async (query, value) => {
query.include("project");
query.equalTo("project", new types_1.Maintenance_Project({ objectId: value }));
},
title: async (query, value) => {
query.matches("title", new RegExp(value, "i")); // case-insensitive match
},
};
/**
* Creates a distinct array based on the getId function and can afterwards filter the array
* @param arr the array to get distinct values from
* @param getId the identifier function to get the id of the item
* @param filter the filter function to filter the array afterwards
* @returns an array with distinct values based on the getId function
*/
function arrayToDistinct(arr, getId, filter) {
const map = new Map();
arr.forEach((item) => {
if (map.has(getId(item)))
return;
map.set(getId(item), item);
});
const array = Array.from(map.values());
return filter ? array.filter(filter) : array;
}