create work order from lot occupancy

deepsource-autofix-76c6eb20
Dan Gowans 2022-12-05 13:17:42 -05:00
parent 9de9247f34
commit 727346777d
13 changed files with 263 additions and 53 deletions

View File

@ -1,4 +1,4 @@
import { getLotOccupantTypes, getLotStatuses, getLotTypes, getOccupancyTypes } from "../../helpers/functions.cache.js"; import { getLotOccupantTypes, getLotStatuses, getLotTypes, getOccupancyTypes, getWorkOrderTypes } from "../../helpers/functions.cache.js";
import * as configFunctions from "../../helpers/functions.config.js"; import * as configFunctions from "../../helpers/functions.config.js";
import { getLotOccupancy } from "../../helpers/lotOccupancyDB/getLotOccupancy.js"; import { getLotOccupancy } from "../../helpers/lotOccupancyDB/getLotOccupancy.js";
import { getMaps } from "../../helpers/lotOccupancyDB/getMaps.js"; import { getMaps } from "../../helpers/lotOccupancyDB/getMaps.js";
@ -13,6 +13,7 @@ export const handler = (request, response) => {
const lotTypes = getLotTypes(); const lotTypes = getLotTypes();
const lotStatuses = getLotStatuses(); const lotStatuses = getLotStatuses();
const maps = getMaps(); const maps = getMaps();
const workOrderTypes = getWorkOrderTypes();
return response.render("lotOccupancy-edit", { return response.render("lotOccupancy-edit", {
headTitle: configFunctions.getProperty("aliases.lot") + headTitle: configFunctions.getProperty("aliases.lot") +
" " + " " +
@ -24,6 +25,7 @@ export const handler = (request, response) => {
lotTypes, lotTypes,
lotStatuses, lotStatuses,
maps, maps,
workOrderTypes,
isCreate: false isCreate: false
}); });
}; };

View File

@ -4,7 +4,8 @@ import {
getLotOccupantTypes, getLotOccupantTypes,
getLotStatuses, getLotStatuses,
getLotTypes, getLotTypes,
getOccupancyTypes getOccupancyTypes,
getWorkOrderTypes
} from "../../helpers/functions.cache.js"; } from "../../helpers/functions.cache.js";
import * as configFunctions from "../../helpers/functions.config.js"; import * as configFunctions from "../../helpers/functions.config.js";
@ -27,6 +28,7 @@ export const handler: RequestHandler = (request, response) => {
const lotTypes = getLotTypes(); const lotTypes = getLotTypes();
const lotStatuses = getLotStatuses(); const lotStatuses = getLotStatuses();
const maps = getMaps(); const maps = getMaps();
const workOrderTypes = getWorkOrderTypes();
return response.render("lotOccupancy-edit", { return response.render("lotOccupancy-edit", {
headTitle: headTitle:
@ -41,6 +43,7 @@ export const handler: RequestHandler = (request, response) => {
lotTypes, lotTypes,
lotStatuses, lotStatuses,
maps, maps,
workOrderTypes,
isCreate: false isCreate: false
}); });

View File

@ -5,6 +5,7 @@ interface AddWorkOrderForm {
workOrderDescription: string; workOrderDescription: string;
workOrderOpenDateString?: string; workOrderOpenDateString?: string;
workOrderCloseDateString?: string; workOrderCloseDateString?: string;
lotOccupancyId?: string;
} }
export declare const addWorkOrder: (workOrderForm: AddWorkOrderForm, requestSession: recordTypes.PartialSession) => number; export declare const addWorkOrder: (workOrderForm: AddWorkOrderForm, requestSession: recordTypes.PartialSession) => number;
export default addWorkOrder; export default addWorkOrder;

View File

@ -2,6 +2,7 @@ import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import { getNextWorkOrderNumber } from "./getNextWorkOrderNumber.js"; import { getNextWorkOrderNumber } from "./getNextWorkOrderNumber.js";
import { dateStringToInteger, dateToInteger } from "@cityssm/expressjs-server-js/dateTimeFns.js"; import { dateStringToInteger, dateToInteger } from "@cityssm/expressjs-server-js/dateTimeFns.js";
import addWorkOrderLotOccupancy from "./addWorkOrderLotOccupancy.js";
export const addWorkOrder = (workOrderForm, requestSession) => { export const addWorkOrder = (workOrderForm, requestSession) => {
const database = sqlite(databasePath); const database = sqlite(databasePath);
const rightNow = new Date(); const rightNow = new Date();
@ -21,7 +22,14 @@ export const addWorkOrder = (workOrderForm, requestSession) => {
: dateToInteger(rightNow), workOrderForm.workOrderCloseDateString : dateToInteger(rightNow), workOrderForm.workOrderCloseDateString
? dateStringToInteger(workOrderForm.workOrderCloseDateString) ? dateStringToInteger(workOrderForm.workOrderCloseDateString)
: undefined, requestSession.user.userName, rightNow.getTime(), requestSession.user.userName, rightNow.getTime()); : undefined, requestSession.user.userName, rightNow.getTime(), requestSession.user.userName, rightNow.getTime());
const workOrderId = result.lastInsertRowid;
if (workOrderForm.lotOccupancyId) {
addWorkOrderLotOccupancy({
workOrderId,
lotOccupancyId: workOrderForm.lotOccupancyId
}, requestSession, database);
}
database.close(); database.close();
return result.lastInsertRowid; return workOrderId;
}; };
export default addWorkOrder; export default addWorkOrder;

View File

@ -4,12 +4,10 @@ import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import { getNextWorkOrderNumber } from "./getNextWorkOrderNumber.js"; import { getNextWorkOrderNumber } from "./getNextWorkOrderNumber.js";
import { import { dateStringToInteger, dateToInteger } from "@cityssm/expressjs-server-js/dateTimeFns.js";
dateStringToInteger,
dateToInteger
} from "@cityssm/expressjs-server-js/dateTimeFns.js";
import type * as recordTypes from "../../types/recordTypes"; import type * as recordTypes from "../../types/recordTypes";
import addWorkOrderLotOccupancy from "./addWorkOrderLotOccupancy.js";
interface AddWorkOrderForm { interface AddWorkOrderForm {
workOrderTypeId: number | string; workOrderTypeId: number | string;
@ -17,6 +15,7 @@ interface AddWorkOrderForm {
workOrderDescription: string; workOrderDescription: string;
workOrderOpenDateString?: string; workOrderOpenDateString?: string;
workOrderCloseDateString?: string; workOrderCloseDateString?: string;
lotOccupancyId?: string;
} }
export const addWorkOrder = ( export const addWorkOrder = (
@ -58,9 +57,22 @@ export const addWorkOrder = (
rightNow.getTime() rightNow.getTime()
); );
const workOrderId = result.lastInsertRowid as number;
if (workOrderForm.lotOccupancyId) {
addWorkOrderLotOccupancy(
{
workOrderId,
lotOccupancyId: workOrderForm.lotOccupancyId
},
requestSession,
database
);
}
database.close(); database.close();
return result.lastInsertRowid as number; return workOrderId;
}; };
export default addWorkOrder; export default addWorkOrder;

View File

@ -1,7 +1,8 @@
import sqlite from "better-sqlite3";
import type * as recordTypes from "../../types/recordTypes"; import type * as recordTypes from "../../types/recordTypes";
interface AddWorkOrderLotOccupancyForm { interface AddWorkOrderLotOccupancyForm {
workOrderId: number | string; workOrderId: number | string;
lotOccupancyId: number | string; lotOccupancyId: number | string;
} }
export declare const addWorkOrderLotOccupancy: (workOrderLotOccupancyForm: AddWorkOrderLotOccupancyForm, requestSession: recordTypes.PartialSession) => boolean; export declare const addWorkOrderLotOccupancy: (workOrderLotOccupancyForm: AddWorkOrderLotOccupancyForm, requestSession: recordTypes.PartialSession, connectedDatabase?: sqlite.Database) => boolean;
export default addWorkOrderLotOccupancy; export default addWorkOrderLotOccupancy;

View File

@ -1,7 +1,7 @@
import sqlite from "better-sqlite3"; import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
export const addWorkOrderLotOccupancy = (workOrderLotOccupancyForm, requestSession) => { export const addWorkOrderLotOccupancy = (workOrderLotOccupancyForm, requestSession, connectedDatabase) => {
const database = sqlite(databasePath); const database = connectedDatabase || sqlite(databasePath);
const rightNowMillis = Date.now(); const rightNowMillis = Date.now();
const row = database const row = database
.prepare("select recordDelete_timeMillis" + .prepare("select recordDelete_timeMillis" +
@ -33,7 +33,9 @@ export const addWorkOrderLotOccupancy = (workOrderLotOccupancyForm, requestSessi
" values (?, ?, ?, ?, ?, ?)") " values (?, ?, ?, ?, ?, ?)")
.run(workOrderLotOccupancyForm.workOrderId, workOrderLotOccupancyForm.lotOccupancyId, requestSession.user.userName, rightNowMillis, requestSession.user.userName, rightNowMillis); .run(workOrderLotOccupancyForm.workOrderId, workOrderLotOccupancyForm.lotOccupancyId, requestSession.user.userName, rightNowMillis, requestSession.user.userName, rightNowMillis);
} }
database.close(); if (!connectedDatabase) {
database.close();
}
return true; return true;
}; };
export default addWorkOrderLotOccupancy; export default addWorkOrderLotOccupancy;

View File

@ -11,9 +11,10 @@ interface AddWorkOrderLotOccupancyForm {
export const addWorkOrderLotOccupancy = ( export const addWorkOrderLotOccupancy = (
workOrderLotOccupancyForm: AddWorkOrderLotOccupancyForm, workOrderLotOccupancyForm: AddWorkOrderLotOccupancyForm,
requestSession: recordTypes.PartialSession requestSession: recordTypes.PartialSession,
connectedDatabase?: sqlite.Database
): boolean => { ): boolean => {
const database = sqlite(databasePath); const database = connectedDatabase || sqlite(databasePath);
const rightNowMillis = Date.now(); const rightNowMillis = Date.now();
@ -68,7 +69,9 @@ export const addWorkOrderLotOccupancy = (
); );
} }
database.close(); if (!connectedDatabase) {
database.close();
}
return true; return true;
}; };

View File

@ -1,6 +1,7 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
(() => { (() => {
var _a, _b, _c;
const los = exports.los; const los = exports.los;
const lotOccupancyId = document.querySelector("#lotOccupancy--lotOccupancyId").value; const lotOccupancyId = document.querySelector("#lotOccupancy--lotOccupancyId").value;
const isCreate = lotOccupancyId === ""; const isCreate = lotOccupancyId === "";
@ -75,7 +76,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
} }
}); });
}; };
document.querySelector("#button--copyLotOccupancy").addEventListener("click", (clickEvent) => { (_a = document
.querySelector("#button--copyLotOccupancy")) === null || _a === void 0 ? void 0 : _a.addEventListener("click", (clickEvent) => {
clickEvent.preventDefault(); clickEvent.preventDefault();
if (hasUnsavedChanges) { if (hasUnsavedChanges) {
bulmaJS.alert({ bulmaJS.alert({
@ -96,7 +98,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
}); });
} }
}); });
document.querySelector("#button--deleteLotOccupancy").addEventListener("click", (clickEvent) => { (_b = document
.querySelector("#button--deleteLotOccupancy")) === null || _b === void 0 ? void 0 : _b.addEventListener("click", (clickEvent) => {
clickEvent.preventDefault(); clickEvent.preventDefault();
const doDelete = () => { const doDelete = () => {
cityssm.postJSON(los.urlPrefix + "/lotOccupancies/doDeleteLotOccupancy", { cityssm.postJSON(los.urlPrefix + "/lotOccupancies/doDeleteLotOccupancy", {
@ -126,6 +129,55 @@ Object.defineProperty(exports, "__esModule", { value: true });
} }
}); });
}); });
(_c = document
.querySelector("#button--createWorkOrder")) === null || _c === void 0 ? void 0 : _c.addEventListener("click", (clickEvent) => {
clickEvent.preventDefault();
let createCloseModalFunction;
const doCreate = (formEvent) => {
formEvent.preventDefault();
cityssm.postJSON(los.urlPrefix + "/workOrders/doCreateWorkOrder", formEvent.currentTarget, (responseJSON) => {
if (responseJSON.success) {
createCloseModalFunction();
bulmaJS.confirm({
title: "Work Order Created Successfully",
message: "Would you like to open the work order now?",
contextualColorName: "success",
okButton: {
text: "Yes, Open the Work Order",
callbackFunction: () => {
window.location.href = los.urlPrefix + "/workOrders/" + responseJSON.workOrderId + "/edit";
}
}
});
}
else {
bulmaJS.alert({
title: "Error Creating Work Order",
message: responseJSON.errorMessage,
contextualColorName: "danger"
});
}
});
};
cityssm.openHtmlModal("lotOccupancy-createWorkOrder", {
onshow: (modalElement) => {
modalElement.querySelector("#workOrderCreate--lotOccupancyId").value = lotOccupancyId;
modalElement.querySelector("#workOrderCreate--workOrderOpenDateString").value = cityssm.dateToString(new Date());
const workOrderTypeSelectElement = modalElement.querySelector("#workOrderCreate--workOrderTypeId");
for (const workOrderType of exports.workOrderTypes) {
const optionElement = document.createElement("option");
optionElement.value = workOrderType.workOrderTypeId.toString();
optionElement.textContent = workOrderType.workOrderType;
workOrderTypeSelectElement.append(optionElement);
}
},
onshown: (modalElement, closeModalFunction) => {
var _a;
createCloseModalFunction = closeModalFunction;
(_a = modalElement.querySelector("form")) === null || _a === void 0 ? void 0 : _a.addEventListener("submit", doCreate);
}
});
});
} }
const occupancyTypeIdElement = document.querySelector("#lotOccupancy--occupancyTypeId"); const occupancyTypeIdElement = document.querySelector("#lotOccupancy--occupancyTypeId");
if (isCreate) { if (isCreate) {

View File

@ -86,7 +86,6 @@ declare const bulmaJS: BulmaJS;
} }
if (!isCreate) { if (!isCreate) {
const doCopy = () => { const doCopy = () => {
cityssm.postJSON( cityssm.postJSON(
los.urlPrefix + "/lotOccupancies/doCopyLotOccupancy", los.urlPrefix + "/lotOccupancies/doCopyLotOccupancy",
@ -116,12 +115,11 @@ declare const bulmaJS: BulmaJS;
); );
}; };
(document.querySelector("#button--copyLotOccupancy") as HTMLAnchorElement).addEventListener( document
"click", .querySelector("#button--copyLotOccupancy")
(clickEvent) => { ?.addEventListener("click", (clickEvent) => {
clickEvent.preventDefault(); clickEvent.preventDefault();
if (hasUnsavedChanges) { if (hasUnsavedChanges) {
bulmaJS.alert({ bulmaJS.alert({
title: "Unsaved Changes", title: "Unsaved Changes",
@ -139,46 +137,115 @@ declare const bulmaJS: BulmaJS;
} }
}); });
} }
} });
);
( document
document.querySelector("#button--deleteLotOccupancy") as HTMLAnchorElement .querySelector("#button--deleteLotOccupancy")
).addEventListener("click", (clickEvent) => { ?.addEventListener("click", (clickEvent) => {
clickEvent.preventDefault(); clickEvent.preventDefault();
const doDelete = () => {
cityssm.postJSON(
los.urlPrefix + "/lotOccupancies/doDeleteLotOccupancy",
{
lotOccupancyId
},
(responseJSON: { success: boolean; errorMessage?: string }) => {
if (responseJSON.success) {
cityssm.disableNavBlocker();
window.location.href =
los.urlPrefix + "/lotOccupancies?t=" + Date.now();
} else {
bulmaJS.alert({
title: "Error Deleting Record",
message: responseJSON.errorMessage || "",
contextualColorName: "danger"
});
}
}
);
};
bulmaJS.confirm({
title: "Delete " + exports.aliases.occupancy + " Record",
message: "Are you sure you want to delete this record?",
contextualColorName: "warning",
okButton: {
text: "Yes, Delete",
callbackFunction: doDelete
}
});
});
document
.querySelector("#button--createWorkOrder")
?.addEventListener("click", (clickEvent) => {
clickEvent.preventDefault();
let createCloseModalFunction: () => void;
const doCreate = (formEvent: SubmitEvent) => {
formEvent.preventDefault();
cityssm.postJSON(los.urlPrefix + "/workOrders/doCreateWorkOrder",
formEvent.currentTarget,
(responseJSON: {success: boolean; errorMessage?: string; workOrderId?: number}) => {
const doDelete = () => {
cityssm.postJSON(
los.urlPrefix + "/lotOccupancies/doDeleteLotOccupancy",
{
lotOccupancyId
},
(responseJSON: { success: boolean; errorMessage?: string }) => {
if (responseJSON.success) { if (responseJSON.success) {
cityssm.disableNavBlocker(); createCloseModalFunction();
window.location.href =
los.urlPrefix + "/lotOccupancies?t=" + Date.now(); bulmaJS.confirm({
title: "Work Order Created Successfully",
message: "Would you like to open the work order now?",
contextualColorName: "success",
okButton: {
text: "Yes, Open the Work Order",
callbackFunction: () => {
window.location.href = los.urlPrefix + "/workOrders/" + responseJSON.workOrderId + "/edit";
}
}
})
} else { } else {
bulmaJS.alert({ bulmaJS.alert({
title: "Error Deleting Record", title: "Error Creating Work Order",
message: responseJSON.errorMessage || "", message: responseJSON.errorMessage as string,
contextualColorName: "danger" contextualColorName: "danger"
}); });
} }
} });
); };
};
bulmaJS.confirm({ cityssm.openHtmlModal("lotOccupancy-createWorkOrder", {
title: "Delete " + exports.aliases.occupancy + " Record", onshow: (modalElement) => {
message: "Are you sure you want to delete this record?", (
contextualColorName: "warning", modalElement.querySelector(
okButton: { "#workOrderCreate--lotOccupancyId"
text: "Yes, Delete", ) as HTMLInputElement
callbackFunction: doDelete ).value = lotOccupancyId;
}
(
modalElement.querySelector(
"#workOrderCreate--workOrderOpenDateString"
) as HTMLInputElement
).value = cityssm.dateToString(new Date());
const workOrderTypeSelectElement = modalElement.querySelector("#workOrderCreate--workOrderTypeId") as HTMLSelectElement;
for (const workOrderType of (exports.workOrderTypes as recordTypes.WorkOrderType[])) {
const optionElement = document.createElement("option");
optionElement.value = (workOrderType.workOrderTypeId as number).toString();
optionElement.textContent = workOrderType.workOrderType as string;
workOrderTypeSelectElement.append(optionElement);
}
},
onshown: (modalElement, closeModalFunction) => {
createCloseModalFunction = closeModalFunction;
modalElement.querySelector("form")?.addEventListener("submit", doCreate);
}
});
}); });
});
} }
// Occupancy Type // Occupancy Type

View File

@ -0,0 +1,52 @@
<div class="modal" role="dialog">
<div class="modal-background"></div>
<div class="modal-card">
<header class="modal-card-head">
<h3 class="modal-card-title">
Create a New Work Order
</h3>
<button class="delete is-close-modal-button" aria-label="close" type="button"></button>
</header>
<section class="modal-card-body">
<form id="form--workOrderCreate">
<input id="workOrderCreate--lotOccupancyId" name="lotOccupancyId" type="hidden" value="" />
<input id="workOrderCreate--workOrderOpenDateString" name="workOrderOpenDateString" type="hidden" value="" />
<label class="label" for="workOrderCreate--workOrderNumber">Work Order Number</label>
<div class="field has-addons">
<div class="control is-expanded">
<input class="input" id="workOrderCreate--workOrderNumber" name="workOrderNumber" maxlength="50" readonly />
</div>
<div class="control">
<button class="button is-unlock-field-button" data-tooltip="Unlock Field" type="button" aria-label="Unlock Field">
<i class="fas fa-unlock" aria-hidden="true"></i>
</button>
</div>
</div>
<p class="help mb-2">Leave work order number blank to autopopulate.</p>
<div class="field">
<label class="label" for="workOrderCreate--workOrderTypeId">Work Order Type</label>
<div class="control">
<div class="select is-fullwidth">
<select id="workOrderCreate--workOrderTypeId" name="workOrderTypeId" required>
<option value="">(Select Type)</option>
</select>
</div>
</div>
</div>
<div class="field">
<label class="label" for="workOrderCreate--workOrderDescription">Description</label>
<div class="control">
<textarea class="textarea" id="workOrderCreate--workOrderDescription" name="workOrderDescription" required></textarea>
</div>
</div>
</form>
</section>
<footer class="modal-card-foot justify-right">
<button class="button is-success" type="submit" form="form--workOrderCreate">
<span class="icon"><i class="fas fa-plus" aria-hidden="true"></i></span>
<span>Create Work Order</span>
</button>
<button class="button is-close-modal-button" type="button">Cancel</button>
</footer>
</div>
</div>

File diff suppressed because one or more lines are too long

View File

@ -282,6 +282,11 @@
</div> </div>
<div class="dropdown-menu"> <div class="dropdown-menu">
<div class="dropdown-content"> <div class="dropdown-content">
<a class="dropdown-item" id="button--createWorkOrder" href="#">
<span class="icon is-small"><i class="fas fa-plus" aria-hidden="true"></i></span>
<span>Create a Work Order</span>
</a>
<hr class="dropdown-divider" />
<a class="dropdown-item" id="button--copyLotOccupancy" href="#"> <a class="dropdown-item" id="button--copyLotOccupancy" href="#">
<span class="icon is-small"><i class="far fa-copy" aria-hidden="true"></i></span> <span class="icon is-small"><i class="far fa-copy" aria-hidden="true"></i></span>
<span>Copy <%= configFunctions.getProperty("aliases.occupancy") %> Record as New</span> <span>Copy <%= configFunctions.getProperty("aliases.occupancy") %> Record as New</span>
@ -406,6 +411,8 @@
exports.lotOccupancyComments = <%- JSON.stringify(lotOccupancy.lotOccupancyComments) %>; exports.lotOccupancyComments = <%- JSON.stringify(lotOccupancy.lotOccupancyComments) %>;
exports.lotOccupancyFees = <%- JSON.stringify(lotOccupancy.lotOccupancyFees) %>; exports.lotOccupancyFees = <%- JSON.stringify(lotOccupancy.lotOccupancyFees) %>;
exports.lotOccupancyTransactions = <%- JSON.stringify(lotOccupancy.lotOccupancyTransactions) %>; exports.lotOccupancyTransactions = <%- JSON.stringify(lotOccupancy.lotOccupancyTransactions) %>;
exports.workOrderTypes = <%- JSON.stringify(workOrderTypes) %>;
<% } %> <% } %>
<% if (configFunctions.getProperty("settings.lot.lotNamePattern")) { %> <% if (configFunctions.getProperty("settings.lot.lotNamePattern")) { %>