From c1707043e627dcb4f85989bad226b38aa86b562e Mon Sep 17 00:00:00 2001 From: Dan Gowans Date: Tue, 27 Sep 2022 10:44:04 -0400 Subject: [PATCH] lot summaries --- handlers/maps-get/view.js | 15 ++- handlers/maps-get/view.ts | 17 +++- .../lotOccupancyDB/getLotStatusSummary.d.ts | 9 ++ helpers/lotOccupancyDB/getLotStatusSummary.js | 24 +++++ helpers/lotOccupancyDB/getLotStatusSummary.ts | 44 +++++++++ helpers/lotOccupancyDB/getLotTypeSummary.d.ts | 9 ++ helpers/lotOccupancyDB/getLotTypeSummary.js | 24 +++++ helpers/lotOccupancyDB/getLotTypeSummary.ts | 44 +++++++++ views/map-view.ejs | 96 +++++++++++++++++-- 9 files changed, 267 insertions(+), 15 deletions(-) create mode 100644 helpers/lotOccupancyDB/getLotStatusSummary.d.ts create mode 100644 helpers/lotOccupancyDB/getLotStatusSummary.js create mode 100644 helpers/lotOccupancyDB/getLotStatusSummary.ts create mode 100644 helpers/lotOccupancyDB/getLotTypeSummary.d.ts create mode 100644 helpers/lotOccupancyDB/getLotTypeSummary.js create mode 100644 helpers/lotOccupancyDB/getLotTypeSummary.ts diff --git a/handlers/maps-get/view.js b/handlers/maps-get/view.js index c81ae464..30f0da8a 100644 --- a/handlers/maps-get/view.js +++ b/handlers/maps-get/view.js @@ -1,14 +1,23 @@ import * as configFunctions from "../../helpers/functions.config.js"; import { getMap } from "../../helpers/lotOccupancyDB/getMap.js"; +import { getLotStatusSummary } from "../../helpers/lotOccupancyDB/getLotStatusSummary.js"; +import { getLotTypeSummary } from "../../helpers/lotOccupancyDB/getLotTypeSummary.js"; export const handler = (request, response) => { const map = getMap(request.params.mapId); if (!map) { - return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") + - "/maps/?error=mapIdNotFound"); + return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") + "/maps/?error=mapIdNotFound"); } + const lotTypeSummary = getLotTypeSummary({ + mapId: map.mapId + }); + const lotStatusSummary = getLotStatusSummary({ + mapId: map.mapId + }); response.render("map-view", { headTitle: map.mapName, - map + map, + lotTypeSummary, + lotStatusSummary }); }; export default handler; diff --git a/handlers/maps-get/view.ts b/handlers/maps-get/view.ts index 4b119937..0cbfa909 100644 --- a/handlers/maps-get/view.ts +++ b/handlers/maps-get/view.ts @@ -3,20 +3,31 @@ import type { RequestHandler } from "express"; import * as configFunctions from "../../helpers/functions.config.js"; import { getMap } from "../../helpers/lotOccupancyDB/getMap.js"; +import { getLotStatusSummary } from "../../helpers/lotOccupancyDB/getLotStatusSummary.js"; +import { getLotTypeSummary } from "../../helpers/lotOccupancyDB/getLotTypeSummary.js"; export const handler: RequestHandler = (request, response) => { const map = getMap(request.params.mapId); if (!map) { return response.redirect( - configFunctions.getProperty("reverseProxy.urlPrefix") + - "/maps/?error=mapIdNotFound" + configFunctions.getProperty("reverseProxy.urlPrefix") + "/maps/?error=mapIdNotFound" ); } + const lotTypeSummary = getLotTypeSummary({ + mapId: map.mapId + }); + + const lotStatusSummary = getLotStatusSummary({ + mapId: map.mapId + }); + response.render("map-view", { headTitle: map.mapName, - map + map, + lotTypeSummary, + lotStatusSummary }); }; diff --git a/helpers/lotOccupancyDB/getLotStatusSummary.d.ts b/helpers/lotOccupancyDB/getLotStatusSummary.d.ts new file mode 100644 index 00000000..fefefd1a --- /dev/null +++ b/helpers/lotOccupancyDB/getLotStatusSummary.d.ts @@ -0,0 +1,9 @@ +import type * as recordTypes from "../../types/recordTypes"; +interface GetFilters { + mapId?: number | string; +} +interface LotStatusSummary extends recordTypes.LotStatus { + lotCount: number; +} +export declare const getLotStatusSummary: (filters?: GetFilters) => LotStatusSummary[]; +export default getLotStatusSummary; diff --git a/helpers/lotOccupancyDB/getLotStatusSummary.js b/helpers/lotOccupancyDB/getLotStatusSummary.js new file mode 100644 index 00000000..caba59b6 --- /dev/null +++ b/helpers/lotOccupancyDB/getLotStatusSummary.js @@ -0,0 +1,24 @@ +import sqlite from "better-sqlite3"; +import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; +export const getLotStatusSummary = (filters) => { + const database = sqlite(databasePath, { + readonly: true + }); + let sqlWhereClause = " where l.recordDelete_timeMillis is null"; + const sqlParameters = []; + if (filters && filters.mapId) { + sqlWhereClause += " and l.mapId = ?"; + sqlParameters.push(filters.mapId); + } + const lotStatuses = database + .prepare("select s.lotStatusId, s.lotStatus, count(l.lotId) as lotCount" + + " from Lots l" + + " left join LotStatuses s on l.lotStatusId = s.lotStatusId" + + sqlWhereClause + + " group by s.lotStatusId, s.lotStatus, s.orderNumber" + + " order by s.orderNumber") + .all(sqlParameters); + database.close(); + return lotStatuses; +}; +export default getLotStatusSummary; diff --git a/helpers/lotOccupancyDB/getLotStatusSummary.ts b/helpers/lotOccupancyDB/getLotStatusSummary.ts new file mode 100644 index 00000000..184ae955 --- /dev/null +++ b/helpers/lotOccupancyDB/getLotStatusSummary.ts @@ -0,0 +1,44 @@ +import sqlite from "better-sqlite3"; + +import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; + +import type * as recordTypes from "../../types/recordTypes"; + +interface GetFilters { + mapId?: number | string; +} + +interface LotStatusSummary extends recordTypes.LotStatus { + lotCount: number; +} + +export const getLotStatusSummary = (filters?: GetFilters): LotStatusSummary[] => { + const database = sqlite(databasePath, { + readonly: true + }); + + let sqlWhereClause = " where l.recordDelete_timeMillis is null"; + const sqlParameters = []; + + if (filters && filters.mapId) { + sqlWhereClause += " and l.mapId = ?"; + sqlParameters.push(filters.mapId); + } + + const lotStatuses: LotStatusSummary[] = database + .prepare( + "select s.lotStatusId, s.lotStatus, count(l.lotId) as lotCount" + + " from Lots l" + + " left join LotStatuses s on l.lotStatusId = s.lotStatusId" + + sqlWhereClause + + " group by s.lotStatusId, s.lotStatus, s.orderNumber" + + " order by s.orderNumber" + ) + .all(sqlParameters); + + database.close(); + + return lotStatuses; +}; + +export default getLotStatusSummary; diff --git a/helpers/lotOccupancyDB/getLotTypeSummary.d.ts b/helpers/lotOccupancyDB/getLotTypeSummary.d.ts new file mode 100644 index 00000000..319b15f9 --- /dev/null +++ b/helpers/lotOccupancyDB/getLotTypeSummary.d.ts @@ -0,0 +1,9 @@ +import type * as recordTypes from "../../types/recordTypes"; +interface GetFilters { + mapId?: number | string; +} +interface LotTypeSummary extends recordTypes.LotType { + lotCount: number; +} +export declare const getLotTypeSummary: (filters?: GetFilters) => LotTypeSummary[]; +export default getLotTypeSummary; diff --git a/helpers/lotOccupancyDB/getLotTypeSummary.js b/helpers/lotOccupancyDB/getLotTypeSummary.js new file mode 100644 index 00000000..bf986c12 --- /dev/null +++ b/helpers/lotOccupancyDB/getLotTypeSummary.js @@ -0,0 +1,24 @@ +import sqlite from "better-sqlite3"; +import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; +export const getLotTypeSummary = (filters) => { + const database = sqlite(databasePath, { + readonly: true + }); + let sqlWhereClause = " where l.recordDelete_timeMillis is null"; + const sqlParameters = []; + if (filters && filters.mapId) { + sqlWhereClause += " and l.mapId = ?"; + sqlParameters.push(filters.mapId); + } + const lotTypes = database + .prepare("select t.lotTypeId, t.lotType, count(l.lotId) as lotCount" + + " from Lots l" + + " left join LotTypes t on l.lotTypeId = t.lotTypeId" + + sqlWhereClause + + " group by t.lotTypeId, t.lotType, t.orderNumber" + + " order by t.orderNumber") + .all(sqlParameters); + database.close(); + return lotTypes; +}; +export default getLotTypeSummary; diff --git a/helpers/lotOccupancyDB/getLotTypeSummary.ts b/helpers/lotOccupancyDB/getLotTypeSummary.ts new file mode 100644 index 00000000..9a124132 --- /dev/null +++ b/helpers/lotOccupancyDB/getLotTypeSummary.ts @@ -0,0 +1,44 @@ +import sqlite from "better-sqlite3"; + +import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; + +import type * as recordTypes from "../../types/recordTypes"; + +interface GetFilters { + mapId?: number | string; +} + +interface LotTypeSummary extends recordTypes.LotType { + lotCount: number; +} + +export const getLotTypeSummary = (filters?: GetFilters): LotTypeSummary[] => { + const database = sqlite(databasePath, { + readonly: true + }); + + let sqlWhereClause = " where l.recordDelete_timeMillis is null"; + const sqlParameters = []; + + if (filters && filters.mapId) { + sqlWhereClause += " and l.mapId = ?"; + sqlParameters.push(filters.mapId); + } + + const lotTypes: LotTypeSummary[] = database + .prepare( + "select t.lotTypeId, t.lotType, count(l.lotId) as lotCount" + + " from Lots l" + + " left join LotTypes t on l.lotTypeId = t.lotTypeId" + + sqlWhereClause + + " group by t.lotTypeId, t.lotType, t.orderNumber" + + " order by t.orderNumber" + ) + .all(sqlParameters); + + database.close(); + + return lotTypes; +}; + +export default getLotTypeSummary; diff --git a/views/map-view.ejs b/views/map-view.ejs index 1d0b1053..a285a22f 100644 --- a/views/map-view.ejs +++ b/views/map-view.ejs @@ -94,16 +94,94 @@ +<% const lotSearchUrl = urlPrefix + "/lots?mapId=" + map.mapId; %>
-

- Related Searches -

-
- - - <%= configFunctions.getProperty("aliases.lots") %> - <%= map.lotCount %> - +
+
+
+
+

+ <%= configFunctions.getProperty("aliases.lot") %> Summaries + + <%= map.lotCount %> + +

+
+
+ +
+
+
+ <% if (map.lotCount === 0) { %> +
+

+ There are no <%= configFunctions.getProperty("aliases.lots").toLowerCase() %> + associated with this <%= configFunctions.getProperty("aliases.map").toLowerCase() %>. +

+
+ <% } else { %> +
+
+ + + + + + + + + <% for (const lotType of lotTypeSummary) { %> + + + + + <% } %> + +
Type + <%= configFunctions.getProperty("aliases.lot") %> Count +
+ + <%= lotType.lotType %> + + + <%= lotType.lotCount %> +
+
+
+ + + + + + + + + <% for (const lotStatus of lotStatusSummary) { %> + + + + + <% } %> + +
Status + <%= configFunctions.getProperty("aliases.lot") %> Count +
+ + <%= lotStatus.lotStatus %> + + + <%= lotStatus.lotCount %> +
+
+
+ <% } %>