@openinc/parse-server-opendash
Version:
Parse Server Cloud Code for open.INC Stack.
422 lines (421 loc) • 17 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getUsername = getUsername;
exports.init = init;
exports.saveTicketData = saveTicketData;
exports.serializeTicketData = serializeTicketData;
const parse_1 = require("parse");
const openservice_1 = require("../features/openservice");
const openware_1 = require("../features/openware");
const catchError_1 = require("../helper/catchError");
const types_1 = require("../types");
const openinc_openservice_ticket_data_1 = require("./openinc-openservice-ticket-data");
function getUsername(user) {
if (!user)
return "System";
let username = "";
if (user?.get("firstname") && user?.get("lastname")) {
username = user?.get("firstname") + " " + user?.get("lastname");
}
else if (user?.get("name")) {
username = user.get("name");
}
else {
username = user?.getUsername();
}
return username ?? "System";
}
async function init(name) {
Parse.Cloud.define(name, handleRequest, { requireUser: false });
}
async function handleRequest(request) {
const result = {
success: true,
};
try {
let user = request.user;
if (request.params.user) {
user = (await new Parse.Query(parse_1.User)
.equalTo("objectId", request.params.user)
.first({
useMasterKey: true,
}));
}
const session = user?.getSessionToken();
if (!session) {
const adminUser = (await new Parse.Query(parse_1.User)
.include("session")
.ascending("createdAt")
.first({ useMasterKey: true }));
// adminUser was fetched with master privileges; ensure subsequent operations run with master as well
const ticket = await saveTicketData(request.params, user ?? adminUser, {
useMasterKey: true,
});
result.ticket = ticket;
return result;
}
const ticket = await saveTicketData(request.params, user);
result.success = true;
result.ticket = ticket;
return result;
}
catch (error) {
console.error(error);
result.success = false;
result.error = error;
return result;
}
}
async function saveTicketData(data, user, overrideFetchOptions) {
const fetchOptions = overrideFetchOptions ??
(user ? { sessionToken: user.getSessionToken() } : { useMasterKey: true });
console.log("[saveTicketData] effective fetchOptions:", fetchOptions);
const ticket = await (0, openservice_1.getTicketObject)(data, user, fetchOptions);
const owticketobj = {
ticket: ticket,
priority: 0,
downtime: 0,
restriction: 0,
frequency: 0,
issuecategory: "",
state: "",
source: new types_1.Maintenance_Ticket_Source(),
};
// needs to be the first save to save a message before data change messages are created on ticket creation
if (data.message)
await (0, openservice_1.saveMessage)(ticket, data.message, fetchOptions, data);
if (data.assignedTo !== undefined)
await (0, openservice_1.assignUsersAndRoles)(ticket, data.assignedTo, fetchOptions, user);
if (data.title)
await (0, openservice_1.saveTicketTitle)(ticket, fetchOptions);
if (data.description)
await (0, openservice_1.saveDescription)(ticket, data, fetchOptions);
if (data.meta)
await (0, openservice_1.saveTicketMeta)(ticket, data.meta, fetchOptions);
if (data.duedate)
await (0, openservice_1.saveDuedate)(ticket, data.duedate, fetchOptions);
if (data.priority !== undefined) {
const savedpriority = await (0, openservice_1.savePriority)(ticket, data.priority, fetchOptions);
owticketobj.priority = savedpriority;
}
else {
//Fetch last value so it won't publish a 0 value to openware and overwrite the last value with default 0
const [lastPriorityError, lastPriority] = await (0, catchError_1.catchError)(new Parse.Query(types_1.Maintenance_Priority)
.equalTo("ticket", ticket)
.descending("createdAt")
.first(fetchOptions), [Error]);
if (lastPriorityError) {
console.log("Error fetching last priority", lastPriorityError);
}
else {
owticketobj.priority = lastPriority?.get("value") ?? 0;
}
}
if (data.downtime !== undefined) {
const saveddowntime = await (0, openservice_1.saveDowntime)(ticket, data.downtime, fetchOptions);
owticketobj.downtime = saveddowntime;
}
else {
//Fetch last value so it won't publish a 0 value to openware and overwrite the last value with default 0
const [lastDowntimeError, lastDowntime] = await (0, catchError_1.catchError)(new Parse.Query(types_1.Maintenance_Downtime)
.equalTo("ticket", ticket)
.descending("createdAt")
.first(fetchOptions), [Error]);
if (lastDowntimeError) {
console.log("Error fetching last downtime", lastDowntimeError);
}
else {
owticketobj.downtime = lastDowntime?.get("value") ?? 0;
}
}
if (data.frequency !== undefined) {
const savedfrequency = await (0, openservice_1.saveFrequency)(ticket, data.frequency, fetchOptions);
owticketobj.frequency = savedfrequency;
}
else {
//Fetch last value so it won't publish a 0 value to openware and overwrite the last value with default 0
const [lastFrequencyError, lastFrequency] = await (0, catchError_1.catchError)(new Parse.Query(types_1.Maintenance_Frequency)
.equalTo("ticket", ticket)
.descending("createdAt")
.first(fetchOptions), [Error]);
if (lastFrequencyError) {
console.log("Error fetching last frequency", lastFrequencyError);
}
else {
owticketobj.frequency = lastFrequency?.get("value") ?? 0;
}
}
if (data.restriction !== undefined) {
const savedrestriction = await (0, openservice_1.saveRestriction)(ticket, data.restriction, fetchOptions);
owticketobj.restriction = savedrestriction;
}
else {
//Fetch last value so it won't publish a 0 value to openware and overwrite the last value with default 0
const [lastRestrictionError, lastRestriction] = await (0, catchError_1.catchError)(new Parse.Query(types_1.Maintenance_Restriction)
.equalTo("ticket", ticket)
.descending("createdAt")
.first(fetchOptions), [Error]);
if (lastRestrictionError) {
console.log("Error fetching last restriction", lastRestrictionError);
}
else {
owticketobj.restriction = lastRestriction?.get("value") ?? 0;
}
}
if (data.issuecategory) {
const savedissuecategory = await (0, openservice_1.saveIssueCategory)(ticket, data.issuecategory, fetchOptions);
const [fetchedSavedIssuecategoryError, fetchedSavedIssuecategory] = await (0, catchError_1.catchError)(new Parse.Query(types_1.Maintenance_Ticket_Issuecategory)
.include("issuecategory")
.get(savedissuecategory.id, fetchOptions), [Error]);
if (fetchedSavedIssuecategoryError) {
console.log("Error fetching saved issue category", fetchedSavedIssuecategoryError);
}
else {
owticketobj.issuecategory = fetchedSavedIssuecategory;
}
}
if (data.state) {
const savedstate = await (0, openservice_1.saveState)(ticket, data.state, fetchOptions);
const [fetchedSavedStateError, fetchedSavedState] = await (0, catchError_1.catchError)(new Parse.Query(types_1.Maintenance_Ticket_Kanban_State)
.include("state")
.get(savedstate.id, fetchOptions), [Error]);
if (fetchedSavedStateError) {
console.log("Error fetching saved state", fetchedSavedStateError);
}
else {
owticketobj.state = fetchedSavedState;
}
}
if (data.media && data.media.length > 0) {
try {
await (0, openservice_1.saveMedia)(ticket, data.media, fetchOptions);
}
catch (error) {
console.error(`Error saving media for ticket ${ticket.id}:`, error);
}
}
if (data.material) {
try {
await (0, openservice_1.saveMaterial)(ticket, data.material, fetchOptions);
}
catch (error) {
console.error(`Error saving material for ticket ${ticket.id}:`, error);
}
}
if (data.project) {
try {
await (0, openservice_1.saveProject)(ticket, data.project, fetchOptions);
}
catch (error) {
console.error(`Error saving project ${data.project} for ticket ${ticket.id}:`, error);
}
}
// save defaults
if (!data.issuecategory && !data.existingTicketId) {
try {
await (0, openservice_1.saveDefaultIssueCategory)(ticket, fetchOptions);
}
catch (error) {
console.error(`Error saving default issue category for ticket ${ticket.id}:`, error);
}
}
if (!data.state && !data.existingTicketId) {
try {
await (0, openservice_1.saveDefaultState)(ticket, fetchOptions);
}
catch (error) {
console.error(`Error saving default state for ticket ${ticket.id}:`, error);
}
}
// save source last so the machinelog does not have the initialization messages of the ticket data
if (data.source) {
try {
await (0, openservice_1.saveSource)(ticket, data.source, fetchOptions);
}
catch (error) {
console.error(`Error saving source ${data.source} for ticket ${ticket.id}:`, error);
}
}
//Get source from ticket and save to openware
const [fetchedTicketSourceError, ticketsource] = await (0, catchError_1.catchError)(new Parse.Query(types_1.Maintenance_Ticket_Source)
.equalTo("ticket", new types_1.Maintenance_Ticket({ objectId: ticket.id }))
.descending("createdAt")
.include("source")
.first({ useMasterKey: true }), [Error]);
if (fetchedTicketSourceError) {
console.log("Error fetching saved source", fetchedTicketSourceError);
}
else if (ticketsource && ticketsource.get("source")) {
owticketobj.source = ticketsource;
// publish to openware
await publishToOpenWare(owticketobj, ticket, ticketsource.get("source").get("tag")
? ticketsource.get("source").get("tag")
: "");
}
// save TicketData in TicketData Table
const [ticketData] = await (0, openinc_openservice_ticket_data_1.getTicketData)([ticket]);
if (ticketData) {
const ticketDataEntry = new types_1.Maintenance_Ticket_Data({
ticket: ticket,
data: serializeTicketData(ticketData),
tenant: ticket.get("tenant"),
});
const fallbackACL = new Parse.ACL();
fallbackACL.setPublicReadAccess(false);
fallbackACL.setPublicWriteAccess(false);
const user = ticket.get("user");
if (user) {
fallbackACL.setReadAccess(user.id, true);
fallbackACL.setWriteAccess(user.id, true);
}
ticketDataEntry.setACL(ticket.getACL() ?? ticket.get("tenant")?.getACL() ?? fallbackACL);
await ticketDataEntry.save(null, { useMasterKey: true });
}
return ticket;
}
/**
* Publishes the ticket to open.WARE with all changed data
* @param owticketobj OpenWareTicketObject
* @param source OD3_Source
*/
async function publishToOpenWare(owticketobj, ticket, source) {
const time = new Date().getTime();
const values = {
date: time,
value: Object.entries(owticketobj).map(([key, value]) => {
if (key === "downtime") {
if (value instanceof types_1.Maintenance_Downtime) {
return value.get("value");
}
return value;
}
else if (key === "frequency") {
if (value instanceof types_1.Maintenance_Frequency) {
return value.get("value");
}
return value;
}
else if (key === "priority") {
if (value instanceof types_1.Maintenance_Priority) {
return value.get("value");
}
return value;
}
else if (key === "restriction") {
if (value instanceof types_1.Maintenance_Restriction) {
return value.get("value");
}
return value;
}
else if (key === "issuecategory") {
if (value instanceof types_1.Maintenance_Ticket_Issuecategory) {
return value.get("issuecategory").id;
}
return value;
}
else if (key === "state") {
if (value instanceof types_1.Maintenance_Ticket_Kanban_State) {
return value.get("state").id;
}
return value;
}
else if (key === "ticket") {
if (value instanceof types_1.Maintenance_Ticket) {
return value.id;
}
return value;
}
else if (key === "source") {
if (value instanceof types_1.Maintenance_Ticket_Source) {
return value.get("source").id;
}
return value;
}
return value;
}),
};
const valueTypes = Object.keys(owticketobj).map((key) => {
const tmpvaluetype = {
name: "",
unit: "",
type: "String",
};
if (key === "downtime") {
tmpvaluetype.name = types_1.Maintenance_Downtime.className.replace("OD3_Maintenance_", "");
tmpvaluetype.unit = "%";
tmpvaluetype.type = "Number";
}
else if (key === "frequency") {
tmpvaluetype.name = types_1.Maintenance_Frequency.className.replace("OD3_Maintenance_", "");
tmpvaluetype.unit = "%";
tmpvaluetype.type = "Number";
}
else if (key === "priority") {
tmpvaluetype.name = types_1.Maintenance_Priority.className.replace("OD3_Maintenance_", "");
tmpvaluetype.unit = "%";
tmpvaluetype.type = "Number";
}
else if (key === "restriction") {
tmpvaluetype.name = types_1.Maintenance_Restriction.className.replace("OD3_Maintenance_", "");
tmpvaluetype.unit = "%";
tmpvaluetype.type = "Number";
}
else if (key === "issuecategory") {
tmpvaluetype.name = types_1.Maintenance_Ticket_Issuecategory.className.replace("OD3_Maintenance_", "");
tmpvaluetype.unit = "";
tmpvaluetype.type = "String";
}
else if (key === "state") {
tmpvaluetype.name = types_1.Maintenance_Ticket_Kanban_State.className.replace("OD3_Maintenance_", "");
tmpvaluetype.unit = "";
tmpvaluetype.type = "String";
}
else if (key === "ticket") {
tmpvaluetype.name = types_1.Maintenance_Ticket.className.replace("OD3_Maintenance_", "");
tmpvaluetype.unit = "";
tmpvaluetype.type = "String";
}
else if (key === "source") {
tmpvaluetype.name = types_1.Maintenance_Ticket_Source.className.replace("OD3_Maintenance_", "");
tmpvaluetype.unit = "";
tmpvaluetype.type = "String";
}
return tmpvaluetype;
});
const dataitem = {
id: `openservice_ticket_${ticket.id}`,
name: `Ticket ${owticketobj.ticket.get("title")}`,
source: source,
values: [values],
valueTypes: valueTypes,
meta: {},
};
console.log("Publishing ticket to openware: ", dataitem, "with values", JSON.stringify(dataitem.values));
try {
await (0, openware_1.publishDataItem)(dataitem, ticket.get("user")?.get("email"), true);
}
catch (error) {
console.error("Error publishing ticket to openware", error);
}
}
function serializeTicketData(obj) {
if (!obj)
return obj;
// Parse.Object → convert to JSON
if (obj instanceof Parse.Object) {
return { ...obj.toJSON(), className: obj.className };
}
// Array
if (Array.isArray(obj)) {
return obj.map(serializeTicketData);
}
// Plain object
if (typeof obj === "object") {
const out = {};
for (const key in obj) {
out[key] = serializeTicketData(obj[key]);
}
return out;
}
return obj; // primitive values
}