refactor to reduce complexity
parent
8edf9e62a4
commit
eda8483e62
|
|
@ -2,17 +2,151 @@ import ical, { ICalEventStatus } from "ical-generator";
|
||||||
import { getWorkOrderMilestones } from "../../helpers/lotOccupancyDB/getWorkOrderMilestones.js";
|
import { getWorkOrderMilestones } from "../../helpers/lotOccupancyDB/getWorkOrderMilestones.js";
|
||||||
import * as configFunctions from "../../helpers/functions.config.js";
|
import * as configFunctions from "../../helpers/functions.config.js";
|
||||||
import { getPrintConfig } from "../../helpers/functions.print.js";
|
import { getPrintConfig } from "../../helpers/functions.print.js";
|
||||||
|
const calendarCompany = "cityssm.github.io";
|
||||||
|
const calendarProduct = configFunctions.getProperty("application.applicationName");
|
||||||
const timeStringSplitRegex = /[ :-]/;
|
const timeStringSplitRegex = /[ :-]/;
|
||||||
function escapeHTML(stringToEscape) {
|
function escapeHTML(stringToEscape) {
|
||||||
return stringToEscape.replace(/[^\d A-Za-z]/g, (c) => "&#" + c.codePointAt(0) + ";");
|
return stringToEscape.replace(/[^\d A-Za-z]/g, (c) => "&#" + c.codePointAt(0) + ";");
|
||||||
}
|
}
|
||||||
export const handler = (request, response) => {
|
function getUrlRoot(request) {
|
||||||
const urlRoot = "http://" +
|
return ("http://" +
|
||||||
request.hostname +
|
request.hostname +
|
||||||
(configFunctions.getProperty("application.httpPort") === 80
|
(configFunctions.getProperty("application.httpPort") === 80
|
||||||
? ""
|
? ""
|
||||||
: ":" + configFunctions.getProperty("application.httpPort")) +
|
: ":" + configFunctions.getProperty("application.httpPort")) +
|
||||||
configFunctions.getProperty("reverseProxy.urlPrefix");
|
configFunctions.getProperty("reverseProxy.urlPrefix"));
|
||||||
|
}
|
||||||
|
function getWorkOrderUrl(request, milestone) {
|
||||||
|
return getUrlRoot(request) + "/workOrders/" + milestone.workOrderId;
|
||||||
|
}
|
||||||
|
function buildEventSummary(milestone) {
|
||||||
|
let summary = (milestone.workOrderMilestoneCompletionDate ? "✔ " : "") +
|
||||||
|
(milestone.workOrderMilestoneTypeId
|
||||||
|
? milestone.workOrderMilestoneType
|
||||||
|
: milestone.workOrderMilestoneDescription).trim();
|
||||||
|
if (milestone.workOrderLotOccupancies.length > 0) {
|
||||||
|
let occupantCount = 0;
|
||||||
|
for (const lotOccupancy of milestone.workOrderLotOccupancies) {
|
||||||
|
for (const occupant of lotOccupancy.lotOccupancyOccupants) {
|
||||||
|
occupantCount += 1;
|
||||||
|
if (occupantCount === 1) {
|
||||||
|
if (summary !== "") {
|
||||||
|
summary += ": ";
|
||||||
|
}
|
||||||
|
summary += occupant.occupantName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (occupantCount > 1) {
|
||||||
|
summary += " plus " + (occupantCount - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return summary;
|
||||||
|
}
|
||||||
|
function buildEventDescriptionHTML(request, milestone) {
|
||||||
|
const urlRoot = getUrlRoot(request);
|
||||||
|
const workOrderUrl = getWorkOrderUrl(request, milestone);
|
||||||
|
let descriptionHTML = "<h1>Milestone Description</h1>" +
|
||||||
|
"<p>" +
|
||||||
|
escapeHTML(milestone.workOrderMilestoneDescription) +
|
||||||
|
"</p>" +
|
||||||
|
"<h2>Work Order #" +
|
||||||
|
milestone.workOrderNumber +
|
||||||
|
"</h2>" +
|
||||||
|
("<p>" + escapeHTML(milestone.workOrderDescription) + "</p>") +
|
||||||
|
("<p>" + workOrderUrl + "</p>");
|
||||||
|
if (milestone.workOrderLotOccupancies.length > 0) {
|
||||||
|
descriptionHTML +=
|
||||||
|
"<h2>Related " +
|
||||||
|
escapeHTML(configFunctions.getProperty("aliases.occupancies")) +
|
||||||
|
"</h2>" +
|
||||||
|
'<table border="1"><thead><tr>' +
|
||||||
|
("<th>" + escapeHTML(configFunctions.getProperty("aliases.occupancy")) + " Type</th>") +
|
||||||
|
("<th>" + escapeHTML(configFunctions.getProperty("aliases.lot")) + "</th>") +
|
||||||
|
"<th>Start Date</th>" +
|
||||||
|
"<th>End Date</th>" +
|
||||||
|
("<th>" + escapeHTML(configFunctions.getProperty("aliases.occupants")) + "</th>") +
|
||||||
|
"</tr></thead>" +
|
||||||
|
"<tbody>";
|
||||||
|
for (const occupancy of milestone.workOrderLotOccupancies) {
|
||||||
|
descriptionHTML +=
|
||||||
|
"<tr>" +
|
||||||
|
("<td>" +
|
||||||
|
'<a href="' +
|
||||||
|
urlRoot +
|
||||||
|
"/lotOccupancies/" +
|
||||||
|
occupancy.lotOccupancyId +
|
||||||
|
'">' +
|
||||||
|
escapeHTML(occupancy.occupancyType) +
|
||||||
|
"</a></td>") +
|
||||||
|
("<td>" +
|
||||||
|
(occupancy.lotName ? escapeHTML(occupancy.lotName) : "(Not Set)") +
|
||||||
|
"</td>") +
|
||||||
|
("<td>" + occupancy.occupancyStartDateString + "</td>") +
|
||||||
|
"<td>" +
|
||||||
|
(occupancy.occupancyEndDate ? occupancy.occupancyEndDateString : "(No End Date)") +
|
||||||
|
"</td>" +
|
||||||
|
"<td>";
|
||||||
|
for (const occupant of occupancy.lotOccupancyOccupants) {
|
||||||
|
descriptionHTML +=
|
||||||
|
escapeHTML(occupant.lotOccupantType) +
|
||||||
|
": " +
|
||||||
|
escapeHTML(occupant.occupantName) +
|
||||||
|
"<br />";
|
||||||
|
}
|
||||||
|
descriptionHTML += "</td>" + "</tr>";
|
||||||
|
}
|
||||||
|
descriptionHTML += "</tbody></table>";
|
||||||
|
}
|
||||||
|
if (milestone.workOrderLots.length > 0) {
|
||||||
|
descriptionHTML +=
|
||||||
|
"<h2>Related " +
|
||||||
|
escapeHTML(configFunctions.getProperty("aliases.lots")) +
|
||||||
|
"</h2>" +
|
||||||
|
'<table border="1"><thead><tr>' +
|
||||||
|
("<th>" + escapeHTML(configFunctions.getProperty("aliases.lot")) + " Type</th>") +
|
||||||
|
("<th>" + escapeHTML(configFunctions.getProperty("aliases.map")) + "</th>") +
|
||||||
|
("<th>" + escapeHTML(configFunctions.getProperty("aliases.lot")) + " Type" + "</th>") +
|
||||||
|
"<th>Status</th>" +
|
||||||
|
"</tr></thead>" +
|
||||||
|
"<tbody>";
|
||||||
|
for (const lot of milestone.workOrderLots) {
|
||||||
|
descriptionHTML +=
|
||||||
|
"<tr>" +
|
||||||
|
("<td>" +
|
||||||
|
'<a href="' +
|
||||||
|
urlRoot +
|
||||||
|
"/lots/" +
|
||||||
|
lot.lotId +
|
||||||
|
'">' +
|
||||||
|
escapeHTML(lot.lotName) +
|
||||||
|
"</a></td>") +
|
||||||
|
("<td>" + escapeHTML(lot.mapName) + "</td>") +
|
||||||
|
("<td>" + escapeHTML(lot.lotType) + "</td>") +
|
||||||
|
("<td>" + escapeHTML(lot.lotStatus) + "</td>") +
|
||||||
|
"</tr>";
|
||||||
|
}
|
||||||
|
descriptionHTML += "</tbody></table>";
|
||||||
|
}
|
||||||
|
const prints = configFunctions.getProperty("settings.workOrders.prints");
|
||||||
|
if (prints.length > 0) {
|
||||||
|
descriptionHTML += "<h2>Prints</h2>";
|
||||||
|
for (const printName of prints) {
|
||||||
|
const printConfig = getPrintConfig(printName);
|
||||||
|
if (printConfig) {
|
||||||
|
descriptionHTML +=
|
||||||
|
"<p>" +
|
||||||
|
escapeHTML(printConfig.title) +
|
||||||
|
"<br />" +
|
||||||
|
(urlRoot + "/print/" + printName + "/?workOrderId=" + milestone.workOrderId) +
|
||||||
|
"</p>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return descriptionHTML;
|
||||||
|
}
|
||||||
|
export const handler = (request, response) => {
|
||||||
|
const urlRoot = getUrlRoot(request);
|
||||||
const workOrderMilestoneFilters = {
|
const workOrderMilestoneFilters = {
|
||||||
workOrderTypeIds: request.query.workOrderTypeIds,
|
workOrderTypeIds: request.query.workOrderTypeIds,
|
||||||
workOrderMilestoneTypeIds: request.query.workOrderMilestoneTypeIds
|
workOrderMilestoneTypeIds: request.query.workOrderMilestoneTypeIds
|
||||||
|
|
@ -36,8 +170,8 @@ export const handler = (request, response) => {
|
||||||
calendar.url(urlRoot + "/workOrders/" + workOrderMilestones[0].workOrderId);
|
calendar.url(urlRoot + "/workOrders/" + workOrderMilestones[0].workOrderId);
|
||||||
}
|
}
|
||||||
calendar.prodId({
|
calendar.prodId({
|
||||||
company: "cityssm.github.io",
|
company: calendarCompany,
|
||||||
product: configFunctions.getProperty("application.applicationName")
|
product: calendarProduct
|
||||||
});
|
});
|
||||||
for (const milestone of workOrderMilestones) {
|
for (const milestone of workOrderMilestones) {
|
||||||
const milestoneTimePieces = (milestone.workOrderMilestoneDateString +
|
const milestoneTimePieces = (milestone.workOrderMilestoneDateString +
|
||||||
|
|
@ -46,28 +180,8 @@ export const handler = (request, response) => {
|
||||||
const milestoneDate = new Date(Number.parseInt(milestoneTimePieces[0], 10), Number.parseInt(milestoneTimePieces[1], 10) - 1, Number.parseInt(milestoneTimePieces[2], 10), Number.parseInt(milestoneTimePieces[3], 10), Number.parseInt(milestoneTimePieces[4], 10));
|
const milestoneDate = new Date(Number.parseInt(milestoneTimePieces[0], 10), Number.parseInt(milestoneTimePieces[1], 10) - 1, Number.parseInt(milestoneTimePieces[2], 10), Number.parseInt(milestoneTimePieces[3], 10), Number.parseInt(milestoneTimePieces[4], 10));
|
||||||
const milestoneEndDate = new Date(milestoneDate.getTime());
|
const milestoneEndDate = new Date(milestoneDate.getTime());
|
||||||
milestoneEndDate.setHours(milestoneEndDate.getHours() + 1);
|
milestoneEndDate.setHours(milestoneEndDate.getHours() + 1);
|
||||||
let summary = (milestone.workOrderMilestoneCompletionDate ? "✔ " : "") +
|
const summary = buildEventSummary(milestone);
|
||||||
(milestone.workOrderMilestoneTypeId
|
const workOrderUrl = getWorkOrderUrl(request, milestone);
|
||||||
? milestone.workOrderMilestoneType
|
|
||||||
: milestone.workOrderMilestoneDescription).trim();
|
|
||||||
if (milestone.workOrderLotOccupancies.length > 0) {
|
|
||||||
let occupantCount = 0;
|
|
||||||
for (const lotOccupancy of milestone.workOrderLotOccupancies) {
|
|
||||||
for (const occupant of lotOccupancy.lotOccupancyOccupants) {
|
|
||||||
occupantCount += 1;
|
|
||||||
if (occupantCount === 1) {
|
|
||||||
if (summary !== "") {
|
|
||||||
summary += ": ";
|
|
||||||
}
|
|
||||||
summary += occupant.occupantName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (occupantCount > 1) {
|
|
||||||
summary += " plus " + (occupantCount - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const workOrderURL = urlRoot + "/workOrders/" + milestone.workOrderId;
|
|
||||||
const eventData = {
|
const eventData = {
|
||||||
start: milestoneDate,
|
start: milestoneDate,
|
||||||
created: new Date(milestone.recordCreate_timeMillis),
|
created: new Date(milestone.recordCreate_timeMillis),
|
||||||
|
|
@ -75,118 +189,15 @@ export const handler = (request, response) => {
|
||||||
lastModified: new Date(Math.max(milestone.recordUpdate_timeMillis, milestone.workOrderRecordUpdate_timeMillis)),
|
lastModified: new Date(Math.max(milestone.recordUpdate_timeMillis, milestone.workOrderRecordUpdate_timeMillis)),
|
||||||
allDay: !milestone.workOrderMilestoneTime,
|
allDay: !milestone.workOrderMilestoneTime,
|
||||||
summary,
|
summary,
|
||||||
url: workOrderURL
|
url: workOrderUrl
|
||||||
};
|
};
|
||||||
if (!eventData.allDay) {
|
if (!eventData.allDay) {
|
||||||
eventData.end = milestoneEndDate;
|
eventData.end = milestoneEndDate;
|
||||||
}
|
}
|
||||||
const calendarEvent = calendar.createEvent(eventData);
|
const calendarEvent = calendar.createEvent(eventData);
|
||||||
let descriptionHTML = "<h1>Milestone Description</h1>" +
|
const descriptionHTML = buildEventDescriptionHTML(request, milestone);
|
||||||
"<p>" +
|
|
||||||
escapeHTML(milestone.workOrderMilestoneDescription) +
|
|
||||||
"</p>" +
|
|
||||||
"<h2>Work Order #" +
|
|
||||||
milestone.workOrderNumber +
|
|
||||||
"</h2>" +
|
|
||||||
("<p>" + escapeHTML(milestone.workOrderDescription) + "</p>") +
|
|
||||||
("<p>" + workOrderURL + "</p>");
|
|
||||||
if (milestone.workOrderLotOccupancies.length > 0) {
|
|
||||||
descriptionHTML +=
|
|
||||||
"<h2>Related " +
|
|
||||||
escapeHTML(configFunctions.getProperty("aliases.occupancies")) +
|
|
||||||
"</h2>" +
|
|
||||||
'<table border="1"><thead><tr>' +
|
|
||||||
("<th>" +
|
|
||||||
escapeHTML(configFunctions.getProperty("aliases.occupancy")) +
|
|
||||||
" Type</th>") +
|
|
||||||
("<th>" + escapeHTML(configFunctions.getProperty("aliases.lot")) + "</th>") +
|
|
||||||
"<th>Start Date</th>" +
|
|
||||||
"<th>End Date</th>" +
|
|
||||||
("<th>" + escapeHTML(configFunctions.getProperty("aliases.occupants")) + "</th>") +
|
|
||||||
"</tr></thead>" +
|
|
||||||
"<tbody>";
|
|
||||||
for (const occupancy of milestone.workOrderLotOccupancies) {
|
|
||||||
descriptionHTML +=
|
|
||||||
"<tr>" +
|
|
||||||
("<td>" +
|
|
||||||
'<a href="' +
|
|
||||||
urlRoot +
|
|
||||||
"/lotOccupancies/" +
|
|
||||||
occupancy.lotOccupancyId +
|
|
||||||
'">' +
|
|
||||||
escapeHTML(occupancy.occupancyType) +
|
|
||||||
"</a></td>") +
|
|
||||||
("<td>" +
|
|
||||||
(occupancy.lotName ? escapeHTML(occupancy.lotName) : "(Not Set)") +
|
|
||||||
"</td>") +
|
|
||||||
("<td>" + occupancy.occupancyStartDateString + "</td>") +
|
|
||||||
"<td>" +
|
|
||||||
(occupancy.occupancyEndDate
|
|
||||||
? occupancy.occupancyEndDateString
|
|
||||||
: "(No End Date)") +
|
|
||||||
"</td>" +
|
|
||||||
"<td>";
|
|
||||||
for (const occupant of occupancy.lotOccupancyOccupants) {
|
|
||||||
descriptionHTML += escapeHTML(occupant.lotOccupantType) + ": " + escapeHTML(occupant.occupantName) + "<br />";
|
|
||||||
}
|
|
||||||
descriptionHTML += "</td>" + "</tr>";
|
|
||||||
}
|
|
||||||
descriptionHTML += "</tbody></table>";
|
|
||||||
}
|
|
||||||
if (milestone.workOrderLots.length > 0) {
|
|
||||||
descriptionHTML +=
|
|
||||||
"<h2>Related " +
|
|
||||||
escapeHTML(configFunctions.getProperty("aliases.lots")) +
|
|
||||||
"</h2>" +
|
|
||||||
'<table border="1"><thead><tr>' +
|
|
||||||
("<th>" + escapeHTML(configFunctions.getProperty("aliases.lot")) + " Type</th>") +
|
|
||||||
("<th>" + escapeHTML(configFunctions.getProperty("aliases.map")) + "</th>") +
|
|
||||||
("<th>" +
|
|
||||||
escapeHTML(configFunctions.getProperty("aliases.lot")) +
|
|
||||||
" Type" +
|
|
||||||
"</th>") +
|
|
||||||
"<th>Status</th>" +
|
|
||||||
"</tr></thead>" +
|
|
||||||
"<tbody>";
|
|
||||||
for (const lot of milestone.workOrderLots) {
|
|
||||||
descriptionHTML +=
|
|
||||||
"<tr>" +
|
|
||||||
("<td>" +
|
|
||||||
'<a href="' +
|
|
||||||
urlRoot +
|
|
||||||
"/lots/" +
|
|
||||||
lot.lotId +
|
|
||||||
'">' +
|
|
||||||
escapeHTML(lot.lotName) +
|
|
||||||
"</a></td>") +
|
|
||||||
("<td>" + escapeHTML(lot.mapName) + "</td>") +
|
|
||||||
("<td>" + escapeHTML(lot.lotType) + "</td>") +
|
|
||||||
("<td>" + escapeHTML(lot.lotStatus) + "</td>") +
|
|
||||||
"</tr>";
|
|
||||||
}
|
|
||||||
descriptionHTML += "</tbody></table>";
|
|
||||||
}
|
|
||||||
const prints = configFunctions.getProperty("settings.workOrders.prints");
|
|
||||||
if (prints.length > 0) {
|
|
||||||
descriptionHTML += "<h2>Prints</h2>";
|
|
||||||
for (const printName of prints) {
|
|
||||||
const printConfig = getPrintConfig(printName);
|
|
||||||
if (printConfig) {
|
|
||||||
descriptionHTML +=
|
|
||||||
"<p>" +
|
|
||||||
escapeHTML(printConfig.title) +
|
|
||||||
"<br />" +
|
|
||||||
(urlRoot +
|
|
||||||
"/print/" +
|
|
||||||
printName +
|
|
||||||
"/?workOrderId=" +
|
|
||||||
milestone.workOrderId) +
|
|
||||||
"</p>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
calendarEvent.description({
|
calendarEvent.description({
|
||||||
plain: workOrderURL,
|
plain: workOrderUrl,
|
||||||
html: descriptionHTML
|
html: descriptionHTML
|
||||||
});
|
});
|
||||||
if (milestone.workOrderMilestoneCompletionDate) {
|
if (milestone.workOrderMilestoneCompletionDate) {
|
||||||
|
|
|
||||||
|
|
@ -7,25 +7,193 @@ import {
|
||||||
WorkOrderMilestoneFilters
|
WorkOrderMilestoneFilters
|
||||||
} from "../../helpers/lotOccupancyDB/getWorkOrderMilestones.js";
|
} from "../../helpers/lotOccupancyDB/getWorkOrderMilestones.js";
|
||||||
|
|
||||||
import type { RequestHandler } from "express";
|
import type { RequestHandler, Request } from "express";
|
||||||
|
|
||||||
import * as configFunctions from "../../helpers/functions.config.js";
|
import * as configFunctions from "../../helpers/functions.config.js";
|
||||||
import { getPrintConfig } from "../../helpers/functions.print.js";
|
import { getPrintConfig } from "../../helpers/functions.print.js";
|
||||||
|
|
||||||
|
import type * as recordTypes from "../../types/recordTypes";
|
||||||
|
|
||||||
|
const calendarCompany = "cityssm.github.io";
|
||||||
|
const calendarProduct = configFunctions.getProperty("application.applicationName");
|
||||||
|
|
||||||
const timeStringSplitRegex = /[ :-]/;
|
const timeStringSplitRegex = /[ :-]/;
|
||||||
|
|
||||||
function escapeHTML(stringToEscape: string) {
|
function escapeHTML(stringToEscape: string) {
|
||||||
return stringToEscape.replace(/[^\d A-Za-z]/g, (c) => "&#" + c.codePointAt(0) + ";");
|
return stringToEscape.replace(/[^\d A-Za-z]/g, (c) => "&#" + c.codePointAt(0) + ";");
|
||||||
}
|
}
|
||||||
|
|
||||||
export const handler: RequestHandler = (request, response) => {
|
function getUrlRoot(request: Request): string {
|
||||||
const urlRoot =
|
return (
|
||||||
"http://" +
|
"http://" +
|
||||||
request.hostname +
|
request.hostname +
|
||||||
(configFunctions.getProperty("application.httpPort") === 80
|
(configFunctions.getProperty("application.httpPort") === 80
|
||||||
? ""
|
? ""
|
||||||
: ":" + configFunctions.getProperty("application.httpPort")) +
|
: ":" + configFunctions.getProperty("application.httpPort")) +
|
||||||
configFunctions.getProperty("reverseProxy.urlPrefix");
|
configFunctions.getProperty("reverseProxy.urlPrefix")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getWorkOrderUrl(request: Request, milestone: recordTypes.WorkOrderMilestone) {
|
||||||
|
return getUrlRoot(request) + "/workOrders/" + milestone.workOrderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildEventSummary(milestone: recordTypes.WorkOrderMilestone): string {
|
||||||
|
let summary =
|
||||||
|
(milestone.workOrderMilestoneCompletionDate ? "✔ " : "") +
|
||||||
|
(milestone.workOrderMilestoneTypeId
|
||||||
|
? milestone.workOrderMilestoneType
|
||||||
|
: milestone.workOrderMilestoneDescription
|
||||||
|
).trim();
|
||||||
|
|
||||||
|
if (milestone.workOrderLotOccupancies.length > 0) {
|
||||||
|
let occupantCount = 0;
|
||||||
|
|
||||||
|
for (const lotOccupancy of milestone.workOrderLotOccupancies) {
|
||||||
|
for (const occupant of lotOccupancy.lotOccupancyOccupants) {
|
||||||
|
occupantCount += 1;
|
||||||
|
|
||||||
|
if (occupantCount === 1) {
|
||||||
|
if (summary !== "") {
|
||||||
|
summary += ": ";
|
||||||
|
}
|
||||||
|
|
||||||
|
summary += occupant.occupantName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (occupantCount > 1) {
|
||||||
|
summary += " plus " + (occupantCount - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return summary;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildEventDescriptionHTML(
|
||||||
|
request: Request,
|
||||||
|
milestone: recordTypes.WorkOrderMilestone
|
||||||
|
): string {
|
||||||
|
const urlRoot = getUrlRoot(request);
|
||||||
|
const workOrderUrl = getWorkOrderUrl(request, milestone);
|
||||||
|
|
||||||
|
let descriptionHTML =
|
||||||
|
"<h1>Milestone Description</h1>" +
|
||||||
|
"<p>" +
|
||||||
|
escapeHTML(milestone.workOrderMilestoneDescription) +
|
||||||
|
"</p>" +
|
||||||
|
"<h2>Work Order #" +
|
||||||
|
milestone.workOrderNumber +
|
||||||
|
"</h2>" +
|
||||||
|
("<p>" + escapeHTML(milestone.workOrderDescription) + "</p>") +
|
||||||
|
("<p>" + workOrderUrl + "</p>");
|
||||||
|
|
||||||
|
if (milestone.workOrderLotOccupancies.length > 0) {
|
||||||
|
descriptionHTML +=
|
||||||
|
"<h2>Related " +
|
||||||
|
escapeHTML(configFunctions.getProperty("aliases.occupancies")) +
|
||||||
|
"</h2>" +
|
||||||
|
'<table border="1"><thead><tr>' +
|
||||||
|
("<th>" + escapeHTML(configFunctions.getProperty("aliases.occupancy")) + " Type</th>") +
|
||||||
|
("<th>" + escapeHTML(configFunctions.getProperty("aliases.lot")) + "</th>") +
|
||||||
|
"<th>Start Date</th>" +
|
||||||
|
"<th>End Date</th>" +
|
||||||
|
("<th>" + escapeHTML(configFunctions.getProperty("aliases.occupants")) + "</th>") +
|
||||||
|
"</tr></thead>" +
|
||||||
|
"<tbody>";
|
||||||
|
|
||||||
|
for (const occupancy of milestone.workOrderLotOccupancies) {
|
||||||
|
descriptionHTML +=
|
||||||
|
"<tr>" +
|
||||||
|
("<td>" +
|
||||||
|
'<a href="' +
|
||||||
|
urlRoot +
|
||||||
|
"/lotOccupancies/" +
|
||||||
|
occupancy.lotOccupancyId +
|
||||||
|
'">' +
|
||||||
|
escapeHTML(occupancy.occupancyType) +
|
||||||
|
"</a></td>") +
|
||||||
|
("<td>" +
|
||||||
|
(occupancy.lotName ? escapeHTML(occupancy.lotName) : "(Not Set)") +
|
||||||
|
"</td>") +
|
||||||
|
("<td>" + occupancy.occupancyStartDateString + "</td>") +
|
||||||
|
"<td>" +
|
||||||
|
(occupancy.occupancyEndDate ? occupancy.occupancyEndDateString : "(No End Date)") +
|
||||||
|
"</td>" +
|
||||||
|
"<td>";
|
||||||
|
|
||||||
|
for (const occupant of occupancy.lotOccupancyOccupants) {
|
||||||
|
descriptionHTML +=
|
||||||
|
escapeHTML(occupant.lotOccupantType) +
|
||||||
|
": " +
|
||||||
|
escapeHTML(occupant.occupantName) +
|
||||||
|
"<br />";
|
||||||
|
}
|
||||||
|
|
||||||
|
descriptionHTML += "</td>" + "</tr>";
|
||||||
|
}
|
||||||
|
|
||||||
|
descriptionHTML += "</tbody></table>";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (milestone.workOrderLots.length > 0) {
|
||||||
|
descriptionHTML +=
|
||||||
|
"<h2>Related " +
|
||||||
|
escapeHTML(configFunctions.getProperty("aliases.lots")) +
|
||||||
|
"</h2>" +
|
||||||
|
'<table border="1"><thead><tr>' +
|
||||||
|
("<th>" + escapeHTML(configFunctions.getProperty("aliases.lot")) + " Type</th>") +
|
||||||
|
("<th>" + escapeHTML(configFunctions.getProperty("aliases.map")) + "</th>") +
|
||||||
|
("<th>" + escapeHTML(configFunctions.getProperty("aliases.lot")) + " Type" + "</th>") +
|
||||||
|
"<th>Status</th>" +
|
||||||
|
"</tr></thead>" +
|
||||||
|
"<tbody>";
|
||||||
|
|
||||||
|
for (const lot of milestone.workOrderLots) {
|
||||||
|
descriptionHTML +=
|
||||||
|
"<tr>" +
|
||||||
|
("<td>" +
|
||||||
|
'<a href="' +
|
||||||
|
urlRoot +
|
||||||
|
"/lots/" +
|
||||||
|
lot.lotId +
|
||||||
|
'">' +
|
||||||
|
escapeHTML(lot.lotName) +
|
||||||
|
"</a></td>") +
|
||||||
|
("<td>" + escapeHTML(lot.mapName) + "</td>") +
|
||||||
|
("<td>" + escapeHTML(lot.lotType) + "</td>") +
|
||||||
|
("<td>" + escapeHTML(lot.lotStatus) + "</td>") +
|
||||||
|
"</tr>";
|
||||||
|
}
|
||||||
|
|
||||||
|
descriptionHTML += "</tbody></table>";
|
||||||
|
}
|
||||||
|
|
||||||
|
const prints = configFunctions.getProperty("settings.workOrders.prints");
|
||||||
|
|
||||||
|
if (prints.length > 0) {
|
||||||
|
descriptionHTML += "<h2>Prints</h2>";
|
||||||
|
|
||||||
|
for (const printName of prints) {
|
||||||
|
const printConfig = getPrintConfig(printName);
|
||||||
|
|
||||||
|
if (printConfig) {
|
||||||
|
descriptionHTML +=
|
||||||
|
"<p>" +
|
||||||
|
escapeHTML(printConfig.title) +
|
||||||
|
"<br />" +
|
||||||
|
(urlRoot + "/print/" + printName + "/?workOrderId=" + milestone.workOrderId) +
|
||||||
|
"</p>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return descriptionHTML;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const handler: RequestHandler = (request, response) => {
|
||||||
|
const urlRoot = getUrlRoot(request);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get work order milestones
|
* Get work order milestones
|
||||||
|
|
@ -62,8 +230,8 @@ export const handler: RequestHandler = (request, response) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
calendar.prodId({
|
calendar.prodId({
|
||||||
company: "cityssm.github.io",
|
company: calendarCompany,
|
||||||
product: configFunctions.getProperty("application.applicationName")
|
product: calendarProduct
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -90,38 +258,11 @@ export const handler: RequestHandler = (request, response) => {
|
||||||
|
|
||||||
// Build summary (title in Outlook)
|
// Build summary (title in Outlook)
|
||||||
|
|
||||||
let summary =
|
const summary = buildEventSummary(milestone);
|
||||||
(milestone.workOrderMilestoneCompletionDate ? "✔ " : "") +
|
|
||||||
(milestone.workOrderMilestoneTypeId
|
|
||||||
? milestone.workOrderMilestoneType
|
|
||||||
: milestone.workOrderMilestoneDescription
|
|
||||||
).trim();
|
|
||||||
|
|
||||||
if (milestone.workOrderLotOccupancies.length > 0) {
|
|
||||||
let occupantCount = 0;
|
|
||||||
|
|
||||||
for (const lotOccupancy of milestone.workOrderLotOccupancies) {
|
|
||||||
for (const occupant of lotOccupancy.lotOccupancyOccupants) {
|
|
||||||
occupantCount += 1;
|
|
||||||
|
|
||||||
if (occupantCount === 1) {
|
|
||||||
if (summary !== "") {
|
|
||||||
summary += ": ";
|
|
||||||
}
|
|
||||||
|
|
||||||
summary += occupant.occupantName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (occupantCount > 1) {
|
|
||||||
summary += " plus " + (occupantCount - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build URL
|
// Build URL
|
||||||
|
|
||||||
const workOrderURL = urlRoot + "/workOrders/" + milestone.workOrderId;
|
const workOrderUrl = getWorkOrderUrl(request, milestone);
|
||||||
|
|
||||||
// Create event
|
// Create event
|
||||||
|
|
||||||
|
|
@ -137,7 +278,7 @@ export const handler: RequestHandler = (request, response) => {
|
||||||
),
|
),
|
||||||
allDay: !milestone.workOrderMilestoneTime,
|
allDay: !milestone.workOrderMilestoneTime,
|
||||||
summary,
|
summary,
|
||||||
url: workOrderURL
|
url: workOrderUrl
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!eventData.allDay) {
|
if (!eventData.allDay) {
|
||||||
|
|
@ -148,126 +289,10 @@ export const handler: RequestHandler = (request, response) => {
|
||||||
|
|
||||||
// Build description
|
// Build description
|
||||||
|
|
||||||
let descriptionHTML =
|
const descriptionHTML = buildEventDescriptionHTML(request, milestone);
|
||||||
"<h1>Milestone Description</h1>" +
|
|
||||||
"<p>" +
|
|
||||||
escapeHTML(milestone.workOrderMilestoneDescription) +
|
|
||||||
"</p>" +
|
|
||||||
"<h2>Work Order #" +
|
|
||||||
milestone.workOrderNumber +
|
|
||||||
"</h2>" +
|
|
||||||
("<p>" + escapeHTML(milestone.workOrderDescription) + "</p>") +
|
|
||||||
("<p>" + workOrderURL + "</p>");
|
|
||||||
|
|
||||||
if (milestone.workOrderLotOccupancies.length > 0) {
|
|
||||||
descriptionHTML +=
|
|
||||||
"<h2>Related " +
|
|
||||||
escapeHTML(configFunctions.getProperty("aliases.occupancies")) +
|
|
||||||
"</h2>" +
|
|
||||||
'<table border="1"><thead><tr>' +
|
|
||||||
("<th>" +
|
|
||||||
escapeHTML(configFunctions.getProperty("aliases.occupancy")) +
|
|
||||||
" Type</th>") +
|
|
||||||
("<th>" + escapeHTML(configFunctions.getProperty("aliases.lot")) + "</th>") +
|
|
||||||
"<th>Start Date</th>" +
|
|
||||||
"<th>End Date</th>" +
|
|
||||||
("<th>" + escapeHTML(configFunctions.getProperty("aliases.occupants")) + "</th>") +
|
|
||||||
"</tr></thead>" +
|
|
||||||
"<tbody>";
|
|
||||||
|
|
||||||
for (const occupancy of milestone.workOrderLotOccupancies) {
|
|
||||||
descriptionHTML +=
|
|
||||||
"<tr>" +
|
|
||||||
("<td>" +
|
|
||||||
'<a href="' +
|
|
||||||
urlRoot +
|
|
||||||
"/lotOccupancies/" +
|
|
||||||
occupancy.lotOccupancyId +
|
|
||||||
'">' +
|
|
||||||
escapeHTML(occupancy.occupancyType) +
|
|
||||||
"</a></td>") +
|
|
||||||
("<td>" +
|
|
||||||
(occupancy.lotName ? escapeHTML(occupancy.lotName) : "(Not Set)") +
|
|
||||||
"</td>") +
|
|
||||||
("<td>" + occupancy.occupancyStartDateString + "</td>") +
|
|
||||||
"<td>" +
|
|
||||||
(occupancy.occupancyEndDate
|
|
||||||
? occupancy.occupancyEndDateString
|
|
||||||
: "(No End Date)") +
|
|
||||||
"</td>" +
|
|
||||||
"<td>";
|
|
||||||
|
|
||||||
for (const occupant of occupancy.lotOccupancyOccupants) {
|
|
||||||
descriptionHTML += escapeHTML(occupant.lotOccupantType) + ": " + escapeHTML(occupant.occupantName) + "<br />";
|
|
||||||
}
|
|
||||||
|
|
||||||
descriptionHTML += "</td>" + "</tr>";
|
|
||||||
}
|
|
||||||
|
|
||||||
descriptionHTML += "</tbody></table>";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (milestone.workOrderLots.length > 0) {
|
|
||||||
descriptionHTML +=
|
|
||||||
"<h2>Related " +
|
|
||||||
escapeHTML(configFunctions.getProperty("aliases.lots")) +
|
|
||||||
"</h2>" +
|
|
||||||
'<table border="1"><thead><tr>' +
|
|
||||||
("<th>" + escapeHTML(configFunctions.getProperty("aliases.lot")) + " Type</th>") +
|
|
||||||
("<th>" + escapeHTML(configFunctions.getProperty("aliases.map")) + "</th>") +
|
|
||||||
("<th>" +
|
|
||||||
escapeHTML(configFunctions.getProperty("aliases.lot")) +
|
|
||||||
" Type" +
|
|
||||||
"</th>") +
|
|
||||||
"<th>Status</th>" +
|
|
||||||
"</tr></thead>" +
|
|
||||||
"<tbody>";
|
|
||||||
|
|
||||||
for (const lot of milestone.workOrderLots) {
|
|
||||||
descriptionHTML +=
|
|
||||||
"<tr>" +
|
|
||||||
("<td>" +
|
|
||||||
'<a href="' +
|
|
||||||
urlRoot +
|
|
||||||
"/lots/" +
|
|
||||||
lot.lotId +
|
|
||||||
'">' +
|
|
||||||
escapeHTML(lot.lotName) +
|
|
||||||
"</a></td>") +
|
|
||||||
("<td>" + escapeHTML(lot.mapName) + "</td>") +
|
|
||||||
("<td>" + escapeHTML(lot.lotType) + "</td>") +
|
|
||||||
("<td>" + escapeHTML(lot.lotStatus) + "</td>") +
|
|
||||||
"</tr>";
|
|
||||||
}
|
|
||||||
|
|
||||||
descriptionHTML += "</tbody></table>";
|
|
||||||
}
|
|
||||||
|
|
||||||
const prints = configFunctions.getProperty("settings.workOrders.prints");
|
|
||||||
|
|
||||||
if (prints.length > 0) {
|
|
||||||
descriptionHTML += "<h2>Prints</h2>";
|
|
||||||
|
|
||||||
for (const printName of prints) {
|
|
||||||
const printConfig = getPrintConfig(printName);
|
|
||||||
|
|
||||||
if (printConfig) {
|
|
||||||
descriptionHTML +=
|
|
||||||
"<p>" +
|
|
||||||
escapeHTML(printConfig.title) +
|
|
||||||
"<br />" +
|
|
||||||
(urlRoot +
|
|
||||||
"/print/" +
|
|
||||||
printName +
|
|
||||||
"/?workOrderId=" +
|
|
||||||
milestone.workOrderId) +
|
|
||||||
"</p>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
calendarEvent.description({
|
calendarEvent.description({
|
||||||
plain: workOrderURL,
|
plain: workOrderUrl,
|
||||||
html: descriptionHTML
|
html: descriptionHTML
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue