@openinc/parse-server-opendash
Version:
Parse Server Cloud Code for open.INC Stack.
456 lines (455 loc) • 21.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.sanatizeMessagesDisplayAt = sanatizeMessagesDisplayAt;
exports.initializeMessages = initializeMessages;
const openinc_openservice_save_ticket_data_1 = require("../../../functions/openinc-openservice-save-ticket-data");
const Maintenance_Ticket_Material_1 = require("../../../hooks/Maintenance_Ticket_Material");
const types_1 = require("../../../types");
const OpenserviceTranslationKeys_1 = require("../types/OpenserviceTranslationKeys");
async function sanatizeMessagesDisplayAt() {
await new Parse.Query(types_1.Maintenance_Message).each(async (message) => {
if (!message.get("displayAt")) {
message.set("displayAt", message.get("createdAt"));
await message.save(null, { useMasterKey: true });
}
}, { useMasterKey: true });
}
/**
* Initializes the messages if there are no messages in the database
*/
async function initializeMessages() {
const count = await new Parse.Query(types_1.Maintenance_Message)
// we only handle system messages, not user messages
// @ts-ignore
.equalTo("data.type", "system")
.count({
useMasterKey: true,
});
if (count !== 0)
return;
console.log("Initializing maintenance messages");
await convertTicketDataToMessages();
await convertScheduleExecutionToMessage();
await sanatizeMessagesDisplayAt();
console.log("Initializing messages is finished");
}
async function convertTicketDataToMessages() {
// we get all ticket sources and convert them to messages
// important for the machinelog is, that all other ticket data should be converted to messages
// pointing to the source that was assigned to the ticket at that time
const ticketSources = await new Parse.Query(types_1.Maintenance_Ticket_Source)
.limit(1000000)
.includeAll()
.ascending("createdAt")
.find({ useMasterKey: true });
// we create the sources as messages and save them
// we also create a time frame for the sources in wich that source was assigned to the ticket
const timeMap = convertSourcesToTimeMap(ticketSources);
// we handle source different than the other data
// we need to create a message for the source that was assigned to the ticket and already fetched the sources here
await convertSourcesToMessages(ticketSources);
await ticketStateToMessage(timeMap);
await ticketIssuecategoryToMessage(timeMap);
await ticketPriorityToMessage(timeMap);
await ticketRestrictionToMessage(timeMap);
await ticketDowntimeToMessage(timeMap);
await ticketFrequencyToMessage(timeMap);
await ticketDuedateToMessage(timeMap);
await ticketTitleToMessage(timeMap);
await ticketMaterialToMessage(timeMap);
await ticketProjectToMessage(timeMap);
}
async function convertToMessage(config) {
const entries = await new Parse.Query(config.className)
.limit(1000000)
.includeAll()
.ascending("createdAt")
.find({ useMasterKey: true });
const messages = [];
for (const index in entries) {
const entry = entries[index];
const previous = entries[Number.parseInt(index) - 1];
// check if ticket entry is valid, might be corrupted
if (!config.isValueValid(entry) ||
!entry.get("ticket") ||
(previous && (!config.isValueValid(previous) || !previous.get("ticket"))))
continue;
const source = getSourceForTime(config.timeMap, entry.get("ticket").id, entry.get("createdAt"));
const message = new types_1.Maintenance_Message({
title: config.ticketTranslation.TITLE,
content: config.ticketTranslation.CONTENT,
referencedObjectId: entry.get("ticket").id,
classname: entry.get("ticket").className,
displayAt: entry.get("createdAt"),
data: {
type: "system",
origin: {
id: entry.id,
classname: entry.className,
},
translation: {
username: (0, openinc_openservice_save_ticket_data_1.getUsername)(entry.get("user")),
ticketName: entry.get("ticket").get("title"),
...config.getTranslationData(entry, previous),
},
},
user: entry.get("user"),
tenant: entry.get("tenant"),
});
messages.push(message);
if (source) {
const machinelogMessage = new types_1.Maintenance_Message({
title: config.machinelogTranslation.TITLE,
content: config.machinelogTranslation.CONTENT,
referencedObjectId: source.id,
classname: source.className,
displayAt: entry.get("createdAt"),
data: {
type: "system",
origin: {
id: entry.get("ticket").id,
classname: entry.get("ticket").className,
},
translation: {
username: (0, openinc_openservice_save_ticket_data_1.getUsername)(entry.get("user")),
ticketName: entry.get("ticket").get("title"),
...config.getTranslationData(entry),
},
},
user: entry.get("user"),
tenant: entry.get("tenant"),
});
messages.push(machinelogMessage);
}
}
await types_1.Maintenance_Message.saveAll(messages, { useMasterKey: true });
}
/**
* Creates a time map from the given ticket sources wich maps the ticket id to the different sources and their createdAt dates
* @param ticketSources the ticket sources from wich the time map sould be created
* @returns a map with the ticket id as key and the different sources and their createdAt dates as value
*/
function convertSourcesToTimeMap(ticketSources) {
// we create a map with the ticket id as key and the different createdAt dates as value
const timeFrameMap = new Map();
for (const ticketSource of ticketSources) {
const ticketId = ticketSource.get("ticket").id;
if (!timeFrameMap.has(ticketId)) {
timeFrameMap.set(ticketId, [
{
source: ticketSource.get("source"),
date: ticketSource.get("createdAt"),
},
]);
}
else {
timeFrameMap.get(ticketId).push({
source: ticketSource.get("source"),
date: ticketSource.get("createdAt"),
});
}
}
return timeFrameMap;
}
/**
* Returns the source that was assigned to the ticket with the given ID at the given time
* @param timeMap the time map that should be used
* @param ticketId id of the ticket
* @param time the date for which the source should be returned
* @returns the source that was assigned to the ticket at the given time
*/
function getSourceForTime(timeMap, ticketId, time) {
const ticketTimes = timeMap.get(ticketId);
if (!ticketTimes)
return null;
let currentSource = null;
// the sources are sorted by date, so we can just iterate over them and take the last one that is smaller than the given time
for (const ticketTime of ticketTimes) {
if (ticketTime.date <= time)
currentSource = ticketTime.source;
else
break; // we can break here because the sources are sorted by date
}
return currentSource;
}
async function convertSourcesToMessages(ticketSources) {
const messages = [];
for (const index in ticketSources) {
const ticketSource = ticketSources[index];
const previous = ticketSources[Number.parseInt(index) - 1];
// save ticket message
const ticketMessage = new types_1.Maintenance_Message({
title: OpenserviceTranslationKeys_1.OpenserviceMessageTranslationKeys.TICKETLOG.SOURCE.TITLE,
content: OpenserviceTranslationKeys_1.OpenserviceMessageTranslationKeys.TICKETLOG.SOURCE.CONTENT,
referencedObjectId: ticketSource.get("ticket").id,
classname: ticketSource.get("ticket").className,
displayAt: ticketSource.get("createdAt"),
data: {
type: "system",
origin: {
id: ticketSource.id,
classname: ticketSource.className,
},
translation: {
old: previous?.get("source")?.get("name") ?? "Nicht vorhanden",
new: ticketSource.get("source")?.get("name") ?? "Nicht vorhanden",
username: (0, openinc_openservice_save_ticket_data_1.getUsername)(ticketSource.get("user")),
ticketName: ticketSource.get("ticket").get("title"),
},
},
user: ticketSource.get("user"),
tenant: ticketSource.get("tenant"),
});
messages.push(ticketMessage);
// save machinelog message
const machinelogMessage = new types_1.Maintenance_Message({
title: OpenserviceTranslationKeys_1.OpenserviceMessageTranslationKeys.MACHINELOG.SOURCE.TITLE,
content: OpenserviceTranslationKeys_1.OpenserviceMessageTranslationKeys.MACHINELOG.SOURCE.CONTENT,
referencedObjectId: ticketSource.get("source").id,
classname: ticketSource.get("source").className,
displayAt: ticketSource.get("createdAt"),
data: {
type: "system",
origin: {
id: ticketSource.get("ticket").id,
classname: ticketSource.get("ticket").className,
},
translation: {
old: previous?.get("source")?.get("name") ?? "Nicht vorhanden",
new: ticketSource.get("source")?.get("name") ?? "Nicht vorhanden",
username: (0, openinc_openservice_save_ticket_data_1.getUsername)(ticketSource.get("user")),
ticketName: ticketSource.get("ticket").get("title"),
},
},
user: ticketSource.get("user"),
tenant: ticketSource.get("tenant"),
});
messages.push(machinelogMessage);
// save also a message for the source that was assigned to the ticket
if (previous) {
const previousSourceMessage = new types_1.Maintenance_Message({
title: OpenserviceTranslationKeys_1.OpenserviceMessageTranslationKeys.MACHINELOG.SOURCE.TITLE,
content: OpenserviceTranslationKeys_1.OpenserviceMessageTranslationKeys.MACHINELOG.SOURCE.CONTENT,
referencedObjectId: previous.get("source").id,
classname: previous.get("source").className,
displayAt: ticketSource.get("createdAt"),
data: {
type: "system",
origin: {
id: ticketSource.get("ticket").id,
classname: ticketSource.get("ticket").className,
},
translation: {
old: previous.get("source").get("name") ?? "Nicht vorhanden",
new: ticketSource.get("source")?.get("name") ?? "Nicht vorhanden",
username: (0, openinc_openservice_save_ticket_data_1.getUsername)(ticketSource.get("user")),
ticketName: ticketSource.get("ticket").get("title"),
},
},
user: ticketSource.get("user"),
tenant: ticketSource.get("tenant"),
});
messages.push(previousSourceMessage);
}
}
await types_1.Maintenance_Message.saveAll(messages, { useMasterKey: true });
}
async function ticketStateToMessage(timeMap) {
console.log("Creating ticket state messages");
await convertToMessage({
className: types_1.Maintenance_Ticket_Kanban_State.className,
timeMap: timeMap,
ticketTranslation: OpenserviceTranslationKeys_1.OpenserviceMessageTranslationKeys.TICKETLOG.KANBANSTATE,
machinelogTranslation: OpenserviceTranslationKeys_1.OpenserviceMessageTranslationKeys.MACHINELOG.KANBANSTATE,
getTranslationData: (entry, prev) => {
return {
old: prev?.get("state")?.get("label") ?? "Nicht vorhanden",
new: entry.get("state")?.get("label") ?? "Nicht vorhanden",
};
},
isValueValid: (entry) => !!entry.get("state"),
});
}
async function ticketMaterialToMessage(timeMap) {
console.log("Creating ticket material messages");
await convertToMessage({
className: types_1.Maintenance_Ticket_Material.className,
timeMap: timeMap,
ticketTranslation: OpenserviceTranslationKeys_1.OpenserviceMessageTranslationKeys.TICKETLOG.MATERIAL,
machinelogTranslation: OpenserviceTranslationKeys_1.OpenserviceMessageTranslationKeys.MACHINELOG.MATERIAL,
getTranslationData: (entry, prev) => {
return {
old: (0, Maintenance_Ticket_Material_1.ticketMaterialItemListToString)(prev?.get("itemList")) ??
"Nicht vorhanden",
new: (0, Maintenance_Ticket_Material_1.ticketMaterialItemListToString)(entry?.get("itemList")) ?? "Nicht vorhanden",
};
},
isValueValid: (entry) => !!entry.get("ticket"),
});
}
async function ticketIssuecategoryToMessage(timeMap) {
console.log("Creating ticket issue messages");
await convertToMessage({
className: types_1.Maintenance_Ticket_Issuecategory.className,
timeMap: timeMap,
ticketTranslation: OpenserviceTranslationKeys_1.OpenserviceMessageTranslationKeys.TICKETLOG.ISSUECATEGORY,
machinelogTranslation: OpenserviceTranslationKeys_1.OpenserviceMessageTranslationKeys.MACHINELOG.ISSUECATEGORY,
getTranslationData: (entry, prev) => {
return {
old: prev?.get("issuecategory")?.get("name") ?? "Nicht vorhanden",
new: entry.get("issuecategory")?.get("name") ?? "Nicht vorhanden",
};
},
isValueValid: (entry) => !!entry.get("issuecategory"),
});
}
async function ticketPriorityToMessage(timeMap) {
console.log("Creating ticket priority messages");
await convertToMessage({
className: types_1.Maintenance_Priority.className,
timeMap: timeMap,
ticketTranslation: OpenserviceTranslationKeys_1.OpenserviceMessageTranslationKeys.TICKETLOG.PRIORITY,
machinelogTranslation: OpenserviceTranslationKeys_1.OpenserviceMessageTranslationKeys.MACHINELOG.PRIORITY,
getTranslationData: (entry, prev) => {
return {
old: prev?.get("value") ?? "Nicht vorhanden",
new: entry.get("value") ?? "Nicht vorhanden",
};
},
isValueValid: (entry) => entry.get("value") !== undefined,
});
}
async function ticketRestrictionToMessage(timeMap) {
console.log("Creating ticket restriction messages");
await convertToMessage({
className: types_1.Maintenance_Restriction.className,
timeMap: timeMap,
ticketTranslation: OpenserviceTranslationKeys_1.OpenserviceMessageTranslationKeys.TICKETLOG.RESTRICTION,
machinelogTranslation: OpenserviceTranslationKeys_1.OpenserviceMessageTranslationKeys.MACHINELOG.RESTRICTION,
getTranslationData: (entry, prev) => {
return {
old: prev?.get("value") ?? "Nicht vorhanden",
new: entry.get("value") ?? "Nicht vorhanden",
};
},
isValueValid: (entry) => entry.get("value") !== undefined,
});
}
async function ticketDowntimeToMessage(timeMap) {
console.log("Creating ticket downtime messages");
await convertToMessage({
className: types_1.Maintenance_Downtime.className,
timeMap: timeMap,
ticketTranslation: OpenserviceTranslationKeys_1.OpenserviceMessageTranslationKeys.TICKETLOG.DOWNTIME,
machinelogTranslation: OpenserviceTranslationKeys_1.OpenserviceMessageTranslationKeys.MACHINELOG.DOWNTIME,
getTranslationData: (entry, prev) => {
return {
old: prev?.get("value") ?? "Nicht vorhanden",
new: entry.get("value") ?? "Nicht vorhanden",
};
},
isValueValid: (entry) => entry.get("value") !== undefined,
});
}
async function ticketFrequencyToMessage(timeMap) {
console.log("Creating ticket frequency messages");
await convertToMessage({
className: types_1.Maintenance_Frequency.className,
timeMap: timeMap,
ticketTranslation: OpenserviceTranslationKeys_1.OpenserviceMessageTranslationKeys.TICKETLOG.FREQUENCY,
machinelogTranslation: OpenserviceTranslationKeys_1.OpenserviceMessageTranslationKeys.MACHINELOG.FREQUENCY,
getTranslationData: (entry, prev) => {
return {
old: prev?.get("value") ?? "Nicht vorhanden",
new: entry.get("value") ?? "Nicht vorhanden",
};
},
isValueValid: (entry) => entry.get("value") !== undefined,
});
}
async function ticketDuedateToMessage(timeMap) {
console.log("Creating ticket duedate messages");
await convertToMessage({
className: types_1.Maintenance_Duedate.className,
timeMap: timeMap,
ticketTranslation: OpenserviceTranslationKeys_1.OpenserviceMessageTranslationKeys.TICKETLOG.DUEDATE,
machinelogTranslation: OpenserviceTranslationKeys_1.OpenserviceMessageTranslationKeys.MACHINELOG.DUEDATE,
getTranslationData: (entry, prev) => {
return {
oldstart: prev?.get("start")?.toLocaleDateString("de-DE") ?? "Nicht vorhanden",
oldend: prev?.get("end")?.toLocaleDateString("de-DE") ?? "Nicht vorhanden",
newstart: entry.get("start")?.toLocaleDateString("de-DE") ?? "Nicht vorhanden",
newend: entry.get("end")?.toLocaleDateString("de-DE") ?? "Nicht vorhanden",
};
},
isValueValid: (entry) => entry.get("end") !== undefined,
});
}
async function ticketTitleToMessage(timeMap) {
console.log("Creating ticket title messages");
await convertToMessage({
className: types_1.Maintenance_Ticket_Title.className,
timeMap: timeMap,
ticketTranslation: OpenserviceTranslationKeys_1.OpenserviceMessageTranslationKeys.TICKETLOG.TITLE,
machinelogTranslation: OpenserviceTranslationKeys_1.OpenserviceMessageTranslationKeys.MACHINELOG.TITLE,
getTranslationData: (entry, prev) => {
return {
old: prev?.get("title") ?? "Nicht vorhanden",
new: entry.get("title") ?? "Nicht vorhanden",
};
},
isValueValid: (entry) => !!entry.get("title"),
});
}
async function ticketProjectToMessage(timeMap) {
console.log("Creating ticket project messages");
await convertToMessage({
className: types_1.Maintenance_Ticket_Project.className,
timeMap: timeMap,
ticketTranslation: OpenserviceTranslationKeys_1.OpenserviceMessageTranslationKeys.TICKETLOG.PROJECT,
machinelogTranslation: OpenserviceTranslationKeys_1.OpenserviceMessageTranslationKeys.MACHINELOG.PROJECT,
getTranslationData: (entry, prev) => {
return {
old: prev?.get("project")?.get("name") ?? "Nicht vorhanden",
new: entry.get("project")?.get("name") ?? "Nicht vorhanden",
};
},
isValueValid: (entry) => !!entry.get("ticket"),
});
}
async function convertScheduleExecutionToMessage() {
console.log("Creating schedule execution messages");
const executions = await new Parse.Query(types_1.Maintenance_Schedule_Execution)
.limit(1000000)
.includeAll()
.find({ useMasterKey: true });
const messages = [];
for (const execution of executions) {
const source = execution.get("source");
if (!source)
continue;
const message = new types_1.Maintenance_Message({
title: OpenserviceTranslationKeys_1.OpenserviceMessageTranslationKeys.MACHINELOG.SCHEDULEEXECUTION.TITLE,
content: OpenserviceTranslationKeys_1.OpenserviceMessageTranslationKeys.MACHINELOG.SCHEDULEEXECUTION.CONTENT,
referencedObjectId: source.id,
classname: source.className,
displayAt: execution.get("finishedAt") ?? execution.get("createdAt"),
data: {
type: "system",
origin: {
id: execution.id,
classname: execution.className,
},
translation: {
title: execution.get("title"),
description: execution.get("description"),
username: (0, openinc_openservice_save_ticket_data_1.getUsername)(execution.get("user")),
},
},
user: execution.get("user"),
tenant: execution.get("tenant"),
});
messages.push(message);
}
await types_1.Maintenance_Message.saveAll(messages, { useMasterKey: true });
}