From c2ae19f4a64a2e76d78e54eb49dc4da2f53d5cd4 Mon Sep 17 00:00:00 2001 From: Dan Gowans Date: Wed, 31 Aug 2022 10:10:33 -0400 Subject: [PATCH] custom lot name sort name function --- data/config.cemetery.ssm.js | 21 +++++++++++++ data/config.cemetery.ssm.ts | 36 ++++++++++++++++++++-- helpers/functions.config.d.ts | 1 + helpers/functions.config.js | 1 + helpers/functions.config.ts | 4 +++ helpers/lotOccupancyDB/getLots.d.ts | 3 +- helpers/lotOccupancyDB/getLots.js | 12 +++++--- helpers/lotOccupancyDB/getLots.ts | 16 +++++++--- helpers/lotOccupancyDB/getNextLotId.js | 6 ++-- helpers/lotOccupancyDB/getNextLotId.ts | 8 +++-- helpers/lotOccupancyDB/getPreviousLotId.js | 6 ++-- helpers/lotOccupancyDB/getPreviousLotId.ts | 8 +++-- temp/legacy.importFromCSV.js | 3 ++ temp/legacy.importFromCSV.ts | 5 ++- types/configTypes.d.ts | 3 ++ types/configTypes.ts | 3 ++ 16 files changed, 116 insertions(+), 20 deletions(-) diff --git a/data/config.cemetery.ssm.js b/data/config.cemetery.ssm.js index a4463423..c1b5b7c5 100644 --- a/data/config.cemetery.ssm.js +++ b/data/config.cemetery.ssm.js @@ -1,5 +1,26 @@ import { config as cemeteryConfig } from "./config.cemetery.ontario.js"; export const config = Object.assign({}, cemeteryConfig); +config.settings.lot = { + lotNameSortNameFunction: (lotName) => { + const numericPadding = "00000"; + const lotNameSplit = lotName.toUpperCase().split("-"); + const cleanLotNamePieces = []; + for (const lotNamePiece of lotNameSplit) { + let numericPiece = numericPadding; + let letterPiece = ""; + for (const letter of lotNamePiece) { + if (letterPiece === "" && "0123456789".includes(letter)) { + numericPiece += letter; + } + else { + letterPiece += letter; + } + } + cleanLotNamePieces.push(numericPiece.slice(-1 * numericPadding.length) + letterPiece); + } + return cleanLotNamePieces.join("-"); + } +}; config.settings.lotOccupancy.occupantCityDefault = "Sault Ste. Marie"; config.settings.map.mapCityDefault = "Sault Ste. Marie"; config.aliases.externalReceiptNumber = "GP Receipt Number"; diff --git a/data/config.cemetery.ssm.ts b/data/config.cemetery.ssm.ts index 723deffd..f447d45f 100644 --- a/data/config.cemetery.ssm.ts +++ b/data/config.cemetery.ssm.ts @@ -1,6 +1,38 @@ -import { config as cemeteryConfig } from "./config.cemetery.ontario.js"; +import { + config as cemeteryConfig +} from "./config.cemetery.ontario.js"; -export const config = Object.assign({}, cemeteryConfig); +export const config = Object.assign({}, cemeteryConfig); + +config.settings.lot = { + lotNameSortNameFunction: (lotName) => { + + const numericPadding = "00000"; + + const lotNameSplit = lotName.toUpperCase().split("-"); + + const cleanLotNamePieces: string[] = []; + + for (const lotNamePiece of lotNameSplit) { + + let numericPiece = numericPadding; + let letterPiece = ""; + + for (const letter of lotNamePiece) { + + if (letterPiece === "" && "0123456789".includes(letter)) { + numericPiece += letter; + } else { + letterPiece += letter; + } + } + + cleanLotNamePieces.push(numericPiece.slice(-1 * numericPadding.length) + letterPiece); + } + + return cleanLotNamePieces.join("-"); + } +}; config.settings.lotOccupancy.occupantCityDefault = "Sault Ste. Marie"; config.settings.map.mapCityDefault = "Sault Ste. Marie"; diff --git a/helpers/functions.config.d.ts b/helpers/functions.config.d.ts index eb655703..923cb056 100644 --- a/helpers/functions.config.d.ts +++ b/helpers/functions.config.d.ts @@ -26,6 +26,7 @@ export declare function getProperty(propertyName: "aliases.occupants"): string; export declare function getProperty(propertyName: "aliases.externalReceiptNumber"): string; export declare function getProperty(propertyName: "settings.map.mapCityDefault"): string; export declare function getProperty(propertyName: "settings.map.mapProvinceDefault"): string; +export declare function getProperty(propertyName: "settings.lot.lotNameSortNameFunction"): (lotName: string) => string; export declare function getProperty(propertyName: "settings.lotOccupancy.occupancyEndDateIsRequired"): boolean; export declare function getProperty(propertyName: "settings.lotOccupancy.occupantCityDefault"): string; export declare function getProperty(propertyName: "settings.lotOccupancy.occupantProvinceDefault"): string; diff --git a/helpers/functions.config.js b/helpers/functions.config.js index 30dd69cf..768adfab 100644 --- a/helpers/functions.config.js +++ b/helpers/functions.config.js @@ -26,6 +26,7 @@ configFallbackValues.set("aliases.occupants", "Occupants"); configFallbackValues.set("aliases.externalReceiptNumber", "External Receipt Number"); configFallbackValues.set("settings.map.mapCityDefault", ""); configFallbackValues.set("settings.map.mapProvinceDefault", ""); +configFallbackValues.set("settings.lot.lotNameSortNameFunction", (lotName) => lotName); configFallbackValues.set("settings.lotOccupancy.occupancyEndDateIsRequired", true); configFallbackValues.set("settings.lotOccupancy.occupantCityDefault", ""); configFallbackValues.set("settings.lotOccupancy.occupantProvinceDefault", ""); diff --git a/helpers/functions.config.ts b/helpers/functions.config.ts index 73691f44..cc969e92 100644 --- a/helpers/functions.config.ts +++ b/helpers/functions.config.ts @@ -46,6 +46,8 @@ configFallbackValues.set("aliases.externalReceiptNumber", "External Receipt Numb configFallbackValues.set("settings.map.mapCityDefault", ""); configFallbackValues.set("settings.map.mapProvinceDefault", ""); +configFallbackValues.set("settings.lot.lotNameSortNameFunction", (lotName: string) => lotName); + configFallbackValues.set("settings.lotOccupancy.occupancyEndDateIsRequired", true); configFallbackValues.set("settings.lotOccupancy.occupantCityDefault", ""); configFallbackValues.set("settings.lotOccupancy.occupantProvinceDefault", ""); @@ -91,6 +93,8 @@ export function getProperty(propertyName: "aliases.externalReceiptNumber"): stri export function getProperty(propertyName: "settings.map.mapCityDefault"): string; export function getProperty(propertyName: "settings.map.mapProvinceDefault"): string; +export function getProperty(propertyName: "settings.lot.lotNameSortNameFunction"): (lotName: string) => string; + export function getProperty(propertyName: "settings.lotOccupancy.occupancyEndDateIsRequired"): boolean; export function getProperty(propertyName: "settings.lotOccupancy.occupantCityDefault"): string; export function getProperty(propertyName: "settings.lotOccupancy.occupantProvinceDefault"): string; diff --git a/helpers/lotOccupancyDB/getLots.d.ts b/helpers/lotOccupancyDB/getLots.d.ts index ad97987b..4b880512 100644 --- a/helpers/lotOccupancyDB/getLots.d.ts +++ b/helpers/lotOccupancyDB/getLots.d.ts @@ -1,3 +1,4 @@ +import sqlite from "better-sqlite3"; import type * as recordTypes from "../../types/recordTypes"; interface GetLotsFilters { lotName?: string; @@ -10,7 +11,7 @@ interface GetLotsOptions { limit: number; offset: number; } -export declare const getLots: (filters?: GetLotsFilters, options?: GetLotsOptions) => { +export declare const getLots: (filters: GetLotsFilters, options: GetLotsOptions, connectedDatabase?: sqlite.Database) => { count: number; lots: recordTypes.Lot[]; }; diff --git a/helpers/lotOccupancyDB/getLots.js b/helpers/lotOccupancyDB/getLots.js index 1ba2d1c4..c5c98162 100644 --- a/helpers/lotOccupancyDB/getLots.js +++ b/helpers/lotOccupancyDB/getLots.js @@ -1,8 +1,9 @@ import sqlite from "better-sqlite3"; import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; import { dateToInteger } from "@cityssm/expressjs-server-js/dateTimeFns.js"; -export const getLots = (filters, options) => { - const database = sqlite(databasePath, { +import * as configFunctions from "../functions.config.js"; +export const getLots = (filters, options, connectedDatabase) => { + const database = connectedDatabase || sqlite(databasePath, { readonly: true }); let sqlWhereClause = " where l.recordDelete_timeMillis is null"; @@ -50,6 +51,7 @@ export const getLots = (filters, options) => { .recordCount; let lots = []; if (count > 0) { + database.function("userFn_lotNameSortName", configFunctions.getProperty("settings.lot.lotNameSortNameFunction")); lots = database .prepare("select l.lotId, l.lotName," + " t.lotType," + @@ -69,13 +71,15 @@ export const getLots = (filters, options) => { " group by lotId" + ") o on l.lotId = o.lotId") + sqlWhereClause + - " order by l.lotName, l.lotId" + + " order by userFn_lotNameSortName(l.lotName), l.lotId" + (options ? " limit " + options.limit + " offset " + options.offset : "")) .all(sqlParameters); } - database.close(); + if (!connectedDatabase) { + database.close(); + } return { count, lots diff --git a/helpers/lotOccupancyDB/getLots.ts b/helpers/lotOccupancyDB/getLots.ts index 26354466..449138a9 100644 --- a/helpers/lotOccupancyDB/getLots.ts +++ b/helpers/lotOccupancyDB/getLots.ts @@ -8,6 +8,8 @@ import { dateToInteger } from "@cityssm/expressjs-server-js/dateTimeFns.js"; +import * as configFunctions from "../functions.config.js"; + import type * as recordTypes from "../../types/recordTypes"; @@ -25,12 +27,14 @@ interface GetLotsOptions { } -export const getLots = (filters ? : GetLotsFilters, options ? : GetLotsOptions): { +export const getLots = (filters: GetLotsFilters, + options: GetLotsOptions, + connectedDatabase ? : sqlite.Database): { count: number; lots: recordTypes.Lot[]; } => { - const database = sqlite(databasePath, { + const database = connectedDatabase || sqlite(databasePath, { readonly: true }); @@ -88,6 +92,8 @@ export const getLots = (filters ? : GetLotsFilters, options ? : GetLotsOptions): if (count > 0) { + database.function("userFn_lotNameSortName", configFunctions.getProperty("settings.lot.lotNameSortNameFunction")); + lots = database .prepare("select l.lotId, l.lotName," + " t.lotType," + @@ -107,14 +113,16 @@ export const getLots = (filters ? : GetLotsFilters, options ? : GetLotsOptions): " group by lotId" + ") o on l.lotId = o.lotId") + sqlWhereClause + - " order by l.lotName, l.lotId" + + " order by userFn_lotNameSortName(l.lotName), l.lotId" + (options ? " limit " + options.limit + " offset " + options.offset : "")) .all(sqlParameters); } - database.close(); + if (!connectedDatabase) { + database.close(); + } return { count, diff --git a/helpers/lotOccupancyDB/getNextLotId.js b/helpers/lotOccupancyDB/getNextLotId.js index 2d1c930c..5f7b79dd 100644 --- a/helpers/lotOccupancyDB/getNextLotId.js +++ b/helpers/lotOccupancyDB/getNextLotId.js @@ -1,14 +1,16 @@ import sqlite from "better-sqlite3"; import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; +import * as configFunctions from "../functions.config.js"; export const getNextLotId = (lotId) => { const database = sqlite(databasePath, { readonly: true }); + database.function("userFn_lotNameSortName", configFunctions.getProperty("settings.lot.lotNameSortNameFunction")); const result = database .prepare("select lotId from Lots" + " where recordDelete_timeMillis is null" + - " and lotName > (select lotName from Lots where lotId = ?)" + - " order by lotName" + + " and userFn_lotNameSortName(lotName) > (select userFn_lotNameSortName(lotName) from Lots where lotId = ?)" + + " order by userFn_lotNameSortName(lotName)" + " limit 1") .get(lotId); database.close(); diff --git a/helpers/lotOccupancyDB/getNextLotId.ts b/helpers/lotOccupancyDB/getNextLotId.ts index 05bb3e77..3f886ffb 100644 --- a/helpers/lotOccupancyDB/getNextLotId.ts +++ b/helpers/lotOccupancyDB/getNextLotId.ts @@ -4,6 +4,8 @@ import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; +import * as configFunctions from "../functions.config.js"; + export const getNextLotId = (lotId: number | string): number => { @@ -11,13 +13,15 @@ export const getNextLotId = (lotId: number | string): number => { readonly: true }); + database.function("userFn_lotNameSortName", configFunctions.getProperty("settings.lot.lotNameSortNameFunction")); + const result: { lotId: number } = database .prepare("select lotId from Lots" + " where recordDelete_timeMillis is null" + - " and lotName > (select lotName from Lots where lotId = ?)" + - " order by lotName" + + " and userFn_lotNameSortName(lotName) > (select userFn_lotNameSortName(lotName) from Lots where lotId = ?)" + + " order by userFn_lotNameSortName(lotName)" + " limit 1") .get(lotId); diff --git a/helpers/lotOccupancyDB/getPreviousLotId.js b/helpers/lotOccupancyDB/getPreviousLotId.js index a1fd624b..7f243a21 100644 --- a/helpers/lotOccupancyDB/getPreviousLotId.js +++ b/helpers/lotOccupancyDB/getPreviousLotId.js @@ -1,14 +1,16 @@ import sqlite from "better-sqlite3"; import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; +import * as configFunctions from "../functions.config.js"; export const getPreviousLotId = (lotId) => { const database = sqlite(databasePath, { readonly: true }); + database.function("userFn_lotNameSortName", configFunctions.getProperty("settings.lot.lotNameSortNameFunction")); const result = database .prepare("select lotId from Lots" + " where recordDelete_timeMillis is null" + - " and lotName < (select lotName from Lots where lotId = ?)" + - " order by lotName desc" + + " and userFn_lotNameSortName(lotName) < (select userFn_lotNameSortName(lotName) from Lots where lotId = ?)" + + " order by userFn_lotNameSortName(lotName) desc" + " limit 1") .get(lotId); database.close(); diff --git a/helpers/lotOccupancyDB/getPreviousLotId.ts b/helpers/lotOccupancyDB/getPreviousLotId.ts index 578f05e8..e869ae54 100644 --- a/helpers/lotOccupancyDB/getPreviousLotId.ts +++ b/helpers/lotOccupancyDB/getPreviousLotId.ts @@ -4,6 +4,8 @@ import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; +import * as configFunctions from "../functions.config.js"; + export const getPreviousLotId = (lotId: number | string): number => { @@ -11,13 +13,15 @@ export const getPreviousLotId = (lotId: number | string): number => { readonly: true }); + database.function("userFn_lotNameSortName", configFunctions.getProperty("settings.lot.lotNameSortNameFunction")); + const result: { lotId: number } = database .prepare("select lotId from Lots" + " where recordDelete_timeMillis is null" + - " and lotName < (select lotName from Lots where lotId = ?)" + - " order by lotName desc" + + " and userFn_lotNameSortName(lotName) < (select userFn_lotNameSortName(lotName) from Lots where lotId = ?)" + + " order by userFn_lotNameSortName(lotName) desc" + " limit 1") .get(lotId); diff --git a/temp/legacy.importFromCSV.js b/temp/legacy.importFromCSV.js index dda9aae4..894f6eb5 100644 --- a/temp/legacy.importFromCSV.js +++ b/temp/legacy.importFromCSV.js @@ -459,6 +459,9 @@ function importFromPrepaidCSV() { const possibleLots = getLots({ mapId: map.mapId, lotName + }, { + limit: -1, + offset: 0 }); if (possibleLots.lots.length > 0) { lot = possibleLots.lots[0]; diff --git a/temp/legacy.importFromCSV.ts b/temp/legacy.importFromCSV.ts index a0d027db..8b5889ff 100644 --- a/temp/legacy.importFromCSV.ts +++ b/temp/legacy.importFromCSV.ts @@ -777,7 +777,10 @@ function importFromPrepaidCSV() { const possibleLots = getLots({ mapId: map.mapId, lotName - }); + }, { + limit: -1, + offset: 0 + }; if (possibleLots.lots.length > 0) { lot = possibleLots.lots[0]; diff --git a/types/configTypes.d.ts b/types/configTypes.d.ts index bad989c5..d8a95766 100644 --- a/types/configTypes.d.ts +++ b/types/configTypes.d.ts @@ -32,6 +32,9 @@ export interface Config { mapCityDefault?: string; mapProvinceDefault?: string; }; + lot?: { + lotNameSortNameFunction?: (lotName: string) => string; + }; lotOccupancy?: { lotIdIsRequired?: boolean; occupancyEndDateIsRequired?: boolean; diff --git a/types/configTypes.ts b/types/configTypes.ts index 7b8651e7..ce497447 100644 --- a/types/configTypes.ts +++ b/types/configTypes.ts @@ -32,6 +32,9 @@ export interface Config { mapCityDefault ? : string; mapProvinceDefault ? : string; }; + lot ? : { + lotNameSortNameFunction ? : (lotName: string) => string; + }; lotOccupancy ? : { lotIdIsRequired ? : boolean; occupancyEndDateIsRequired ? : boolean;