diff --git a/data/config.cemetery.ssm.js b/data/config.cemetery.ssm.js
index 7a26c9c0..e2b52164 100644
--- a/data/config.cemetery.ssm.js
+++ b/data/config.cemetery.ssm.js
@@ -24,5 +24,8 @@ config.settings.lot = {
};
config.settings.lotOccupancy.occupantCityDefault = "Sault Ste. Marie";
config.settings.map.mapCityDefault = "Sault Ste. Marie";
+config.settings.workOrders = {
+ workOrderNumberLength: 6
+};
config.aliases.externalReceiptNumber = "GP Receipt Number";
export default config;
diff --git a/data/config.cemetery.ssm.ts b/data/config.cemetery.ssm.ts
index 05453ddc..2f46b8d9 100644
--- a/data/config.cemetery.ssm.ts
+++ b/data/config.cemetery.ssm.ts
@@ -38,6 +38,10 @@ config.settings.lot = {
config.settings.lotOccupancy.occupantCityDefault = "Sault Ste. Marie";
config.settings.map.mapCityDefault = "Sault Ste. Marie";
+config.settings.workOrders = {
+ workOrderNumberLength: 6
+};
+
config.aliases.externalReceiptNumber = "GP Receipt Number";
export default config;
\ No newline at end of file
diff --git a/handlers/workOrders-get/new.d.ts b/handlers/workOrders-get/new.d.ts
new file mode 100644
index 00000000..9621c611
--- /dev/null
+++ b/handlers/workOrders-get/new.d.ts
@@ -0,0 +1,3 @@
+import type { RequestHandler } from "express";
+export declare const handler: RequestHandler;
+export default handler;
diff --git a/handlers/workOrders-get/new.js b/handlers/workOrders-get/new.js
new file mode 100644
index 00000000..84409fb1
--- /dev/null
+++ b/handlers/workOrders-get/new.js
@@ -0,0 +1,17 @@
+import { dateToInteger, dateToString } from "@cityssm/expressjs-server-js/dateTimeFns.js";
+import { getWorkOrderTypes } from "../../helpers/functions.cache.js";
+export const handler = (request, response) => {
+ const currentDate = new Date();
+ const workOrder = {
+ workOrderOpenDate: dateToInteger(currentDate),
+ workOrderOpenDateString: dateToString(currentDate)
+ };
+ const workOrderTypes = getWorkOrderTypes();
+ response.render("workOrder-edit", {
+ headTitle: "New Work Order",
+ workOrder,
+ isCreate: true,
+ workOrderTypes
+ });
+};
+export default handler;
diff --git a/handlers/workOrders-get/new.ts b/handlers/workOrders-get/new.ts
new file mode 100644
index 00000000..fcd1c8ae
--- /dev/null
+++ b/handlers/workOrders-get/new.ts
@@ -0,0 +1,29 @@
+import { dateToInteger, dateToString } from "@cityssm/expressjs-server-js/dateTimeFns.js";
+import type { RequestHandler } from "express";
+
+import {
+ getWorkOrderTypes
+} from "../../helpers/functions.cache.js";
+
+import * as recordTypes from "../../types/recordTypes";
+
+export const handler: RequestHandler = (request, response) => {
+
+ const currentDate = new Date();
+
+ const workOrder: recordTypes.WorkOrder = {
+ workOrderOpenDate: dateToInteger(currentDate),
+ workOrderOpenDateString: dateToString(currentDate)
+ };
+
+ const workOrderTypes = getWorkOrderTypes();
+
+ response.render("workOrder-edit", {
+ headTitle: "New Work Order",
+ workOrder,
+ isCreate: true,
+ workOrderTypes
+ });
+};
+
+export default handler;
diff --git a/handlers/workOrders-post/doCreateWorkOrder.d.ts b/handlers/workOrders-post/doCreateWorkOrder.d.ts
new file mode 100644
index 00000000..9621c611
--- /dev/null
+++ b/handlers/workOrders-post/doCreateWorkOrder.d.ts
@@ -0,0 +1,3 @@
+import type { RequestHandler } from "express";
+export declare const handler: RequestHandler;
+export default handler;
diff --git a/handlers/workOrders-post/doCreateWorkOrder.js b/handlers/workOrders-post/doCreateWorkOrder.js
new file mode 100644
index 00000000..2946e597
--- /dev/null
+++ b/handlers/workOrders-post/doCreateWorkOrder.js
@@ -0,0 +1,9 @@
+import { addWorkOrder } from "../../helpers/lotOccupancyDB/addWorkOrder.js";
+export const handler = async (request, response) => {
+ const workOrderId = addWorkOrder(request.body, request.session);
+ response.json({
+ success: true,
+ workOrderId
+ });
+};
+export default handler;
diff --git a/handlers/workOrders-post/doCreateWorkOrder.ts b/handlers/workOrders-post/doCreateWorkOrder.ts
new file mode 100644
index 00000000..3da2da52
--- /dev/null
+++ b/handlers/workOrders-post/doCreateWorkOrder.ts
@@ -0,0 +1,14 @@
+import type { RequestHandler } from "express";
+
+import { addWorkOrder } from "../../helpers/lotOccupancyDB/addWorkOrder.js";
+
+export const handler: RequestHandler = async (request, response) => {
+ const workOrderId = addWorkOrder(request.body, request.session);
+
+ response.json({
+ success: true,
+ workOrderId
+ });
+};
+
+export default handler;
diff --git a/helpers/functions.config.d.ts b/helpers/functions.config.d.ts
index 567edf0d..aefb50a3 100644
--- a/helpers/functions.config.d.ts
+++ b/helpers/functions.config.d.ts
@@ -32,4 +32,5 @@ export declare function getProperty(propertyName: "settings.lotOccupancy.occupan
export declare function getProperty(propertyName: "settings.lotOccupancy.occupantCityDefault"): string;
export declare function getProperty(propertyName: "settings.lotOccupancy.occupantProvinceDefault"): string;
export declare function getProperty(propertyName: "settings.fees.taxPercentageDefault"): number;
+export declare function getProperty(propertyName: "settings.workOrders.workOrderNumberLength"): number;
export declare const keepAliveMillis: number;
diff --git a/helpers/functions.config.js b/helpers/functions.config.js
index 353493b0..3c60725a 100644
--- a/helpers/functions.config.js
+++ b/helpers/functions.config.js
@@ -31,6 +31,7 @@ configFallbackValues.set("settings.lotOccupancy.occupancyEndDateIsRequired", tru
configFallbackValues.set("settings.lotOccupancy.occupantCityDefault", "");
configFallbackValues.set("settings.lotOccupancy.occupantProvinceDefault", "");
configFallbackValues.set("settings.fees.taxPercentageDefault", 0);
+configFallbackValues.set("settings.workOrders.workOrderNumberLength", 6);
export function getProperty(propertyName) {
const propertyNameSplit = propertyName.split(".");
let currentObject = config;
diff --git a/helpers/functions.config.ts b/helpers/functions.config.ts
index 70de2832..5614abf3 100644
--- a/helpers/functions.config.ts
+++ b/helpers/functions.config.ts
@@ -62,6 +62,8 @@ configFallbackValues.set("settings.lotOccupancy.occupantProvinceDefault", "");
configFallbackValues.set("settings.fees.taxPercentageDefault", 0);
+configFallbackValues.set("settings.workOrders.workOrderNumberLength", 6);
+
/*
* Set up function overloads
*/
@@ -142,6 +144,10 @@ export function getProperty(
propertyName: "settings.fees.taxPercentageDefault"
): number;
+export function getProperty(
+ propertyName: "settings.workOrders.workOrderNumberLength"
+): number;
+
export function getProperty(propertyName: string): unknown {
const propertyNameSplit = propertyName.split(".");
diff --git a/helpers/lotOccupancyDB/addWorkOrder.d.ts b/helpers/lotOccupancyDB/addWorkOrder.d.ts
index e36afd7b..4e92f917 100644
--- a/helpers/lotOccupancyDB/addWorkOrder.d.ts
+++ b/helpers/lotOccupancyDB/addWorkOrder.d.ts
@@ -1,7 +1,7 @@
import type * as recordTypes from "../../types/recordTypes";
interface AddWorkOrderForm {
workOrderTypeId: number | string;
- workOrderNumber: string;
+ workOrderNumber?: string;
workOrderDescription: string;
workOrderOpenDateString?: string;
workOrderCloseDateString?: string;
diff --git a/helpers/lotOccupancyDB/addWorkOrder.js b/helpers/lotOccupancyDB/addWorkOrder.js
index 3f0bcc3a..af0bf254 100644
--- a/helpers/lotOccupancyDB/addWorkOrder.js
+++ b/helpers/lotOccupancyDB/addWorkOrder.js
@@ -1,9 +1,14 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
+import { getNextWorkOrderNumber } from "./getNextWorkOrderNumber.js";
import { dateStringToInteger, dateToInteger } from "@cityssm/expressjs-server-js/dateTimeFns.js";
export const addWorkOrder = (workOrderForm, requestSession) => {
const database = sqlite(databasePath);
const rightNow = new Date();
+ let workOrderNumber = workOrderForm.workOrderNumber;
+ if (!workOrderNumber) {
+ workOrderNumber = getNextWorkOrderNumber(database);
+ }
const result = database
.prepare("insert into WorkOrders (" +
"workOrderTypeId, workOrderNumber, workOrderDescription," +
@@ -11,7 +16,7 @@ export const addWorkOrder = (workOrderForm, requestSession) => {
" recordCreate_userName, recordCreate_timeMillis," +
" recordUpdate_userName, recordUpdate_timeMillis)" +
" values (?, ?, ?, ?, ?, ?, ?, ?, ?)")
- .run(workOrderForm.workOrderTypeId, workOrderForm.workOrderNumber, workOrderForm.workOrderDescription, workOrderForm.workOrderOpenDateString
+ .run(workOrderForm.workOrderTypeId, workOrderNumber, workOrderForm.workOrderDescription, workOrderForm.workOrderOpenDateString
? dateStringToInteger(workOrderForm.workOrderOpenDateString)
: dateToInteger(rightNow), workOrderForm.workOrderCloseDateString
? dateStringToInteger(workOrderForm.workOrderCloseDateString)
diff --git a/helpers/lotOccupancyDB/addWorkOrder.ts b/helpers/lotOccupancyDB/addWorkOrder.ts
index 0365f335..4f840c4c 100644
--- a/helpers/lotOccupancyDB/addWorkOrder.ts
+++ b/helpers/lotOccupancyDB/addWorkOrder.ts
@@ -2,6 +2,8 @@ import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
+import { getNextWorkOrderNumber } from "./getNextWorkOrderNumber.js";
+
import {
dateStringToInteger,
dateToInteger
@@ -11,7 +13,7 @@ import type * as recordTypes from "../../types/recordTypes";
interface AddWorkOrderForm {
workOrderTypeId: number | string;
- workOrderNumber: string;
+ workOrderNumber?: string;
workOrderDescription: string;
workOrderOpenDateString?: string;
workOrderCloseDateString?: string;
@@ -25,6 +27,12 @@ export const addWorkOrder = (
const rightNow = new Date();
+ let workOrderNumber = workOrderForm.workOrderNumber;
+
+ if (!workOrderNumber) {
+ workOrderNumber = getNextWorkOrderNumber(database);
+ }
+
const result = database
.prepare(
"insert into WorkOrders (" +
@@ -36,7 +44,7 @@ export const addWorkOrder = (
)
.run(
workOrderForm.workOrderTypeId,
- workOrderForm.workOrderNumber,
+ workOrderNumber,
workOrderForm.workOrderDescription,
workOrderForm.workOrderOpenDateString
? dateStringToInteger(workOrderForm.workOrderOpenDateString)
diff --git a/helpers/lotOccupancyDB/getNextWorkOrderNumber.d.ts b/helpers/lotOccupancyDB/getNextWorkOrderNumber.d.ts
new file mode 100644
index 00000000..c91ef8ef
--- /dev/null
+++ b/helpers/lotOccupancyDB/getNextWorkOrderNumber.d.ts
@@ -0,0 +1,3 @@
+import sqlite from "better-sqlite3";
+export declare const getNextWorkOrderNumber: (connectedDatabase?: sqlite.Database) => string;
+export default getNextWorkOrderNumber;
diff --git a/helpers/lotOccupancyDB/getNextWorkOrderNumber.js b/helpers/lotOccupancyDB/getNextWorkOrderNumber.js
new file mode 100644
index 00000000..2179c3ff
--- /dev/null
+++ b/helpers/lotOccupancyDB/getNextWorkOrderNumber.js
@@ -0,0 +1,30 @@
+import sqlite from "better-sqlite3";
+import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
+import * as configFunctions from "../functions.config.js";
+export const getNextWorkOrderNumber = (connectedDatabase) => {
+ const database = connectedDatabase ||
+ sqlite(databasePath, {
+ readonly: true
+ });
+ const paddingLength = configFunctions.getProperty("settings.workOrders.workOrderNumberLength");
+ const currentYearString = new Date().getFullYear().toString();
+ const regex = new RegExp("^" + currentYearString + "-\\d+$");
+ database.function("userFn_matchesWorkOrderNumberSyntax", (workOrderNumber) => {
+ return regex.test(workOrderNumber) ? 1 : 0;
+ });
+ const workOrderNumberRecord = database
+ .prepare("select workOrderNumber from WorkOrders" +
+ " where userFn_matchesWorkOrderNumberSyntax(workOrderNumber) = 1" +
+ " order by cast(substr(workOrderNumber, instr(workOrderNumber, '-') + 1) as integer) desc")
+ .get();
+ if (!connectedDatabase) {
+ database.close();
+ }
+ let workOrderNumberIndex = 0;
+ if (workOrderNumberRecord) {
+ workOrderNumberIndex = Number.parseInt(workOrderNumberRecord.workOrderNumber.split("-")[1], 10);
+ }
+ workOrderNumberIndex += 1;
+ return currentYearString + "-" + workOrderNumberIndex.toString().padStart(paddingLength, "0");
+};
+export default getNextWorkOrderNumber;
diff --git a/helpers/lotOccupancyDB/getNextWorkOrderNumber.ts b/helpers/lotOccupancyDB/getNextWorkOrderNumber.ts
new file mode 100644
index 00000000..62a36fb8
--- /dev/null
+++ b/helpers/lotOccupancyDB/getNextWorkOrderNumber.ts
@@ -0,0 +1,56 @@
+import sqlite from "better-sqlite3";
+
+import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
+
+import * as configFunctions from "../functions.config.js";
+
+export const getNextWorkOrderNumber = (
+ connectedDatabase?: sqlite.Database
+): string => {
+ const database =
+ connectedDatabase ||
+ sqlite(databasePath, {
+ readonly: true
+ });
+
+ const paddingLength = configFunctions.getProperty(
+ "settings.workOrders.workOrderNumberLength"
+ );
+ const currentYearString = new Date().getFullYear().toString();
+
+ const regex = new RegExp("^" + currentYearString + "-\\d+$");
+
+ database.function(
+ "userFn_matchesWorkOrderNumberSyntax",
+ (workOrderNumber: string) => {
+ return regex.test(workOrderNumber) ? 1 : 0;
+ }
+ );
+
+ const workOrderNumberRecord = database
+ .prepare(
+ "select workOrderNumber from WorkOrders" +
+ " where userFn_matchesWorkOrderNumberSyntax(workOrderNumber) = 1" +
+ " order by cast(substr(workOrderNumber, instr(workOrderNumber, '-') + 1) as integer) desc"
+ )
+ .get();
+
+ if (!connectedDatabase) {
+ database.close();
+ }
+
+ let workOrderNumberIndex = 0;
+
+ if (workOrderNumberRecord) {
+ workOrderNumberIndex = Number.parseInt(
+ workOrderNumberRecord.workOrderNumber.split("-")[1],
+ 10
+ );
+ }
+
+ workOrderNumberIndex += 1;
+
+ return currentYearString + "-" + workOrderNumberIndex.toString().padStart(paddingLength, "0");
+};
+
+export default getNextWorkOrderNumber;
diff --git a/public-typescript/main.js b/public-typescript/main.js
index ce01a2dc..3f8dc438 100644
--- a/public-typescript/main.js
+++ b/public-typescript/main.js
@@ -24,7 +24,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
const fieldElement = clickEvent.currentTarget.closest(".field");
const inputOrSelectElement = fieldElement.querySelector("input, select");
if (inputOrSelectElement.tagName === "INPUT") {
- inputOrSelectElement.disabled = false;
+ inputOrSelectElement.readOnly = false;
}
else {
const optionElements = inputOrSelectElement.querySelectorAll("option");
diff --git a/public-typescript/main.ts b/public-typescript/main.ts
index a654eaa7..03cc1f7a 100644
--- a/public-typescript/main.ts
+++ b/public-typescript/main.ts
@@ -54,7 +54,7 @@ import type * as globalTypes from "../types/globalTypes";
) as HTMLInputElement | HTMLSelectElement;
if (inputOrSelectElement.tagName === "INPUT") {
- inputOrSelectElement.disabled = false;
+ (inputOrSelectElement as HTMLInputElement).readOnly = false;
} else {
const optionElements =
inputOrSelectElement.querySelectorAll("option");
diff --git a/public-typescript/workOrderEdit.js b/public-typescript/workOrderEdit.js
index 581683f8..d56e1aef 100644
--- a/public-typescript/workOrderEdit.js
+++ b/public-typescript/workOrderEdit.js
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
const urlPrefix = document.querySelector("main").dataset.urlPrefix;
const workOrderId = document.querySelector("#workOrderEdit--workOrderId").value;
const isCreate = workOrderId === "";
+ los.initializeUnlockFieldButtons(document.querySelector("#form--workOrderEdit"));
document
.querySelector("#form--workOrderEdit")
.addEventListener("submit", (submitEvent) => {
diff --git a/public-typescript/workOrderEdit.ts b/public-typescript/workOrderEdit.ts
index 070d2720..556fecf4 100644
--- a/public-typescript/workOrderEdit.ts
+++ b/public-typescript/workOrderEdit.ts
@@ -5,8 +5,6 @@ import type { BulmaJS } from "@cityssm/bulma-js/types";
import type * as globalTypes from "../types/globalTypes";
import type * as recordTypes from "../types/recordTypes";
-import { response } from "express";
-import { closeDelimiter } from "ejs";
declare const cityssm: cityssmGlobal;
declare const bulmaJS: BulmaJS;
@@ -24,6 +22,10 @@ declare const bulmaJS: BulmaJS;
const isCreate = workOrderId === "";
+ los.initializeUnlockFieldButtons(
+ document.querySelector("#form--workOrderEdit")
+ );
+
document
.querySelector("#form--workOrderEdit")
.addEventListener("submit", (submitEvent) => {
diff --git a/public/javascripts/main.min.js b/public/javascripts/main.min.js
index 0de7f811..465813a1 100644
--- a/public/javascripts/main.min.js
+++ b/public/javascripts/main.min.js
@@ -1 +1 @@
-"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=e=>{const t=e.currentTarget.closest(".field").querySelector("input, select");if("INPUT"===t.tagName)t.disabled=!1;else{const e=t.querySelectorAll("option");for(const t of e)t.disabled=!1}t.focus()},t={highlightMap:(e,t,s)=>{let o,a=t;for(;!(o=e.querySelector("#"+a))&&a.includes("-");)a=a.slice(0,Math.max(0,a.lastIndexOf("-")));if(o){o.style.fill=null,o.classList.add("highlight","is-"+s);const e=o.querySelectorAll("path");for(const t of e)t.style.fill=null}},initializeUnlockFieldButtons:t=>{const s=t.querySelectorAll(".is-unlock-field-button");for(const t of s)t.addEventListener("click",e)},populateAliases:e=>{const t=e.querySelectorAll(".alias");for(const e of t)switch(e.dataset.alias){case"Lot":e.textContent=exports.aliases.lot;break;case"lot":e.textContent=exports.aliases.lot.toLowerCase();break;case"Occupancy":e.textContent=exports.aliases.occupancy;break;case"occupancy":e.textContent=exports.aliases.occupancy.toLowerCase();break;case"Occupant":e.textContent=exports.aliases.occupant;break;case"occupant":e.textContent=exports.aliases.occupant.toLowerCase();break;case"ExternalReceiptNumber":e.textContent=exports.aliases.externalReceiptNumber}}};exports.los=t})();
\ No newline at end of file
+"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=e=>{const t=e.currentTarget.closest(".field").querySelector("input, select");if("INPUT"===t.tagName)t.readOnly=!1;else{const e=t.querySelectorAll("option");for(const t of e)t.disabled=!1}t.focus()},t={highlightMap:(e,t,s)=>{let o,a=t;for(;!(o=e.querySelector("#"+a))&&a.includes("-");)a=a.slice(0,Math.max(0,a.lastIndexOf("-")));if(o){o.style.fill=null,o.classList.add("highlight","is-"+s);const e=o.querySelectorAll("path");for(const t of e)t.style.fill=null}},initializeUnlockFieldButtons:t=>{const s=t.querySelectorAll(".is-unlock-field-button");for(const t of s)t.addEventListener("click",e)},populateAliases:e=>{const t=e.querySelectorAll(".alias");for(const e of t)switch(e.dataset.alias){case"Lot":e.textContent=exports.aliases.lot;break;case"lot":e.textContent=exports.aliases.lot.toLowerCase();break;case"Occupancy":e.textContent=exports.aliases.occupancy;break;case"occupancy":e.textContent=exports.aliases.occupancy.toLowerCase();break;case"Occupant":e.textContent=exports.aliases.occupant;break;case"occupant":e.textContent=exports.aliases.occupant.toLowerCase();break;case"ExternalReceiptNumber":e.textContent=exports.aliases.externalReceiptNumber}}};exports.los=t})();
\ No newline at end of file
diff --git a/public/javascripts/workOrderEdit.min.js b/public/javascripts/workOrderEdit.min.js
index 9001ac89..7cca5a04 100644
--- a/public/javascripts/workOrderEdit.min.js
+++ b/public/javascripts/workOrderEdit.min.js
@@ -1 +1 @@
-"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=exports.los,t=document.querySelector("main").dataset.urlPrefix,s=document.querySelector("#workOrderEdit--workOrderId").value,o=""===s;if(document.querySelector("#form--workOrderEdit").addEventListener("submit",e=>{e.preventDefault(),cityssm.postJSON(t+"/workOrders/"+(o?"doCreateWorkOrder":"doUpdateWorkOrder"),e.currentTarget,e=>{e.success?o?window.location.href=t+"/workOrders/"+e.workOrderId+"/edit":bulmaJS.alert({message:"Work Order Updated Successfully",contextualColorName:"success"}):bulmaJS.alert({title:"Error Updating Work Order",message:e.errorMessage,contextualColorName:"danger"})})}),!o){let o=exports.workOrderLots;delete exports.workOrderLots;let r=exports.workOrderLotOccupancies;delete exports.workOrderLotOccupancies;const a=e=>{const o=e.currentTarget.closest(".container--lotOccupancy").dataset.lotOccupancyId;bulmaJS.confirm({title:"Delete "+exports.aliases.lot+" "+exports.aliases.occupancy+" Relationship",message:"Are you sure you want to remove the relationship to this "+exports.aliases.lot.toLowerCase()+" "+exports.aliases.occupancy.toLowerCase()+" record from this work order? Note that the record will remain.",contextualColorName:"warning",okButton:{text:"Yes, Delete Relationship",callbackFunction:()=>{cityssm.postJSON(t+"/workOrders/doDeleteWorkOrderLotOccupancy",{workOrderId:s,lotOccupancyId:o},e=>{e.success?(r=e.workOrderLotOccupancies,u()):bulmaJS.alert({title:"Error Deleting Relationship",message:e.errorMessage,contextualColorName:"danger"})})}}})},n=(e,r)=>{cityssm.postJSON(t+"/workOrders/doAddWorkOrderLot",{workOrderId:s,lotId:e},e=>{e.success?(o=e.workOrderLots,u()):bulmaJS.alert({title:"Error Adding "+exports.aliases.lot,message:e.errorMessage,contextualColorName:"danger"}),r&&r(e.success)})},l=(e,o)=>{cityssm.postJSON(t+"/workOrders/doAddWorkOrderLotOccupancy",{workOrderId:s,lotOccupancyId:e},e=>{e.success?(r=e.workOrderLotOccupancies,u()):bulmaJS.alert({title:"Error Adding "+exports.aliases.occupancy,message:e.errorMessage,contextualColorName:"danger"}),o&&o(e.success)})},c=e=>{const t=e.currentTarget.dataset.lotId;n(t)},i=()=>{const e=document.querySelector("#container--lotOccupancies");if(document.querySelector(".tabs a[href='#relatedTab--lotOccupancies'] .tag").textContent=r.length.toString(),0===r.length)return void(e.innerHTML='
There are no '+exports.aliases.occupancies.toLowerCase()+" associated with this work order.
");e.innerHTML='
'+exports.aliases.occupancy+" Type
"+exports.aliases.lot+"
Start Date
End Date
"+exports.aliases.occupants+'
';const s=cityssm.dateToString(new Date);for(const n of r){const r=document.createElement("tr");r.className="container--lotOccupancy",r.dataset.lotOccupancyId=n.lotOccupancyId.toString();const l=!(n.occupancyEndDate&&n.occupancyEndDateStringn.lotId===e.lotId);r.innerHTML='
"+(n.occupancyEndDate?n.occupancyEndDateString:'(No End Date)')+"
"+(0===n.lotOccupancyOccupants.length?'(No '+cityssm.escapeHTML(exports.aliases.occupants)+")":cityssm.escapeHTML(n.lotOccupancyOccupants[0].occupantName)+(n.lotOccupancyOccupants.length>1?" plus "+(n.lotOccupancyOccupants.length-1):""))+'
'),n.lotId&&!i&&r.querySelector(".button--addLot").addEventListener("click",c),r.querySelector(".button--deleteLotOccupancy").addEventListener("click",a),e.querySelector("tbody").append(r)}},d=e=>{const r=e.currentTarget.closest(".container--lot").dataset.lotId;bulmaJS.confirm({title:"Delete "+exports.aliases.lot+" "+exports.aliases.occupancy+" Relationship",message:"Are you sure you want to remove the relationship to this "+exports.aliases.lot.toLowerCase()+" "+exports.aliases.occupancy.toLowerCase()+" record from this work order? Note that the record will remain.",contextualColorName:"warning",okButton:{text:"Yes, Delete Relationship",callbackFunction:()=>{cityssm.postJSON(t+"/workOrders/doDeleteWorkOrderLot",{workOrderId:s,lotId:r},e=>{e.success?(o=e.workOrderLots,u()):bulmaJS.alert({title:"Error Deleting Relationship",message:e.errorMessage,contextualColorName:"danger"})})}}})},p=()=>{const e=document.querySelector("#container--lots");if(document.querySelector(".tabs a[href='#relatedTab--lots'] .tag").textContent=o.length.toString(),0!==o.length){e.innerHTML='
'+exports.aliases.lot+"
"+exports.aliases.map+"
"+exports.aliases.lot+' Type
Status
';for(const s of o){const o=document.createElement("tr");o.className="container--lot",o.dataset.lotId=s.lotId.toString(),o.innerHTML='
";for(const t of e.lotOccupancies){const e=document.createElement("tr");e.className="container--lotOccupancy",e.dataset.lotOccupancyId=t.lotOccupancyId.toString(),e.innerHTML='
'+cityssm.escapeHTML(t.occupancyType)+"
",t.lotId?e.insertAdjacentHTML("beforeend","
"+cityssm.escapeHTML(t.lotName)+"
"):e.insertAdjacentHTML("beforeend",'
(No '+exports.aliases.lot+")
"),e.insertAdjacentHTML("beforeend","
"+t.occupancyStartDateString+"
"+(t.occupancyEndDate?t.occupancyEndDateString:'(No End Date)')+"
"+(0===t.lotOccupancyOccupants.length?'(No '+cityssm.escapeHTML(exports.aliases.occupants)+")":cityssm.escapeHTML(t.lotOccupancyOccupants[0].occupantName)+(t.lotOccupancyOccupants.length>1?" plus "+(t.lotOccupancyOccupants.length-1):""))+"
There are no records that meet the search criteria.
'})};cityssm.openHtmlModal("workOrder-addLot",{onshow:t=>{e.populateAliases(t),o=t.querySelector("form"),r=t.querySelector("#resultsContainer--lotAdd"),t.querySelector("#lotSearch--notWorkOrderId").value=s;const a=t.querySelector("#lotSearch--lotStatusId");for(const e of exports.lotStatuses){const t=document.createElement("option");t.value=e.lotStatusId.toString(),t.textContent=e.lotStatus,a.append(t)}l()},onshown:e=>{bulmaJS.toggleHtmlClipped(),e.querySelector("#lotSearch--lotName").addEventListener("change",l),e.querySelector("#lotSearch--lotStatusId").addEventListener("change",l),o.addEventListener("submit",l)},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})})}if(!o){let e=exports.workOrderMilestones;delete exports.workOrderMilestones;const o=t=>{t.success?(e=t.workOrderMilestones,c()):bulmaJS.alert({title:"Error Reopening Milestone",message:t.errorMessage,contextualColorName:"danger"})},r=r=>{r.preventDefault();const a=cityssm.dateToString(new Date),n=Number.parseInt(r.currentTarget.closest(".container--milestone").dataset.workOrderMilestoneId,10),l=e.find(e=>e.workOrderMilestoneId===n);bulmaJS.confirm({title:"Complete Milestone",message:"Are you sure you want to complete this milestone?"+(l.workOrderMilestoneDateString>a?" Note that this milestone is expected to be completed in the future.":""),messageIsHtml:!0,contextualColorName:"warning",okButton:{text:"Yes, Complete Milestone",callbackFunction:()=>{cityssm.postJSON(t+"/workOrders/doCompleteWorkOrderMilestone",{workOrderId:s,workOrderMilestoneId:n},o)}}})},a=e=>{e.preventDefault();const r=e.currentTarget.closest(".container--milestone").dataset.workOrderMilestoneId;bulmaJS.confirm({title:"Reopen Milestone",message:"Are you sure you want to remove the completion status from this milestone, and reopen it?",contextualColorName:"warning",okButton:{text:"Yes, Reopen Milestone",callbackFunction:()=>{cityssm.postJSON(t+"/workOrders/doReopenWorkOrderMilestone",{workOrderId:s,workOrderMilestoneId:r},o)}}})},n=e=>{e.preventDefault();const r=e.currentTarget.closest(".container--milestone").dataset.workOrderMilestoneId;bulmaJS.confirm({title:"Delete Milestone",message:"Are you sure you want to delete this milestone?",contextualColorName:"warning",okButton:{text:"Yes, Delete Milestone",callbackFunction:()=>{cityssm.postJSON(t+"/workOrders/doDeleteWorkOrderMilestone",{workOrderMilestoneId:r,workOrderId:s},o)}}})},l=r=>{r.preventDefault();const a=Number.parseInt(r.currentTarget.closest(".container--milestone").dataset.workOrderMilestoneId,10),n=e.find(e=>e.workOrderMilestoneId===a);let l;const c=e=>{e.preventDefault(),cityssm.postJSON(t+"/workOrders/doUpdateWorkOrderMilestone",e.currentTarget,e=>{o(e),e.success&&l()})};cityssm.openHtmlModal("workOrder-editMilestone",{onshow:e=>{e.querySelector("#milestoneEdit--workOrderId").value=s,e.querySelector("#milestoneEdit--workOrderMilestoneId").value=n.workOrderMilestoneId.toString();const t=e.querySelector("#milestoneEdit--workOrderMilestoneTypeId");let o=!1;for(const e of exports.workOrderMilestoneTypes){const s=document.createElement("option");s.value=e.workOrderMilestoneTypeId.toString(),s.textContent=e.workOrderMilestoneType,e.workOrderMilestoneTypeId===n.workOrderMilestoneTypeId&&(s.selected=!0,o=!0),t.append(s)}if(!o&&n.workOrderMilestoneTypeId){const e=document.createElement("option");e.value=n.workOrderMilestoneTypeId.toString(),e.textContent=n.workOrderMilestoneType,e.selected=!0,t.append(e)}e.querySelector("#milestoneEdit--workOrderMilestoneDateString").value=n.workOrderMilestoneDateString,e.querySelector("#milestoneEdit--workOrderMilestoneTimeString").value=n.workOrderMilestoneTimeString,e.querySelector("#milestoneEdit--workOrderMilestoneDescription").value=n.workOrderMilestoneDescription},onshown:(e,t)=>{l=t,bulmaJS.toggleHtmlClipped(),e.querySelector("form").addEventListener("submit",c)},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})},c=()=>{const t=document.querySelector("#panel--milestones"),s=t.querySelectorAll(".panel-block");for(const e of s)e.remove();for(const s of e){const e=document.createElement("div");e.className="panel-block is-block container--milestone",e.dataset.workOrderMilestoneId=s.workOrderMilestoneId.toString(),e.innerHTML='
',s.workOrderMilestoneCompletionDate?e.querySelector(".button--reopenMilestone").addEventListener("click",a):(e.querySelector(".button--editMilestone").addEventListener("click",l),e.querySelector(".button--completeMilestone").addEventListener("click",r)),e.querySelector(".button--deleteMilestone").addEventListener("click",n),t.append(e)}bulmaJS.init(t)};c(),document.querySelector("#button--addMilestone").addEventListener("click",()=>{let e;const r=s=>{s.preventDefault(),cityssm.postJSON(t+"/workOrders/doAddWorkOrderMilestone",s.currentTarget,t=>{o(t),t.success&&e()})};cityssm.openHtmlModal("workOrder-addMilestone",{onshow:e=>{e.querySelector("#milestoneAdd--workOrderId").value=s;const t=e.querySelector("#milestoneAdd--workOrderMilestoneTypeId");for(const e of exports.workOrderMilestoneTypes){const s=document.createElement("option");s.value=e.workOrderMilestoneTypeId.toString(),s.textContent=e.workOrderMilestoneType,t.append(s)}e.querySelector("#milestoneAdd--workOrderMilestoneDateString").valueAsDate=new Date},onshown:(t,s)=>{e=s,bulmaJS.toggleHtmlClipped(),t.querySelector("form").addEventListener("submit",r)},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})})}})();
\ No newline at end of file
+"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=exports.los,t=document.querySelector("main").dataset.urlPrefix,o=document.querySelector("#workOrderEdit--workOrderId").value,s=""===o;if(e.initializeUnlockFieldButtons(document.querySelector("#form--workOrderEdit")),document.querySelector("#form--workOrderEdit").addEventListener("submit",e=>{e.preventDefault(),cityssm.postJSON(t+"/workOrders/"+(s?"doCreateWorkOrder":"doUpdateWorkOrder"),e.currentTarget,e=>{e.success?s?window.location.href=t+"/workOrders/"+e.workOrderId+"/edit":bulmaJS.alert({message:"Work Order Updated Successfully",contextualColorName:"success"}):bulmaJS.alert({title:"Error Updating Work Order",message:e.errorMessage,contextualColorName:"danger"})})}),!s){let s=exports.workOrderLots;delete exports.workOrderLots;let r=exports.workOrderLotOccupancies;delete exports.workOrderLotOccupancies;const a=e=>{const s=e.currentTarget.closest(".container--lotOccupancy").dataset.lotOccupancyId;bulmaJS.confirm({title:"Delete "+exports.aliases.lot+" "+exports.aliases.occupancy+" Relationship",message:"Are you sure you want to remove the relationship to this "+exports.aliases.lot.toLowerCase()+" "+exports.aliases.occupancy.toLowerCase()+" record from this work order? Note that the record will remain.",contextualColorName:"warning",okButton:{text:"Yes, Delete Relationship",callbackFunction:()=>{cityssm.postJSON(t+"/workOrders/doDeleteWorkOrderLotOccupancy",{workOrderId:o,lotOccupancyId:s},e=>{e.success?(r=e.workOrderLotOccupancies,u()):bulmaJS.alert({title:"Error Deleting Relationship",message:e.errorMessage,contextualColorName:"danger"})})}}})},n=(e,r)=>{cityssm.postJSON(t+"/workOrders/doAddWorkOrderLot",{workOrderId:o,lotId:e},e=>{e.success?(s=e.workOrderLots,u()):bulmaJS.alert({title:"Error Adding "+exports.aliases.lot,message:e.errorMessage,contextualColorName:"danger"}),r&&r(e.success)})},l=(e,s)=>{cityssm.postJSON(t+"/workOrders/doAddWorkOrderLotOccupancy",{workOrderId:o,lotOccupancyId:e},e=>{e.success?(r=e.workOrderLotOccupancies,u()):bulmaJS.alert({title:"Error Adding "+exports.aliases.occupancy,message:e.errorMessage,contextualColorName:"danger"}),s&&s(e.success)})},c=e=>{const t=e.currentTarget.dataset.lotId;n(t)},i=()=>{const e=document.querySelector("#container--lotOccupancies");if(document.querySelector(".tabs a[href='#relatedTab--lotOccupancies'] .tag").textContent=r.length.toString(),0===r.length)return void(e.innerHTML='
There are no '+exports.aliases.occupancies.toLowerCase()+" associated with this work order.
");e.innerHTML='
'+exports.aliases.occupancy+" Type
"+exports.aliases.lot+"
Start Date
End Date
"+exports.aliases.occupants+'
';const o=cityssm.dateToString(new Date);for(const n of r){const r=document.createElement("tr");r.className="container--lotOccupancy",r.dataset.lotOccupancyId=n.lotOccupancyId.toString();const l=!(n.occupancyEndDate&&n.occupancyEndDateStringn.lotId===e.lotId);r.innerHTML='
"+(n.occupancyEndDate?n.occupancyEndDateString:'(No End Date)')+"
"+(0===n.lotOccupancyOccupants.length?'(No '+cityssm.escapeHTML(exports.aliases.occupants)+")":cityssm.escapeHTML(n.lotOccupancyOccupants[0].occupantName)+(n.lotOccupancyOccupants.length>1?" plus "+(n.lotOccupancyOccupants.length-1):""))+'
'),n.lotId&&!i&&r.querySelector(".button--addLot").addEventListener("click",c),r.querySelector(".button--deleteLotOccupancy").addEventListener("click",a),e.querySelector("tbody").append(r)}},d=e=>{const r=e.currentTarget.closest(".container--lot").dataset.lotId;bulmaJS.confirm({title:"Delete "+exports.aliases.lot+" "+exports.aliases.occupancy+" Relationship",message:"Are you sure you want to remove the relationship to this "+exports.aliases.lot.toLowerCase()+" "+exports.aliases.occupancy.toLowerCase()+" record from this work order? Note that the record will remain.",contextualColorName:"warning",okButton:{text:"Yes, Delete Relationship",callbackFunction:()=>{cityssm.postJSON(t+"/workOrders/doDeleteWorkOrderLot",{workOrderId:o,lotId:r},e=>{e.success?(s=e.workOrderLots,u()):bulmaJS.alert({title:"Error Deleting Relationship",message:e.errorMessage,contextualColorName:"danger"})})}}})},p=()=>{const e=document.querySelector("#container--lots");if(document.querySelector(".tabs a[href='#relatedTab--lots'] .tag").textContent=s.length.toString(),0!==s.length){e.innerHTML='
'+exports.aliases.lot+"
"+exports.aliases.map+"
"+exports.aliases.lot+' Type
Status
';for(const o of s){const s=document.createElement("tr");s.className="container--lot",s.dataset.lotId=o.lotId.toString(),s.innerHTML='
";for(const t of e.lotOccupancies){const e=document.createElement("tr");e.className="container--lotOccupancy",e.dataset.lotOccupancyId=t.lotOccupancyId.toString(),e.innerHTML='
'+cityssm.escapeHTML(t.occupancyType)+"
",t.lotId?e.insertAdjacentHTML("beforeend","
"+cityssm.escapeHTML(t.lotName)+"
"):e.insertAdjacentHTML("beforeend",'
(No '+exports.aliases.lot+")
"),e.insertAdjacentHTML("beforeend","
"+t.occupancyStartDateString+"
"+(t.occupancyEndDate?t.occupancyEndDateString:'(No End Date)')+"
"+(0===t.lotOccupancyOccupants.length?'(No '+cityssm.escapeHTML(exports.aliases.occupants)+")":cityssm.escapeHTML(t.lotOccupancyOccupants[0].occupantName)+(t.lotOccupancyOccupants.length>1?" plus "+(t.lotOccupancyOccupants.length-1):""))+"
There are no records that meet the search criteria.
'})};cityssm.openHtmlModal("workOrder-addLot",{onshow:t=>{e.populateAliases(t),s=t.querySelector("form"),r=t.querySelector("#resultsContainer--lotAdd"),t.querySelector("#lotSearch--notWorkOrderId").value=o;const a=t.querySelector("#lotSearch--lotStatusId");for(const e of exports.lotStatuses){const t=document.createElement("option");t.value=e.lotStatusId.toString(),t.textContent=e.lotStatus,a.append(t)}l()},onshown:e=>{bulmaJS.toggleHtmlClipped(),e.querySelector("#lotSearch--lotName").addEventListener("change",l),e.querySelector("#lotSearch--lotStatusId").addEventListener("change",l),s.addEventListener("submit",l)},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})})}if(!s){let e=exports.workOrderMilestones;delete exports.workOrderMilestones;const s=t=>{t.success?(e=t.workOrderMilestones,c()):bulmaJS.alert({title:"Error Reopening Milestone",message:t.errorMessage,contextualColorName:"danger"})},r=r=>{r.preventDefault();const a=cityssm.dateToString(new Date),n=Number.parseInt(r.currentTarget.closest(".container--milestone").dataset.workOrderMilestoneId,10),l=e.find(e=>e.workOrderMilestoneId===n);bulmaJS.confirm({title:"Complete Milestone",message:"Are you sure you want to complete this milestone?"+(l.workOrderMilestoneDateString>a?" Note that this milestone is expected to be completed in the future.":""),messageIsHtml:!0,contextualColorName:"warning",okButton:{text:"Yes, Complete Milestone",callbackFunction:()=>{cityssm.postJSON(t+"/workOrders/doCompleteWorkOrderMilestone",{workOrderId:o,workOrderMilestoneId:n},s)}}})},a=e=>{e.preventDefault();const r=e.currentTarget.closest(".container--milestone").dataset.workOrderMilestoneId;bulmaJS.confirm({title:"Reopen Milestone",message:"Are you sure you want to remove the completion status from this milestone, and reopen it?",contextualColorName:"warning",okButton:{text:"Yes, Reopen Milestone",callbackFunction:()=>{cityssm.postJSON(t+"/workOrders/doReopenWorkOrderMilestone",{workOrderId:o,workOrderMilestoneId:r},s)}}})},n=e=>{e.preventDefault();const r=e.currentTarget.closest(".container--milestone").dataset.workOrderMilestoneId;bulmaJS.confirm({title:"Delete Milestone",message:"Are you sure you want to delete this milestone?",contextualColorName:"warning",okButton:{text:"Yes, Delete Milestone",callbackFunction:()=>{cityssm.postJSON(t+"/workOrders/doDeleteWorkOrderMilestone",{workOrderMilestoneId:r,workOrderId:o},s)}}})},l=r=>{r.preventDefault();const a=Number.parseInt(r.currentTarget.closest(".container--milestone").dataset.workOrderMilestoneId,10),n=e.find(e=>e.workOrderMilestoneId===a);let l;const c=e=>{e.preventDefault(),cityssm.postJSON(t+"/workOrders/doUpdateWorkOrderMilestone",e.currentTarget,e=>{s(e),e.success&&l()})};cityssm.openHtmlModal("workOrder-editMilestone",{onshow:e=>{e.querySelector("#milestoneEdit--workOrderId").value=o,e.querySelector("#milestoneEdit--workOrderMilestoneId").value=n.workOrderMilestoneId.toString();const t=e.querySelector("#milestoneEdit--workOrderMilestoneTypeId");let s=!1;for(const e of exports.workOrderMilestoneTypes){const o=document.createElement("option");o.value=e.workOrderMilestoneTypeId.toString(),o.textContent=e.workOrderMilestoneType,e.workOrderMilestoneTypeId===n.workOrderMilestoneTypeId&&(o.selected=!0,s=!0),t.append(o)}if(!s&&n.workOrderMilestoneTypeId){const e=document.createElement("option");e.value=n.workOrderMilestoneTypeId.toString(),e.textContent=n.workOrderMilestoneType,e.selected=!0,t.append(e)}e.querySelector("#milestoneEdit--workOrderMilestoneDateString").value=n.workOrderMilestoneDateString,e.querySelector("#milestoneEdit--workOrderMilestoneTimeString").value=n.workOrderMilestoneTimeString,e.querySelector("#milestoneEdit--workOrderMilestoneDescription").value=n.workOrderMilestoneDescription},onshown:(e,t)=>{l=t,bulmaJS.toggleHtmlClipped(),e.querySelector("form").addEventListener("submit",c)},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})},c=()=>{const t=document.querySelector("#panel--milestones"),o=t.querySelectorAll(".panel-block");for(const e of o)e.remove();for(const o of e){const e=document.createElement("div");e.className="panel-block is-block container--milestone",e.dataset.workOrderMilestoneId=o.workOrderMilestoneId.toString(),e.innerHTML='