From 9af03a05e6d3cadec3716837a8ad44df824fa837 Mon Sep 17 00:00:00 2001 From: Dan Gowans Date: Mon, 29 Aug 2022 16:10:58 -0400 Subject: [PATCH] work order search --- handlers/lots-post/doCreateLot.ts | 18 ++- handlers/lots-post/doSearchLots.ts | 24 +-- handlers/lots-post/doUpdateLot.ts | 18 ++- handlers/workOrders-get/search.js | 5 +- handlers/workOrders-get/search.ts | 7 +- .../workOrders-post/doSearchWorkOrders.d.ts | 3 + .../workOrders-post/doSearchWorkOrders.js | 12 ++ .../workOrders-post/doSearchWorkOrders.ts | 24 +++ helpers/lotOccupancyDB/addMap.ts | 63 ++++---- helpers/lotOccupancyDB/addWorkOrder.d.ts | 10 ++ helpers/lotOccupancyDB/addWorkOrder.js | 18 +++ helpers/lotOccupancyDB/addWorkOrder.ts | 50 ++++++ helpers/lotOccupancyDB/addWorkOrderLot.d.ts | 7 + helpers/lotOccupancyDB/addWorkOrderLot.js | 16 ++ helpers/lotOccupancyDB/addWorkOrderLot.ts | 42 +++++ helpers/lotOccupancyDB/getWorkOrders.d.ts | 13 ++ helpers/lotOccupancyDB/getWorkOrders.js | 43 ++++++ helpers/lotOccupancyDB/getWorkOrders.ts | 78 ++++++++++ package-lock.json | 104 +++++++------ package.json | 2 +- public-typescript/workOrderSearch.d.ts | 1 + public-typescript/workOrderSearch.js | 107 +++++++++++++ public-typescript/workOrderSearch.ts | 146 ++++++++++++++++++ public/javascripts/workOrderSearch.min.js | 1 + routes/workOrders.js | 2 + routes/workOrders.ts | 11 +- temp/legacy.importFromCSV.js | 54 ++++--- temp/legacy.importFromCSV.ts | 69 ++++++--- types/recordTypes.d.ts | 12 ++ types/recordTypes.js | 3 +- types/recordTypes.ts | 21 ++- views/workOrder-search.ejs | 27 ++++ 32 files changed, 865 insertions(+), 146 deletions(-) create mode 100644 handlers/workOrders-post/doSearchWorkOrders.d.ts create mode 100644 handlers/workOrders-post/doSearchWorkOrders.js create mode 100644 handlers/workOrders-post/doSearchWorkOrders.ts create mode 100644 helpers/lotOccupancyDB/addWorkOrder.d.ts create mode 100644 helpers/lotOccupancyDB/addWorkOrder.js create mode 100644 helpers/lotOccupancyDB/addWorkOrder.ts create mode 100644 helpers/lotOccupancyDB/addWorkOrderLot.d.ts create mode 100644 helpers/lotOccupancyDB/addWorkOrderLot.js create mode 100644 helpers/lotOccupancyDB/addWorkOrderLot.ts create mode 100644 helpers/lotOccupancyDB/getWorkOrders.d.ts create mode 100644 helpers/lotOccupancyDB/getWorkOrders.js create mode 100644 helpers/lotOccupancyDB/getWorkOrders.ts create mode 100644 public-typescript/workOrderSearch.d.ts create mode 100644 public-typescript/workOrderSearch.js create mode 100644 public-typescript/workOrderSearch.ts create mode 100644 public/javascripts/workOrderSearch.min.js diff --git a/handlers/lots-post/doCreateLot.ts b/handlers/lots-post/doCreateLot.ts index bd383b06..21a7b324 100644 --- a/handlers/lots-post/doCreateLot.ts +++ b/handlers/lots-post/doCreateLot.ts @@ -1,16 +1,20 @@ -import type { RequestHandler } from "express"; +import type { + RequestHandler +} from "express"; -import { addLot } from "../../helpers/lotOccupancyDB/addLot.js"; +import { + addLot +} from "../../helpers/lotOccupancyDB/addLot.js"; export const handler: RequestHandler = async (request, response) => { - const lotId = addLot(request.body, request.session); + const lotId = addLot(request.body, request.session); - response.json({ - success: true, - lotId - }); + response.json({ + success: true, + lotId + }); }; diff --git a/handlers/lots-post/doSearchLots.ts b/handlers/lots-post/doSearchLots.ts index 3fd55d52..0ad31a09 100644 --- a/handlers/lots-post/doSearchLots.ts +++ b/handlers/lots-post/doSearchLots.ts @@ -1,19 +1,23 @@ -import type { RequestHandler } from "express"; +import type { + RequestHandler +} from "express"; -import { getLots } from "../../helpers/lotOccupancyDB/getLots.js"; +import { + getLots +} from "../../helpers/lotOccupancyDB/getLots.js"; export const handler: RequestHandler = async (request, response) => { - const result = getLots(request.body, { - limit: request.body.limit, - offset: request.body.offset - }); + const result = getLots(request.body, { + limit: request.body.limit, + offset: request.body.offset + }); - response.json({ - count: result.count, - lots: result.lots - }); + response.json({ + count: result.count, + lots: result.lots + }); }; diff --git a/handlers/lots-post/doUpdateLot.ts b/handlers/lots-post/doUpdateLot.ts index 060e6f50..081527e2 100644 --- a/handlers/lots-post/doUpdateLot.ts +++ b/handlers/lots-post/doUpdateLot.ts @@ -1,16 +1,20 @@ -import type { RequestHandler } from "express"; +import type { + RequestHandler +} from "express"; -import { updateLot } from "../../helpers/lotOccupancyDB/updateLot.js"; +import { + updateLot +} from "../../helpers/lotOccupancyDB/updateLot.js"; export const handler: RequestHandler = async (request, response) => { - const success = updateLot(request.body, request.session); + const success = updateLot(request.body, request.session); - response.json({ - success, - lotId: request.body.lotId - }); + response.json({ + success, + lotId: request.body.lotId + }); }; diff --git a/handlers/workOrders-get/search.js b/handlers/workOrders-get/search.js index 4bc88699..54d0524b 100644 --- a/handlers/workOrders-get/search.js +++ b/handlers/workOrders-get/search.js @@ -1,6 +1,9 @@ +import { getWorkOrderTypes } from "../../helpers/functions.cache.js"; export const handler = (request, response) => { + const workOrderTypes = getWorkOrderTypes(); response.render("workOrder-search", { - headTitle: "Work Order Search" + headTitle: "Work Order Search", + workOrderTypes }); }; export default handler; diff --git a/handlers/workOrders-get/search.ts b/handlers/workOrders-get/search.ts index dd1c6cf8..0d2cc2ef 100644 --- a/handlers/workOrders-get/search.ts +++ b/handlers/workOrders-get/search.ts @@ -2,11 +2,16 @@ import type { RequestHandler } from "express"; +import { getWorkOrderTypes } from "../../helpers/functions.cache.js"; + export const handler: RequestHandler = (request, response) => { + const workOrderTypes = getWorkOrderTypes(); + response.render("workOrder-search", { - headTitle: "Work Order Search" + headTitle: "Work Order Search", + workOrderTypes }); }; diff --git a/handlers/workOrders-post/doSearchWorkOrders.d.ts b/handlers/workOrders-post/doSearchWorkOrders.d.ts new file mode 100644 index 00000000..9621c611 --- /dev/null +++ b/handlers/workOrders-post/doSearchWorkOrders.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/doSearchWorkOrders.js b/handlers/workOrders-post/doSearchWorkOrders.js new file mode 100644 index 00000000..c47d7657 --- /dev/null +++ b/handlers/workOrders-post/doSearchWorkOrders.js @@ -0,0 +1,12 @@ +import { getWorkOrders } from "../../helpers/lotOccupancyDB/getWorkOrders.js"; +export const handler = async (request, response) => { + const result = getWorkOrders(request.body, { + limit: request.body.limit, + offset: request.body.offset + }); + response.json({ + count: result.count, + workOrders: result.workOrders + }); +}; +export default handler; diff --git a/handlers/workOrders-post/doSearchWorkOrders.ts b/handlers/workOrders-post/doSearchWorkOrders.ts new file mode 100644 index 00000000..e09abf86 --- /dev/null +++ b/handlers/workOrders-post/doSearchWorkOrders.ts @@ -0,0 +1,24 @@ +import type { + RequestHandler +} from "express"; + +import { + getWorkOrders +} from "../../helpers/lotOccupancyDB/getWorkOrders.js"; + + +export const handler: RequestHandler = async (request, response) => { + + const result = getWorkOrders(request.body, { + limit: request.body.limit, + offset: request.body.offset + }); + + response.json({ + count: result.count, + workOrders: result.workOrders + }); +}; + + +export default handler; \ No newline at end of file diff --git a/helpers/lotOccupancyDB/addMap.ts b/helpers/lotOccupancyDB/addMap.ts index dad05a5a..092ecc6d 100644 --- a/helpers/lotOccupancyDB/addMap.ts +++ b/helpers/lotOccupancyDB/addMap.ts @@ -1,5 +1,8 @@ import sqlite from "better-sqlite3"; -import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; + +import { + lotOccupancyDB as databasePath +} from "../../data/databasePaths.js"; import type * as recordTypes from "../../types/recordTypes"; @@ -20,40 +23,40 @@ interface AddMapForm { export const addMap = - (mapForm: AddMapForm, requestSession: recordTypes.PartialSession): number => { + (mapForm: AddMapForm, requestSession: recordTypes.PartialSession): number => { - const database = sqlite(databasePath); + const database = sqlite(databasePath); - const rightNowMillis = Date.now(); + const rightNowMillis = Date.now(); - const result = database - .prepare("insert into Maps (" + - "mapName, mapDescription," + - " mapSVG, mapLatitude, mapLongitude," + - " mapAddress1, mapAddress2, mapCity, mapProvince, mapPostalCode, mapPhoneNumber," + - " recordCreate_userName, recordCreate_timeMillis," + - " recordUpdate_userName, recordUpdate_timeMillis)" + - " values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") - .run(mapForm.mapName, - mapForm.mapDescription, - mapForm.mapSVG, - (mapForm.mapLatitude === "" ? undefined : mapForm.mapLatitude), - (mapForm.mapLongitude === "" ? undefined : mapForm.mapLongitude), - mapForm.mapAddress1, - mapForm.mapAddress2, - mapForm.mapCity, - mapForm.mapProvince, - mapForm.mapPostalCode, - mapForm.mapPhoneNumber, - requestSession.user.userName, - rightNowMillis, - requestSession.user.userName, - rightNowMillis); + const result = database + .prepare("insert into Maps (" + + "mapName, mapDescription," + + " mapSVG, mapLatitude, mapLongitude," + + " mapAddress1, mapAddress2, mapCity, mapProvince, mapPostalCode, mapPhoneNumber," + + " recordCreate_userName, recordCreate_timeMillis," + + " recordUpdate_userName, recordUpdate_timeMillis)" + + " values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") + .run(mapForm.mapName, + mapForm.mapDescription, + mapForm.mapSVG, + (mapForm.mapLatitude === "" ? undefined : mapForm.mapLatitude), + (mapForm.mapLongitude === "" ? undefined : mapForm.mapLongitude), + mapForm.mapAddress1, + mapForm.mapAddress2, + mapForm.mapCity, + mapForm.mapProvince, + mapForm.mapPostalCode, + mapForm.mapPhoneNumber, + requestSession.user.userName, + rightNowMillis, + requestSession.user.userName, + rightNowMillis); - database.close(); + database.close(); - return result.lastInsertRowid as number; - }; + return result.lastInsertRowid as number; + }; export default addMap; \ No newline at end of file diff --git a/helpers/lotOccupancyDB/addWorkOrder.d.ts b/helpers/lotOccupancyDB/addWorkOrder.d.ts new file mode 100644 index 00000000..e36afd7b --- /dev/null +++ b/helpers/lotOccupancyDB/addWorkOrder.d.ts @@ -0,0 +1,10 @@ +import type * as recordTypes from "../../types/recordTypes"; +interface AddWorkOrderForm { + workOrderTypeId: number | string; + workOrderNumber: string; + workOrderDescription: string; + workOrderOpenDateString?: string; + workOrderCloseDateString?: string; +} +export declare const addWorkOrder: (workOrderForm: AddWorkOrderForm, requestSession: recordTypes.PartialSession) => number; +export default addWorkOrder; diff --git a/helpers/lotOccupancyDB/addWorkOrder.js b/helpers/lotOccupancyDB/addWorkOrder.js new file mode 100644 index 00000000..81289689 --- /dev/null +++ b/helpers/lotOccupancyDB/addWorkOrder.js @@ -0,0 +1,18 @@ +import { dateStringToInteger, dateToInteger } from "@cityssm/expressjs-server-js/dateTimeFns.js"; +import sqlite from "better-sqlite3"; +import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; +export const addWorkOrder = (workOrderForm, requestSession) => { + const database = sqlite(databasePath); + const rightNow = new Date(); + const result = database + .prepare("insert into WorkOrders (" + + "workOrderTypeId, workOrderNumber, workOrderDescription," + + " workOrderOpenDate, workOrderCloseDate," + + " recordCreate_userName, recordCreate_timeMillis," + + " recordUpdate_userName, recordUpdate_timeMillis)" + + " values (?, ?, ?, ?, ?, ?, ?, ?, ?)") + .run(workOrderForm.workOrderTypeId, workOrderForm.workOrderNumber, workOrderForm.workOrderDescription, (workOrderForm.workOrderOpenDateString ? dateStringToInteger(workOrderForm.workOrderOpenDateString) : dateToInteger(rightNow)), (workOrderForm.workOrderCloseDateString ? dateStringToInteger(workOrderForm.workOrderCloseDateString) : undefined), requestSession.user.userName, rightNow.getTime(), requestSession.user.userName, rightNow.getTime()); + database.close(); + return result.lastInsertRowid; +}; +export default addWorkOrder; diff --git a/helpers/lotOccupancyDB/addWorkOrder.ts b/helpers/lotOccupancyDB/addWorkOrder.ts new file mode 100644 index 00000000..4a62b071 --- /dev/null +++ b/helpers/lotOccupancyDB/addWorkOrder.ts @@ -0,0 +1,50 @@ +import { dateStringToInteger, dateToInteger } from "@cityssm/expressjs-server-js/dateTimeFns.js"; +import sqlite from "better-sqlite3"; + +import { + lotOccupancyDB as databasePath +} from "../../data/databasePaths.js"; + +import type * as recordTypes from "../../types/recordTypes"; + + +interface AddWorkOrderForm { + workOrderTypeId: number | string; + workOrderNumber: string; + workOrderDescription: string; + workOrderOpenDateString?: string; + workOrderCloseDateString?: string; +} + + +export const addWorkOrder = + (workOrderForm: AddWorkOrderForm, requestSession: recordTypes.PartialSession): number => { + + const database = sqlite(databasePath); + + const rightNow = new Date(); + + const result = database + .prepare("insert into WorkOrders (" + + "workOrderTypeId, workOrderNumber, workOrderDescription," + + " workOrderOpenDate, workOrderCloseDate," + + " recordCreate_userName, recordCreate_timeMillis," + + " recordUpdate_userName, recordUpdate_timeMillis)" + + " values (?, ?, ?, ?, ?, ?, ?, ?, ?)") + .run(workOrderForm.workOrderTypeId, + workOrderForm.workOrderNumber, + workOrderForm.workOrderDescription, + (workOrderForm.workOrderOpenDateString ? dateStringToInteger(workOrderForm.workOrderOpenDateString) : dateToInteger(rightNow)), + (workOrderForm.workOrderCloseDateString ? dateStringToInteger(workOrderForm.workOrderCloseDateString) : undefined), + requestSession.user.userName, + rightNow.getTime(), + requestSession.user.userName, + rightNow.getTime()); + + database.close(); + + return result.lastInsertRowid as number; + }; + + +export default addWorkOrder; \ No newline at end of file diff --git a/helpers/lotOccupancyDB/addWorkOrderLot.d.ts b/helpers/lotOccupancyDB/addWorkOrderLot.d.ts new file mode 100644 index 00000000..35bc832d --- /dev/null +++ b/helpers/lotOccupancyDB/addWorkOrderLot.d.ts @@ -0,0 +1,7 @@ +import type * as recordTypes from "../../types/recordTypes"; +interface AddWorkOrderLotForm { + workOrderId: number | string; + lotId: number | string; +} +export declare const addWorkOrderLot: (workOrderLotForm: AddWorkOrderLotForm, requestSession: recordTypes.PartialSession) => boolean; +export default addWorkOrderLot; diff --git a/helpers/lotOccupancyDB/addWorkOrderLot.js b/helpers/lotOccupancyDB/addWorkOrderLot.js new file mode 100644 index 00000000..916d17a0 --- /dev/null +++ b/helpers/lotOccupancyDB/addWorkOrderLot.js @@ -0,0 +1,16 @@ +import sqlite from "better-sqlite3"; +import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; +export const addWorkOrderLot = (workOrderLotForm, requestSession) => { + const database = sqlite(databasePath); + const rightNowMillis = Date.now(); + const result = database + .prepare("insert into WorkOrderLots (" + + "workOrderId, lotId," + + " recordCreate_userName, recordCreate_timeMillis," + + " recordUpdate_userName, recordUpdate_timeMillis)" + + " values (?, ?, ?, ?, ?, ?)") + .run(workOrderLotForm.workOrderId, workOrderLotForm.lotId, requestSession.user.userName, rightNowMillis, requestSession.user.userName, rightNowMillis); + database.close(); + return result.changes > 0; +}; +export default addWorkOrderLot; diff --git a/helpers/lotOccupancyDB/addWorkOrderLot.ts b/helpers/lotOccupancyDB/addWorkOrderLot.ts new file mode 100644 index 00000000..b1c0695a --- /dev/null +++ b/helpers/lotOccupancyDB/addWorkOrderLot.ts @@ -0,0 +1,42 @@ +import sqlite from "better-sqlite3"; + +import { + lotOccupancyDB as databasePath +} from "../../data/databasePaths.js"; + +import type * as recordTypes from "../../types/recordTypes"; + + +interface AddWorkOrderLotForm { + workOrderId: number | string; + lotId: number | string; +} + + +export const addWorkOrderLot = + (workOrderLotForm: AddWorkOrderLotForm, requestSession: recordTypes.PartialSession): boolean => { + + const database = sqlite(databasePath); + + const rightNowMillis = Date.now(); + + const result = database + .prepare("insert into WorkOrderLots (" + + "workOrderId, lotId," + + " recordCreate_userName, recordCreate_timeMillis," + + " recordUpdate_userName, recordUpdate_timeMillis)" + + " values (?, ?, ?, ?, ?, ?)") + .run(workOrderLotForm.workOrderId, + workOrderLotForm.lotId, + requestSession.user.userName, + rightNowMillis, + requestSession.user.userName, + rightNowMillis); + + database.close(); + + return result.changes > 0; + }; + + +export default addWorkOrderLot; \ No newline at end of file diff --git a/helpers/lotOccupancyDB/getWorkOrders.d.ts b/helpers/lotOccupancyDB/getWorkOrders.d.ts new file mode 100644 index 00000000..e66886e4 --- /dev/null +++ b/helpers/lotOccupancyDB/getWorkOrders.d.ts @@ -0,0 +1,13 @@ +import type * as recordTypes from "../../types/recordTypes"; +interface GetWorkOrdersFilters { + workOrderTypeId?: number | string; +} +interface GetWorkOrdersOptions { + limit: number; + offset: number; +} +export declare const getWorkOrders: (filters?: GetWorkOrdersFilters, options?: GetWorkOrdersOptions) => { + count: number; + workOrders: recordTypes.WorkOrder[]; +}; +export default getWorkOrders; diff --git a/helpers/lotOccupancyDB/getWorkOrders.js b/helpers/lotOccupancyDB/getWorkOrders.js new file mode 100644 index 00000000..84bbef82 --- /dev/null +++ b/helpers/lotOccupancyDB/getWorkOrders.js @@ -0,0 +1,43 @@ +import sqlite from "better-sqlite3"; +import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; +import { dateIntegerToString } from "@cityssm/expressjs-server-js/dateTimeFns.js"; +export const getWorkOrders = (filters, options) => { + const database = sqlite(databasePath, { + readonly: true + }); + database.function("userFn_dateIntegerToString", dateIntegerToString); + let sqlWhereClause = " where w.recordDelete_timeMillis is null"; + const sqlParameters = []; + if (filters.workOrderTypeId) { + sqlWhereClause += " and w.workOrderTypeId = ?"; + sqlParameters.push(filters.workOrderTypeId); + } + const count = database.prepare("select count(*) as recordCount" + + " from WorkOrders w" + + sqlWhereClause) + .get(sqlParameters) + .recordCount; + let workOrders = []; + if (count > 0) { + workOrders = database + .prepare("select w.workOrderId," + + " w.workOrderTypeId, t.workOrderType," + + " w.workOrderNumber, w.workOrderDescription," + + " w.workOrderOpenDate, userFn_dateIntegerToString(w.workOrderOpenDate) as workOrderOpenDateString," + + " w.workOrderCloseDate, userFn_dateIntegerToString(w.workOrderCloseDate) as workOrderCloseDateString" + + " from WorkOrders w" + + " left join WorkOrderTypes t on w.workOrderTypeId = t.workOrderTypeId" + + sqlWhereClause + + " order by w.workOrderOpenDate desc, w.workOrderNumber" + + (options ? + " limit " + options.limit + " offset " + options.offset : + "")) + .all(sqlParameters); + } + database.close(); + return { + count, + workOrders + }; +}; +export default getWorkOrders; diff --git a/helpers/lotOccupancyDB/getWorkOrders.ts b/helpers/lotOccupancyDB/getWorkOrders.ts new file mode 100644 index 00000000..9821ccf0 --- /dev/null +++ b/helpers/lotOccupancyDB/getWorkOrders.ts @@ -0,0 +1,78 @@ +import sqlite from "better-sqlite3"; + +import { + lotOccupancyDB as databasePath +} from "../../data/databasePaths.js"; + +import { + dateIntegerToString +} from "@cityssm/expressjs-server-js/dateTimeFns.js"; + +import type * as recordTypes from "../../types/recordTypes"; + + +interface GetWorkOrdersFilters { + workOrderTypeId ? : number | string; +} + +interface GetWorkOrdersOptions { + limit: number; + offset: number; +} + + +export const getWorkOrders = (filters ? : GetWorkOrdersFilters, options ? : GetWorkOrdersOptions): { + count: number; + workOrders: recordTypes.WorkOrder[]; +} => { + + const database = sqlite(databasePath, { + readonly: true + }); + + database.function("userFn_dateIntegerToString", dateIntegerToString); + + let sqlWhereClause = " where w.recordDelete_timeMillis is null"; + const sqlParameters = []; + + if (filters.workOrderTypeId) { + sqlWhereClause += " and w.workOrderTypeId = ?"; + sqlParameters.push(filters.workOrderTypeId); + } + + const count: number = database.prepare("select count(*) as recordCount" + + " from WorkOrders w" + + sqlWhereClause) + .get(sqlParameters) + .recordCount; + + let workOrders: recordTypes.WorkOrder[] = []; + + if (count > 0) { + + workOrders = database + .prepare("select w.workOrderId," + + " w.workOrderTypeId, t.workOrderType," + + " w.workOrderNumber, w.workOrderDescription," + + " w.workOrderOpenDate, userFn_dateIntegerToString(w.workOrderOpenDate) as workOrderOpenDateString," + + " w.workOrderCloseDate, userFn_dateIntegerToString(w.workOrderCloseDate) as workOrderCloseDateString" + + " from WorkOrders w" + + " left join WorkOrderTypes t on w.workOrderTypeId = t.workOrderTypeId" + + sqlWhereClause + + " order by w.workOrderOpenDate desc, w.workOrderNumber" + + (options ? + " limit " + options.limit + " offset " + options.offset : + "")) + .all(sqlParameters); + } + + database.close(); + + return { + count, + workOrders + }; +}; + + +export default getWorkOrders; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 98c76f12..cb959ae7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -59,7 +59,7 @@ "bulma": "^0.9.4", "cypress": "^10.6.0", "cypress-axe": "^1.0.0", - "eslint": "^8.22.0", + "eslint": "^8.23.0", "eslint-plugin-import": "^2.26.0", "eslint-plugin-node": "^11.1.0", "eslint-plugin-promise": "^6.0.1", @@ -705,14 +705,14 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", - "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.1.tgz", + "integrity": "sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.2", + "espree": "^9.4.0", "globals": "^13.15.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -722,6 +722,9 @@ }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/@fortawesome/fontawesome-free": { @@ -757,6 +760,19 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", @@ -3697,14 +3713,15 @@ } }, "node_modules/eslint": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.22.0.tgz", - "integrity": "sha512-ci4t0sz6vSRKdmkOGmprBo6fmI4PrphDFMy5JEq/fNS0gQkJM3rLmrqcp8ipMcdobH3KtUP40KniAE9W19S4wA==", + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.0.tgz", + "integrity": "sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.3.0", + "@eslint/eslintrc": "^1.3.1", "@humanwhocodes/config-array": "^0.10.4", "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@humanwhocodes/module-importer": "^1.0.1", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -3714,7 +3731,7 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.3", + "espree": "^9.4.0", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -3739,8 +3756,7 @@ "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" @@ -4140,9 +4156,9 @@ } }, "node_modules/espree": { - "version": "9.3.3", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.3.tgz", - "integrity": "sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", "dev": true, "dependencies": { "acorn": "^8.8.0", @@ -5779,9 +5795,9 @@ } }, "node_modules/globals": { - "version": "13.16.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.16.0.tgz", - "integrity": "sha512-A1lrQfpNF+McdPOnnFqY3kSN0AFTy485bTi1bkLk4mVPODIUEcSfhHgRqA+QdXPksrSTTztYXx37NFV+GpGk3Q==", + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -11302,12 +11318,6 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, "node_modules/v8flags": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", @@ -12419,14 +12429,14 @@ } }, "@eslint/eslintrc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", - "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.1.tgz", + "integrity": "sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.2", + "espree": "^9.4.0", "globals": "^13.15.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -12457,6 +12467,12 @@ "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", "dev": true }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, "@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", @@ -14757,14 +14773,15 @@ "dev": true }, "eslint": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.22.0.tgz", - "integrity": "sha512-ci4t0sz6vSRKdmkOGmprBo6fmI4PrphDFMy5JEq/fNS0gQkJM3rLmrqcp8ipMcdobH3KtUP40KniAE9W19S4wA==", + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.0.tgz", + "integrity": "sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.3.0", + "@eslint/eslintrc": "^1.3.1", "@humanwhocodes/config-array": "^0.10.4", "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@humanwhocodes/module-importer": "^1.0.1", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -14774,7 +14791,7 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.3", + "espree": "^9.4.0", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -14799,8 +14816,7 @@ "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "dependencies": { "eslint-scope": { @@ -15089,9 +15105,9 @@ "dev": true }, "espree": { - "version": "9.3.3", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.3.tgz", - "integrity": "sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", "dev": true, "requires": { "acorn": "^8.8.0", @@ -16405,9 +16421,9 @@ } }, "globals": { - "version": "13.16.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.16.0.tgz", - "integrity": "sha512-A1lrQfpNF+McdPOnnFqY3kSN0AFTy485bTi1bkLk4mVPODIUEcSfhHgRqA+QdXPksrSTTztYXx37NFV+GpGk3Q==", + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -20657,12 +20673,6 @@ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, "v8flags": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", diff --git a/package.json b/package.json index 88758899..8540ef58 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "bulma": "^0.9.4", "cypress": "^10.6.0", "cypress-axe": "^1.0.0", - "eslint": "^8.22.0", + "eslint": "^8.23.0", "eslint-plugin-import": "^2.26.0", "eslint-plugin-node": "^11.1.0", "eslint-plugin-promise": "^6.0.1", diff --git a/public-typescript/workOrderSearch.d.ts b/public-typescript/workOrderSearch.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/public-typescript/workOrderSearch.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/public-typescript/workOrderSearch.js b/public-typescript/workOrderSearch.js new file mode 100644 index 00000000..2c2eff0e --- /dev/null +++ b/public-typescript/workOrderSearch.js @@ -0,0 +1,107 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +(() => { + const urlPrefix = document.querySelector("main").dataset.urlPrefix; + const searchFilterFormElement = document.querySelector("#form--searchFilters"); + const searchResultsContainerElement = document.querySelector("#container--searchResults"); + const limit = Number.parseInt(document.querySelector("#searchFilter--limit").value, 10); + const offsetElement = document.querySelector("#searchFilter--offset"); + const getWorkOrders = () => { + const offset = Number.parseInt(offsetElement.value, 10); + searchResultsContainerElement.innerHTML = "
" + + "
" + + "Loading Work Orders..." + + "
"; + cityssm.postJSON(urlPrefix + "/workOrders/doSearchWorkOrders", searchFilterFormElement, (responseJSON) => { + if (responseJSON.workOrders.length === 0) { + searchResultsContainerElement.innerHTML = "
" + + "

There are no work orders that meet the search criteria.

" + + "
"; + return; + } + const resultsTbodyElement = document.createElement("tbody"); + for (const workOrder of responseJSON.workOrders) { + resultsTbodyElement.insertAdjacentHTML("beforeend", "" + + ("" + + "" + + cityssm.escapeHTML(workOrder.workOrderNumber) + + "" + + "") + + ("" + + cityssm.escapeHTML(workOrder.workOrderType) + + "") + + "" + cityssm.escapeHTML(workOrder.workOrderDescription) + "" + + ("" + + workOrder.workOrderOpenDateString + + "") + + ("" + + (workOrder.workOrderCloseDate ? workOrder.workOrderCloseDateString : "(No Close Date)") + + "") + + ""); + } + searchResultsContainerElement.innerHTML = "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "
Work Order NumberWork Order TypeWork Order DescriptionOpen DateClose Date
" + + "
" + + ("
" + + "
" + + "Displaying " + (offset + 1).toString() + + " to " + Math.min(responseJSON.count, limit + offset) + + " of " + responseJSON.count + + "
" + + "
") + + ("
" + + (offset > 0 ? + "
" + + "" + + "
" : + "") + + (limit + offset < responseJSON.count ? + "
" + + "" + + "
" : + "") + + "
") + + "
"; + searchResultsContainerElement.querySelector("table").append(resultsTbodyElement); + if (offset > 0) { + searchResultsContainerElement.querySelector("button[data-page='previous']").addEventListener("click", previousAndGetWorkOrders); + } + if (limit + offset < responseJSON.count) { + searchResultsContainerElement.querySelector("button[data-page='next']").addEventListener("click", nextAndGetWorkOrders); + } + }); + }; + const resetOffsetAndGetWorkOrders = () => { + offsetElement.value = "0"; + getWorkOrders(); + }; + const previousAndGetWorkOrders = () => { + offsetElement.value = Math.max(Number.parseInt(offsetElement.value, 10) - limit, 0).toString(); + getWorkOrders(); + }; + const nextAndGetWorkOrders = () => { + offsetElement.value = (Number.parseInt(offsetElement.value, 10) + limit).toString(); + getWorkOrders(); + }; + const filterElements = searchFilterFormElement.querySelectorAll("input, select"); + for (const filterElement of filterElements) { + filterElement.addEventListener("change", resetOffsetAndGetWorkOrders); + } + searchFilterFormElement.addEventListener("submit", (formEvent) => { + formEvent.preventDefault(); + resetOffsetAndGetWorkOrders(); + }); + getWorkOrders(); +})(); diff --git a/public-typescript/workOrderSearch.ts b/public-typescript/workOrderSearch.ts new file mode 100644 index 00000000..5ff2c313 --- /dev/null +++ b/public-typescript/workOrderSearch.ts @@ -0,0 +1,146 @@ +/* eslint-disable unicorn/prefer-module */ + +import type * as recordTypes from "../types/recordTypes"; + +import type { + cityssmGlobal +} from "@cityssm/bulma-webapp-js/src/types"; + + +declare const cityssm: cityssmGlobal; + + +(() => { + const urlPrefix = document.querySelector("main").dataset.urlPrefix; + + const searchFilterFormElement = document.querySelector("#form--searchFilters") as HTMLFormElement; + const searchResultsContainerElement = document.querySelector("#container--searchResults") as HTMLElement; + + const limit = Number.parseInt((document.querySelector("#searchFilter--limit") as HTMLInputElement).value, 10); + const offsetElement = document.querySelector("#searchFilter--offset") as HTMLInputElement; + + + const getWorkOrders = () => { + + const offset = Number.parseInt(offsetElement.value, 10); + + searchResultsContainerElement.innerHTML = "
" + + "
" + + "Loading Work Orders..." + + "
"; + + cityssm.postJSON(urlPrefix + "/workOrders/doSearchWorkOrders", searchFilterFormElement, + (responseJSON: { + count: number; + workOrders: recordTypes.WorkOrder[]; + }) => { + + if (responseJSON.workOrders.length === 0) { + + searchResultsContainerElement.innerHTML = "
" + + "

There are no work orders that meet the search criteria.

" + + "
"; + + return; + } + + const resultsTbodyElement = document.createElement("tbody"); + + for (const workOrder of responseJSON.workOrders) { + + resultsTbodyElement.insertAdjacentHTML("beforeend", "" + + ("") + + ("") + + "" + + ("") + + ("") + + ""); + + } + + searchResultsContainerElement.innerHTML = "
" + + "" + + cityssm.escapeHTML(workOrder.workOrderNumber) + + "" + + "" + + cityssm.escapeHTML(workOrder.workOrderType) + + "" + cityssm.escapeHTML(workOrder.workOrderDescription) + "" + + workOrder.workOrderOpenDateString + + "" + + (workOrder.workOrderCloseDate ? workOrder.workOrderCloseDateString : "(No Close Date)") + + "
" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "
Work Order NumberWork Order TypeWork Order DescriptionOpen DateClose Date
" + + "
" + + ("
" + + "
" + + "Displaying " + (offset + 1).toString() + + " to " + Math.min(responseJSON.count, limit + offset) + + " of " + responseJSON.count + + "
" + + "
") + + ("
" + + (offset > 0 ? + "
" + + "" + + "
" : + "") + + (limit + offset < responseJSON.count ? + "
" + + "" + + "
" : + "") + + "
") + + "
"; + + searchResultsContainerElement.querySelector("table").append(resultsTbodyElement); + + if (offset > 0) { + searchResultsContainerElement.querySelector("button[data-page='previous']").addEventListener("click", previousAndGetWorkOrders); + } + + if (limit + offset < responseJSON.count) { + searchResultsContainerElement.querySelector("button[data-page='next']").addEventListener("click", nextAndGetWorkOrders); + } + }); + }; + + const resetOffsetAndGetWorkOrders = () => { + offsetElement.value = "0"; + getWorkOrders(); + } + + const previousAndGetWorkOrders = () => { + offsetElement.value = Math.max(Number.parseInt(offsetElement.value, 10) - limit, 0).toString(); + getWorkOrders(); + }; + + const nextAndGetWorkOrders = () => { + offsetElement.value = (Number.parseInt(offsetElement.value, 10) + limit).toString(); + getWorkOrders(); + }; + + const filterElements = searchFilterFormElement.querySelectorAll("input, select") as NodeListOf < HTMLInputElement | HTMLSelectElement > ; + + for (const filterElement of filterElements) { + filterElement.addEventListener("change", resetOffsetAndGetWorkOrders); + } + + searchFilterFormElement.addEventListener("submit", (formEvent) => { + formEvent.preventDefault(); + resetOffsetAndGetWorkOrders(); + }); + + getWorkOrders(); +})(); \ No newline at end of file diff --git a/public/javascripts/workOrderSearch.min.js b/public/javascripts/workOrderSearch.min.js new file mode 100644 index 00000000..19ddc3a2 --- /dev/null +++ b/public/javascripts/workOrderSearch.min.js @@ -0,0 +1 @@ +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=document.querySelector("main").dataset.urlPrefix,t=document.querySelector("#form--searchFilters"),r=document.querySelector("#container--searchResults"),s=Number.parseInt(document.querySelector("#searchFilter--limit").value,10),a=document.querySelector("#searchFilter--offset"),i=()=>{const i=Number.parseInt(a.value,10);r.innerHTML='

Loading Work Orders...
',cityssm.postJSON(e+"/workOrders/doSearchWorkOrders",t,t=>{if(0===t.workOrders.length)return void(r.innerHTML='

There are no work orders that meet the search criteria.

');const a=document.createElement("tbody");for(const r of t.workOrders)a.insertAdjacentHTML("beforeend",'");r.innerHTML='
'+cityssm.escapeHTML(r.workOrderNumber)+""+cityssm.escapeHTML(r.workOrderType)+""+cityssm.escapeHTML(r.workOrderDescription)+""+r.workOrderOpenDateString+""+(r.workOrderCloseDate?r.workOrderCloseDateString:'(No Close Date)')+"
Work Order NumberWork Order TypeWork Order DescriptionOpen DateClose Date
Displaying '+(i+1).toString()+" to "+Math.min(t.count,s+i)+" of "+t.count+'
'+(i>0?'
':"")+(s+i
':"")+"
",r.querySelector("table").append(a),i>0&&r.querySelector("button[data-page='previous']").addEventListener("click",d),s+i{a.value="0",i()},d=()=>{a.value=Math.max(Number.parseInt(a.value,10)-s,0).toString(),i()},n=()=>{a.value=(Number.parseInt(a.value,10)+s).toString(),i()},l=t.querySelectorAll("input, select");for(const e of l)e.addEventListener("change",o);t.addEventListener("submit",e=>{e.preventDefault(),o()}),i()})(); \ No newline at end of file diff --git a/routes/workOrders.js b/routes/workOrders.js index 4cd6c0d9..21ae8f37 100644 --- a/routes/workOrders.js +++ b/routes/workOrders.js @@ -1,5 +1,7 @@ import { Router } from "express"; import handler_search from "../handlers/workOrders-get/search.js"; +import handler_doSearchWorkOrders from "../handlers/workOrders-post/doSearchWorkOrders.js"; export const router = Router(); router.get("/", handler_search); +router.post("/doSearchWorkOrders", handler_doSearchWorkOrders); export default router; diff --git a/routes/workOrders.ts b/routes/workOrders.ts index db647d5d..044d1142 100644 --- a/routes/workOrders.ts +++ b/routes/workOrders.ts @@ -1,9 +1,13 @@ -import { Router } from "express"; +import { + Router +} from "express"; import * as permissionHandlers from "../handlers/permissions.js"; import * as configFunctions from "../helpers/functions.config.js"; import handler_search from "../handlers/workOrders-get/search.js"; +import handler_doSearchWorkOrders from "../handlers/workOrders-post/doSearchWorkOrders.js"; + export const router = Router(); @@ -12,5 +16,8 @@ export const router = Router(); router.get("/", handler_search); +router.post("/doSearchWorkOrders", + handler_doSearchWorkOrders); -export default router; + +export default router; \ No newline at end of file diff --git a/temp/legacy.importFromCSV.js b/temp/legacy.importFromCSV.js index f8b7962b..352a431d 100644 --- a/temp/legacy.importFromCSV.js +++ b/temp/legacy.importFromCSV.js @@ -16,6 +16,8 @@ import { getLots } from "../helpers/lotOccupancyDB/getLots.js"; import { getLotOccupancies } from "../helpers/lotOccupancyDB/getLotOccupancies.js"; import { addLotOccupancyFee } from "../helpers/lotOccupancyDB/addLotOccupancyFee.js"; import { addLotOccupancyTransaction } from "../helpers/lotOccupancyDB/addLotOccupancyTransaction.js"; +import { addWorkOrder } from "../helpers/lotOccupancyDB/addWorkOrder.js"; +import { addWorkOrderLot } from "../helpers/lotOccupancyDB/addWorkOrderLot.js"; const user = { user: { userName: "import.unix", @@ -207,25 +209,26 @@ function importFromMasterCSV() { lotLongitude: "" }, user); } + let preneedOccupancyStartDateString; if (masterRow.CM_PRENEED_ORDER) { - let occupancyStartDateString = formatDateString(masterRow.CM_PURCHASE_YR, masterRow.CM_PURCHASE_MON, masterRow.CM_PURCHASE_DAY); + preneedOccupancyStartDateString = formatDateString(masterRow.CM_PURCHASE_YR, masterRow.CM_PURCHASE_MON, masterRow.CM_PURCHASE_DAY); let occupancyEndDateString = ""; if (masterRow.CM_INTERMENT_YR !== "" && masterRow.CM_INTERMENT_YR !== "0") { occupancyEndDateString = formatDateString(masterRow.CM_INTERMENT_YR, masterRow.CM_INTERMENT_MON, masterRow.CM_INTERMENT_DAY); } - if (occupancyStartDateString === "0000-00-00" && occupancyEndDateString !== "") { - occupancyStartDateString = occupancyEndDateString; + if (preneedOccupancyStartDateString === "0000-00-00" && occupancyEndDateString !== "") { + preneedOccupancyStartDateString = occupancyEndDateString; } - if (occupancyStartDateString === "0000-00-00" && masterRow.CM_DEATH_YR !== "" && masterRow.CM_DEATH_YR !== "0") { - occupancyStartDateString = formatDateString(masterRow.CM_DEATH_YR, masterRow.CM_DEATH_MON, masterRow.CM_DEATH_DAY); + if (preneedOccupancyStartDateString === "0000-00-00" && masterRow.CM_DEATH_YR !== "" && masterRow.CM_DEATH_YR !== "0") { + preneedOccupancyStartDateString = formatDateString(masterRow.CM_DEATH_YR, masterRow.CM_DEATH_MON, masterRow.CM_DEATH_DAY); } - if (occupancyStartDateString === "" || occupancyStartDateString === "0000-00-00") { - occupancyStartDateString = "0001-01-01"; + if (preneedOccupancyStartDateString === "" || preneedOccupancyStartDateString === "0000-00-00") { + preneedOccupancyStartDateString = "0001-01-01"; } const lotOccupancyId = addLotOccupancy({ occupancyTypeId: preneedOccupancyType.occupancyTypeId, lotId, - occupancyStartDateString, + occupancyStartDateString: preneedOccupancyStartDateString, occupancyEndDateString, occupancyTypeFieldIds: "" }, user); @@ -244,7 +247,7 @@ function importFromMasterCSV() { if (masterRow.CM_REMARK1 !== "") { addLotOccupancyComment({ lotOccupancyId, - lotOccupancyCommentDateString: occupancyStartDateString, + lotOccupancyCommentDateString: preneedOccupancyStartDateString, lotOccupancyCommentTimeString: "00:00", lotOccupancyComment: masterRow.CM_REMARK1 }, user); @@ -252,7 +255,7 @@ function importFromMasterCSV() { if (masterRow.CM_REMARK2 !== "") { addLotOccupancyComment({ lotOccupancyId, - lotOccupancyCommentDateString: occupancyStartDateString, + lotOccupancyCommentDateString: preneedOccupancyStartDateString, lotOccupancyCommentTimeString: "00:00", lotOccupancyComment: masterRow.CM_REMARK2 }, user); @@ -261,19 +264,20 @@ function importFromMasterCSV() { updateLotStatus(lotId, reservedLotStatus.lotStatusId, user); } } + let deceasedOccupancyStartDateString; if (masterRow.CM_DECEASED_NAME) { - let occupancyStartDateString = formatDateString(masterRow.CM_INTERMENT_YR, masterRow.CM_INTERMENT_MON, masterRow.CM_INTERMENT_DAY); + deceasedOccupancyStartDateString = formatDateString(masterRow.CM_INTERMENT_YR, masterRow.CM_INTERMENT_MON, masterRow.CM_INTERMENT_DAY); const occupancyEndDateString = ""; - if (occupancyStartDateString === "0000-00-00" && masterRow.CM_DEATH_YR !== "" && masterRow.CM_DEATH_YR !== "0") { - occupancyStartDateString = formatDateString(masterRow.CM_DEATH_YR, masterRow.CM_DEATH_MON, masterRow.CM_DEATH_DAY); + if (deceasedOccupancyStartDateString === "0000-00-00" && masterRow.CM_DEATH_YR !== "" && masterRow.CM_DEATH_YR !== "0") { + deceasedOccupancyStartDateString = formatDateString(masterRow.CM_DEATH_YR, masterRow.CM_DEATH_MON, masterRow.CM_DEATH_DAY); } - if (occupancyStartDateString === "" || occupancyStartDateString === "0000-00-00") { - occupancyStartDateString = "0001-01-01"; + if (deceasedOccupancyStartDateString === "" || deceasedOccupancyStartDateString === "0000-00-00") { + deceasedOccupancyStartDateString = "0001-01-01"; } const lotOccupancyId = addLotOccupancy({ occupancyTypeId: lotId ? deceasedOccupancyType.occupancyTypeId : cremationOccupancyType.occupancyTypeId, lotId, - occupancyStartDateString, + occupancyStartDateString: deceasedOccupancyStartDateString, occupancyEndDateString, occupancyTypeFieldIds: "" }, user); @@ -361,7 +365,7 @@ function importFromMasterCSV() { if (masterRow.CM_REMARK1 !== "") { addLotOccupancyComment({ lotOccupancyId, - lotOccupancyCommentDateString: occupancyStartDateString, + lotOccupancyCommentDateString: deceasedOccupancyStartDateString, lotOccupancyCommentTimeString: "00:00", lotOccupancyComment: masterRow.CM_REMARK1 }, user); @@ -369,13 +373,27 @@ function importFromMasterCSV() { if (masterRow.CM_REMARK2 !== "") { addLotOccupancyComment({ lotOccupancyId, - lotOccupancyCommentDateString: occupancyStartDateString, + lotOccupancyCommentDateString: deceasedOccupancyStartDateString, lotOccupancyCommentTimeString: "00:00", lotOccupancyComment: masterRow.CM_REMARK2 }, user); } updateLotStatus(lotId, takenLotStatus.lotStatusId, user); } + if (masterRow.CM_WORK_ORDER) { + const workOrderId = addWorkOrder({ + workOrderNumber: masterRow.CM_WORK_ORDER, + workOrderTypeId: 1, + workOrderDescription: "", + workOrderOpenDateString: deceasedOccupancyStartDateString || preneedOccupancyStartDateString + }, user); + if (lotId) { + addWorkOrderLot({ + workOrderId, + lotId + }, user); + } + } } } catch (error) { diff --git a/temp/legacy.importFromCSV.ts b/temp/legacy.importFromCSV.ts index 32beefbe..4389631b 100644 --- a/temp/legacy.importFromCSV.ts +++ b/temp/legacy.importFromCSV.ts @@ -4,6 +4,7 @@ import fs from "node:fs"; import papa from "papaparse"; import sqlite from "better-sqlite3"; + import { lotOccupancyDB as databasePath } from "../data/databasePaths.js"; @@ -60,6 +61,14 @@ import { addLotOccupancyTransaction } from "../helpers/lotOccupancyDB/addLotOccupancyTransaction.js"; +import { + addWorkOrder +} from "../helpers/lotOccupancyDB/addWorkOrder.js"; + +import { + addWorkOrderLot +} from "../helpers/lotOccupancyDB/addWorkOrderLot.js"; + import type * as recordTypes from "../types/recordTypes"; @@ -229,7 +238,8 @@ const cemeteryToMapName = { "PG": "Pine Grove", "UG": "New Greenwood - Urn Garden", "WK": "West Korah" -} +}; + const mapCache: Map < string, recordTypes.Map > = new Map(); @@ -434,9 +444,11 @@ function importFromMasterCSV() { }, user); } + let preneedOccupancyStartDateString: string; + if (masterRow.CM_PRENEED_ORDER) { - let occupancyStartDateString = formatDateString(masterRow.CM_PURCHASE_YR, + preneedOccupancyStartDateString = formatDateString(masterRow.CM_PURCHASE_YR, masterRow.CM_PURCHASE_MON, masterRow.CM_PURCHASE_DAY); @@ -449,25 +461,25 @@ function importFromMasterCSV() { } // if purchase date unavailable - if (occupancyStartDateString === "0000-00-00" && occupancyEndDateString !== "") { - occupancyStartDateString = occupancyEndDateString; + if (preneedOccupancyStartDateString === "0000-00-00" && occupancyEndDateString !== "") { + preneedOccupancyStartDateString = occupancyEndDateString; } // if end date unavailable - if (occupancyStartDateString === "0000-00-00" && masterRow.CM_DEATH_YR !== "" && masterRow.CM_DEATH_YR !== "0") { - occupancyStartDateString = formatDateString(masterRow.CM_DEATH_YR, + if (preneedOccupancyStartDateString === "0000-00-00" && masterRow.CM_DEATH_YR !== "" && masterRow.CM_DEATH_YR !== "0") { + preneedOccupancyStartDateString = formatDateString(masterRow.CM_DEATH_YR, masterRow.CM_DEATH_MON, masterRow.CM_DEATH_DAY); } - if (occupancyStartDateString === "" || occupancyStartDateString === "0000-00-00") { - occupancyStartDateString = "0001-01-01"; + if (preneedOccupancyStartDateString === "" || preneedOccupancyStartDateString === "0000-00-00") { + preneedOccupancyStartDateString = "0001-01-01"; } const lotOccupancyId = addLotOccupancy({ occupancyTypeId: preneedOccupancyType.occupancyTypeId, lotId, - occupancyStartDateString, + occupancyStartDateString: preneedOccupancyStartDateString, occupancyEndDateString, occupancyTypeFieldIds: "" }, user); @@ -489,7 +501,7 @@ function importFromMasterCSV() { if (masterRow.CM_REMARK1 !== "") { addLotOccupancyComment({ lotOccupancyId, - lotOccupancyCommentDateString: occupancyStartDateString, + lotOccupancyCommentDateString: preneedOccupancyStartDateString, lotOccupancyCommentTimeString: "00:00", lotOccupancyComment: masterRow.CM_REMARK1 }, user); @@ -498,7 +510,7 @@ function importFromMasterCSV() { if (masterRow.CM_REMARK2 !== "") { addLotOccupancyComment({ lotOccupancyId, - lotOccupancyCommentDateString: occupancyStartDateString, + lotOccupancyCommentDateString: preneedOccupancyStartDateString, lotOccupancyCommentTimeString: "00:00", lotOccupancyComment: masterRow.CM_REMARK2 }, user); @@ -509,29 +521,31 @@ function importFromMasterCSV() { } } + let deceasedOccupancyStartDateString: string; + if (masterRow.CM_DECEASED_NAME) { - let occupancyStartDateString = formatDateString(masterRow.CM_INTERMENT_YR, + deceasedOccupancyStartDateString = formatDateString(masterRow.CM_INTERMENT_YR, masterRow.CM_INTERMENT_MON, masterRow.CM_INTERMENT_DAY); const occupancyEndDateString = ""; // if interment date unavailable - if (occupancyStartDateString === "0000-00-00" && masterRow.CM_DEATH_YR !== "" && masterRow.CM_DEATH_YR !== "0") { - occupancyStartDateString = formatDateString(masterRow.CM_DEATH_YR, + if (deceasedOccupancyStartDateString === "0000-00-00" && masterRow.CM_DEATH_YR !== "" && masterRow.CM_DEATH_YR !== "0") { + deceasedOccupancyStartDateString = formatDateString(masterRow.CM_DEATH_YR, masterRow.CM_DEATH_MON, masterRow.CM_DEATH_DAY); } - if (occupancyStartDateString === "" || occupancyStartDateString === "0000-00-00") { - occupancyStartDateString = "0001-01-01"; + if (deceasedOccupancyStartDateString === "" || deceasedOccupancyStartDateString === "0000-00-00") { + deceasedOccupancyStartDateString = "0001-01-01"; } const lotOccupancyId = addLotOccupancy({ occupancyTypeId: lotId ? deceasedOccupancyType.occupancyTypeId : cremationOccupancyType.occupancyTypeId, lotId, - occupancyStartDateString, + occupancyStartDateString: deceasedOccupancyStartDateString, occupancyEndDateString, occupancyTypeFieldIds: "" }, user); @@ -644,7 +658,7 @@ function importFromMasterCSV() { if (masterRow.CM_REMARK1 !== "") { addLotOccupancyComment({ lotOccupancyId, - lotOccupancyCommentDateString: occupancyStartDateString, + lotOccupancyCommentDateString: deceasedOccupancyStartDateString, lotOccupancyCommentTimeString: "00:00", lotOccupancyComment: masterRow.CM_REMARK1 }, user); @@ -653,7 +667,7 @@ function importFromMasterCSV() { if (masterRow.CM_REMARK2 !== "") { addLotOccupancyComment({ lotOccupancyId, - lotOccupancyCommentDateString: occupancyStartDateString, + lotOccupancyCommentDateString: deceasedOccupancyStartDateString, lotOccupancyCommentTimeString: "00:00", lotOccupancyComment: masterRow.CM_REMARK2 }, user); @@ -661,6 +675,23 @@ function importFromMasterCSV() { updateLotStatus(lotId, takenLotStatus.lotStatusId, user); } + + if (masterRow.CM_WORK_ORDER) { + + const workOrderId = addWorkOrder({ + workOrderNumber: masterRow.CM_WORK_ORDER, + workOrderTypeId: 1, + workOrderDescription: "", + workOrderOpenDateString: deceasedOccupancyStartDateString || preneedOccupancyStartDateString + }, user); + + if (lotId) { + addWorkOrderLot({ + workOrderId, + lotId + }, user); + } + } } } catch (error) { console.error(error) diff --git a/types/recordTypes.d.ts b/types/recordTypes.d.ts index dcf337a4..653803f8 100644 --- a/types/recordTypes.d.ts +++ b/types/recordTypes.d.ts @@ -190,6 +190,18 @@ export interface WorkOrderType extends Record { workOrderType?: string; orderNumber?: number; } +export interface WorkOrder extends Record { + workOrderId?: number; + workOrderTypeId?: number; + workOrderType?: string; + workOrderNumber?: string; + workOrderDescription?: string; + workOrderOpenDate?: number; + workOrderOpenDateString?: string; + workOrderCloseDate?: number; + workOrderCloseDateString?: string; + workOrderLots?: Lot[]; +} export interface User { userName: string; userProperties?: UserProperties; diff --git a/types/recordTypes.js b/types/recordTypes.js index c8ad2e54..cb0ff5c3 100644 --- a/types/recordTypes.js +++ b/types/recordTypes.js @@ -1,2 +1 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); +export {}; diff --git a/types/recordTypes.ts b/types/recordTypes.ts index 3c52c2dd..d741acf1 100644 --- a/types/recordTypes.ts +++ b/types/recordTypes.ts @@ -265,7 +265,7 @@ export interface LotOccupancy extends Record { /* - * WORK ORDER TYPES + * WORK ORDERS */ @@ -276,6 +276,25 @@ export interface WorkOrderType extends Record { } +export interface WorkOrder extends Record { + workOrderId?: number; + + workOrderTypeId?: number; + workOrderType?: string; + + workOrderNumber?: string; + workOrderDescription?: string; + + workOrderOpenDate?: number; + workOrderOpenDateString?: string; + + workOrderCloseDate?: number; + workOrderCloseDateString?: string; + + workOrderLots?: Lot[]; +} + + /* * USER TYPES */ diff --git a/views/workOrder-search.ejs b/views/workOrder-search.ejs index 53880904..cce1134f 100644 --- a/views/workOrder-search.ejs +++ b/views/workOrder-search.ejs @@ -25,7 +25,34 @@ <% } %> +
+
+ + + +
+ +
+
+ +
+ + + +
+
+ +
+
<%- include('_footerA'); -%> + + + <%- include('_footerB'); -%> \ No newline at end of file