deepsource-autofix-76c6eb20
Dan Gowans 2023-01-12 11:10:29 -05:00
parent c937521807
commit 062892ac3f
56 changed files with 2235 additions and 2011 deletions

View File

@ -1,16 +1,17 @@
import * as configFunctions from "./functions.config.js"; import * as configFunctions from './functions.config.js';
import ActiveDirectory from "activedirectory2"; import ActiveDirectory from 'activedirectory2';
const userDomain = configFunctions.getProperty("application.userDomain"); const userDomain = configFunctions.getProperty('application.userDomain');
const activeDirectoryConfig = configFunctions.getProperty("activeDirectory"); const activeDirectoryConfig = configFunctions.getProperty('activeDirectory');
async function authenticateViaActiveDirectory(userName, password) { async function authenticateViaActiveDirectory(userName, password) {
return new Promise((resolve) => { return await new Promise((resolve) => {
try { try {
const ad = new ActiveDirectory(activeDirectoryConfig); const ad = new ActiveDirectory(activeDirectoryConfig);
ad.authenticate(userDomain + "\\" + userName, password, async (error, auth) => { ad.authenticate(userDomain + '\\' + userName, password, (error, auth) => {
if (error) { let authenticated = false;
resolve(false); if (!error) {
authenticated = auth;
} }
resolve(auth); resolve(authenticated);
}); });
} }
catch { catch {
@ -19,32 +20,32 @@ async function authenticateViaActiveDirectory(userName, password) {
}); });
} }
export async function authenticate(userName, password) { export async function authenticate(userName, password) {
if (!userName || userName === "" || !password || password === "") { if (!userName || userName === '' || !password || password === '') {
return false; return false;
} }
return await authenticateViaActiveDirectory(userName, password); return await authenticateViaActiveDirectory(userName, password);
} }
const safeRedirects = new Set([ const safeRedirects = new Set([
"/admin/cleanup", '/admin/cleanup',
"/admin/fees", '/admin/fees',
"/admin/lottypes", '/admin/lottypes',
"/admin/occupancytypes", '/admin/occupancytypes',
"/admin/tables", '/admin/tables',
"/lotoccupancies", '/lotoccupancies',
"/lotoccupancies/new", '/lotoccupancies/new',
"/lots", '/lots',
"/lots/new", '/lots/new',
"/maps", '/maps',
"/maps/new", '/maps/new',
"/workorders", '/workorders',
"/workorders/new", '/workorders/new',
"/workorders/milestonecalendar", '/workorders/milestonecalendar',
"/workorders/outlook", '/workorders/outlook',
"/reports" '/reports'
]); ]);
export function getSafeRedirectURL(possibleRedirectURL = "") { export function getSafeRedirectURL(possibleRedirectURL = '') {
const urlPrefix = configFunctions.getProperty("reverseProxy.urlPrefix"); const urlPrefix = configFunctions.getProperty('reverseProxy.urlPrefix');
if (typeof possibleRedirectURL === "string") { if (typeof possibleRedirectURL === 'string') {
const urlToCheck = possibleRedirectURL.startsWith(urlPrefix) const urlToCheck = possibleRedirectURL.startsWith(urlPrefix)
? possibleRedirectURL.slice(urlPrefix.length) ? possibleRedirectURL.slice(urlPrefix.length)
: possibleRedirectURL; : possibleRedirectURL;
@ -58,5 +59,5 @@ export function getSafeRedirectURL(possibleRedirectURL = "") {
return urlPrefix + urlToCheck; return urlPrefix + urlToCheck;
} }
} }
return urlPrefix + "/dashboard"; return urlPrefix + '/dashboard';
} }

View File

@ -1,68 +1,73 @@
import * as configFunctions from "./functions.config.js"; import * as configFunctions from './functions.config.js'
import ActiveDirectory from "activedirectory2"; import ActiveDirectory from 'activedirectory2'
const userDomain = configFunctions.getProperty("application.userDomain"); const userDomain = configFunctions.getProperty('application.userDomain')
const activeDirectoryConfig = configFunctions.getProperty("activeDirectory"); const activeDirectoryConfig = configFunctions.getProperty('activeDirectory')
async function authenticateViaActiveDirectory( async function authenticateViaActiveDirectory(
userName: string, userName: string,
password: string password: string
): Promise<boolean> { ): Promise<boolean> {
return new Promise((resolve) => { return await new Promise((resolve) => {
try { try {
const ad = new ActiveDirectory(activeDirectoryConfig); const ad = new ActiveDirectory(activeDirectoryConfig)
ad.authenticate(userDomain + "\\" + userName, password, async (error, auth) => { ad.authenticate(userDomain + '\\' + userName, password, (error, auth) => {
if (error) { let authenticated = false
resolve(false);
if (!error) {
authenticated = auth
} }
resolve(auth); resolve(authenticated)
}); })
} catch { } catch {
resolve(false); resolve(false)
} }
}); })
} }
export async function authenticate(userName: string, password: string): Promise<boolean> { export async function authenticate(
if (!userName || userName === "" || !password || password === "") { userName: string,
return false; password: string
): Promise<boolean> {
if (!userName || userName === '' || !password || password === '') {
return false
} }
return await authenticateViaActiveDirectory(userName, password); return await authenticateViaActiveDirectory(userName, password)
} }
const safeRedirects = new Set([ const safeRedirects = new Set([
"/admin/cleanup", '/admin/cleanup',
"/admin/fees", '/admin/fees',
"/admin/lottypes", '/admin/lottypes',
"/admin/occupancytypes", '/admin/occupancytypes',
"/admin/tables", '/admin/tables',
"/lotoccupancies", '/lotoccupancies',
"/lotoccupancies/new", '/lotoccupancies/new',
"/lots", '/lots',
"/lots/new", '/lots/new',
"/maps", '/maps',
"/maps/new", '/maps/new',
"/workorders", '/workorders',
"/workorders/new", '/workorders/new',
"/workorders/milestonecalendar", '/workorders/milestonecalendar',
"/workorders/outlook", '/workorders/outlook',
"/reports" '/reports'
]); ])
export function getSafeRedirectURL(possibleRedirectURL = "") { export function getSafeRedirectURL(possibleRedirectURL = ''): string {
const urlPrefix = configFunctions.getProperty("reverseProxy.urlPrefix"); const urlPrefix = configFunctions.getProperty('reverseProxy.urlPrefix')
if (typeof possibleRedirectURL === "string") { if (typeof possibleRedirectURL === 'string') {
const urlToCheck = possibleRedirectURL.startsWith(urlPrefix) const urlToCheck = possibleRedirectURL.startsWith(urlPrefix)
? possibleRedirectURL.slice(urlPrefix.length) ? possibleRedirectURL.slice(urlPrefix.length)
: possibleRedirectURL; : possibleRedirectURL
const urlToCheckLowerCase = urlToCheck.toLowerCase(); const urlToCheckLowerCase = urlToCheck.toLowerCase()
if ( if (
safeRedirects.has(urlToCheckLowerCase) || safeRedirects.has(urlToCheckLowerCase) ||
@ -72,9 +77,9 @@ export function getSafeRedirectURL(possibleRedirectURL = "") {
/^(\/workorders\/)\d+(\/edit)?$/.test(urlToCheckLowerCase) || /^(\/workorders\/)\d+(\/edit)?$/.test(urlToCheckLowerCase) ||
/^\/print\/(pdf|screen)\/[\d/=?A-Za-z-]+$/.test(urlToCheck) /^\/print\/(pdf|screen)\/[\d/=?A-Za-z-]+$/.test(urlToCheck)
) { ) {
return urlPrefix + urlToCheck; return urlPrefix + urlToCheck
} }
} }
return urlPrefix + "/dashboard"; return urlPrefix + '/dashboard'
} }

View File

@ -1,49 +1,49 @@
import type * as configTypes from "../types/configTypes"; import type * as configTypes from '../types/configTypes';
export declare function getProperty(propertyName: "application.applicationName"): string; export declare function getProperty(propertyName: 'application.applicationName'): string;
export declare function getProperty(propertyName: "application.logoURL"): string; export declare function getProperty(propertyName: 'application.logoURL'): string;
export declare function getProperty(propertyName: "application.httpPort"): number; export declare function getProperty(propertyName: 'application.httpPort'): number;
export declare function getProperty(propertyName: "application.userDomain"): string; export declare function getProperty(propertyName: 'application.userDomain'): string;
export declare function getProperty(propertyName: "application.useTestDatabases"): boolean; export declare function getProperty(propertyName: 'application.useTestDatabases'): boolean;
export declare function getProperty(propertyName: "application.ntfyStartup"): configTypes.ConfigNtfyStartup; export declare function getProperty(propertyName: 'application.ntfyStartup'): configTypes.ConfigNtfyStartup;
export declare function getProperty(propertyName: "activeDirectory"): configTypes.ConfigActiveDirectory; export declare function getProperty(propertyName: 'activeDirectory'): configTypes.ConfigActiveDirectory;
export declare function getProperty(propertyName: "users.testing"): string[]; export declare function getProperty(propertyName: 'users.testing'): string[];
export declare function getProperty(propertyName: "users.canLogin"): string[]; export declare function getProperty(propertyName: 'users.canLogin'): string[];
export declare function getProperty(propertyName: "users.canUpdate"): string[]; export declare function getProperty(propertyName: 'users.canUpdate'): string[];
export declare function getProperty(propertyName: "users.isAdmin"): string[]; export declare function getProperty(propertyName: 'users.isAdmin'): string[];
export declare function getProperty(propertyName: "reverseProxy.disableCompression"): boolean; export declare function getProperty(propertyName: 'reverseProxy.disableCompression'): boolean;
export declare function getProperty(propertyName: "reverseProxy.disableEtag"): boolean; export declare function getProperty(propertyName: 'reverseProxy.disableEtag'): boolean;
export declare function getProperty(propertyName: "reverseProxy.urlPrefix"): string; export declare function getProperty(propertyName: 'reverseProxy.urlPrefix'): string;
export declare function getProperty(propertyName: "session.cookieName"): string; export declare function getProperty(propertyName: 'session.cookieName'): string;
export declare function getProperty(propertyName: "session.doKeepAlive"): boolean; export declare function getProperty(propertyName: 'session.doKeepAlive'): boolean;
export declare function getProperty(propertyName: "session.maxAgeMillis"): number; export declare function getProperty(propertyName: 'session.maxAgeMillis'): number;
export declare function getProperty(propertyName: "session.secret"): string; export declare function getProperty(propertyName: 'session.secret'): string;
export declare function getProperty(propertyName: "aliases.lot"): string; export declare function getProperty(propertyName: 'aliases.lot'): string;
export declare function getProperty(propertyName: "aliases.lots"): string; export declare function getProperty(propertyName: 'aliases.lots'): string;
export declare function getProperty(propertyName: "aliases.map"): string; export declare function getProperty(propertyName: 'aliases.map'): string;
export declare function getProperty(propertyName: "aliases.maps"): string; export declare function getProperty(propertyName: 'aliases.maps'): string;
export declare function getProperty(propertyName: "aliases.occupancy"): string; export declare function getProperty(propertyName: 'aliases.occupancy'): string;
export declare function getProperty(propertyName: "aliases.occupancies"): string; export declare function getProperty(propertyName: 'aliases.occupancies'): string;
export declare function getProperty(propertyName: "aliases.occupancyStartDate"): string; export declare function getProperty(propertyName: 'aliases.occupancyStartDate'): string;
export declare function getProperty(propertyName: "aliases.occupant"): string; export declare function getProperty(propertyName: 'aliases.occupant'): string;
export declare function getProperty(propertyName: "aliases.occupants"): string; export declare function getProperty(propertyName: 'aliases.occupants'): string;
export declare function getProperty(propertyName: "aliases.workOrderOpenDate"): string; export declare function getProperty(propertyName: 'aliases.workOrderOpenDate'): string;
export declare function getProperty(propertyName: "aliases.workOrderCloseDate"): string; export declare function getProperty(propertyName: 'aliases.workOrderCloseDate'): string;
export declare function getProperty(propertyName: "aliases.externalReceiptNumber"): 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.mapCityDefault'): string;
export declare function getProperty(propertyName: "settings.map.mapProvinceDefault"): string; export declare function getProperty(propertyName: 'settings.map.mapProvinceDefault'): string;
export declare function getProperty(propertyName: "settings.lot.lotNamePattern"): RegExp; export declare function getProperty(propertyName: 'settings.lot.lotNamePattern'): RegExp;
export declare function getProperty(propertyName: "settings.lot.lotNameHelpText"): string; export declare function getProperty(propertyName: 'settings.lot.lotNameHelpText'): string;
export declare function getProperty(propertyName: "settings.lot.lotNameSortNameFunction"): (lotName: string) => 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.occupancyEndDateIsRequired'): boolean;
export declare function getProperty(propertyName: "settings.lotOccupancy.occupantCityDefault"): string; export declare function getProperty(propertyName: 'settings.lotOccupancy.occupantCityDefault'): string;
export declare function getProperty(propertyName: "settings.lotOccupancy.occupantProvinceDefault"): string; export declare function getProperty(propertyName: 'settings.lotOccupancy.occupantProvinceDefault'): string;
export declare function getProperty(propertyName: "settings.lotOccupancy.prints"): string[]; export declare function getProperty(propertyName: 'settings.lotOccupancy.prints'): string[];
export declare function getProperty(propertyName: "settings.fees.taxPercentageDefault"): number; export declare function getProperty(propertyName: 'settings.fees.taxPercentageDefault'): number;
export declare function getProperty(propertyName: "settings.workOrders.workOrderNumberLength"): number; export declare function getProperty(propertyName: 'settings.workOrders.workOrderNumberLength'): number;
export declare function getProperty(propertyName: "settings.workOrders.workOrderMilestoneDateRecentBeforeDays"): number; export declare function getProperty(propertyName: 'settings.workOrders.workOrderMilestoneDateRecentBeforeDays'): number;
export declare function getProperty(propertyName: "settings.workOrders.workOrderMilestoneDateRecentAfterDays"): number; export declare function getProperty(propertyName: 'settings.workOrders.workOrderMilestoneDateRecentAfterDays'): number;
export declare function getProperty(propertyName: "settings.workOrders.calendarEmailAddress"): string; export declare function getProperty(propertyName: 'settings.workOrders.calendarEmailAddress'): string;
export declare function getProperty(propertyName: "settings.workOrders.prints"): string[]; export declare function getProperty(propertyName: 'settings.workOrders.prints'): string[];
export declare function getProperty(propertyName: "settings.adminCleanup.recordDeleteAgeDays"): number; export declare function getProperty(propertyName: 'settings.adminCleanup.recordDeleteAgeDays'): number;
export declare function getProperty(propertyName: "settings.printPdf.contentDisposition"): "attachment" | "inline"; export declare function getProperty(propertyName: 'settings.printPdf.contentDisposition'): 'attachment' | 'inline';
export declare const keepAliveMillis: number; export declare const keepAliveMillis: number;

View File

@ -1,53 +1,55 @@
import { config } from "../data/config.js"; import { config } from '../data/config.js';
const configFallbackValues = new Map(); const configFallbackValues = new Map();
configFallbackValues.set("application.applicationName", "Lot Occupancy System"); configFallbackValues.set('application.applicationName', 'Lot Occupancy System');
configFallbackValues.set("application.backgroundURL", "/images/cemetery-background.jpg"); configFallbackValues.set('application.backgroundURL', '/images/cemetery-background.jpg');
configFallbackValues.set("application.logoURL", "/images/cemetery-logo.png"); configFallbackValues.set('application.logoURL', '/images/cemetery-logo.png');
configFallbackValues.set("application.httpPort", 7000); configFallbackValues.set('application.httpPort', 7000);
configFallbackValues.set("application.useTestDatabases", false); configFallbackValues.set('application.useTestDatabases', false);
configFallbackValues.set("reverseProxy.disableCompression", false); configFallbackValues.set('reverseProxy.disableCompression', false);
configFallbackValues.set("reverseProxy.disableEtag", false); configFallbackValues.set('reverseProxy.disableEtag', false);
configFallbackValues.set("reverseProxy.urlPrefix", ""); configFallbackValues.set('reverseProxy.urlPrefix', '');
configFallbackValues.set("session.cookieName", "lot-occupancy-system-user-sid"); configFallbackValues.set('session.cookieName', 'lot-occupancy-system-user-sid');
configFallbackValues.set("session.secret", "cityssm/lot-occupancy-system"); configFallbackValues.set('session.secret', 'cityssm/lot-occupancy-system');
configFallbackValues.set("session.maxAgeMillis", 60 * 60 * 1000); configFallbackValues.set('session.maxAgeMillis', 60 * 60 * 1000);
configFallbackValues.set("session.doKeepAlive", false); configFallbackValues.set('session.doKeepAlive', false);
configFallbackValues.set("users.testing", []); configFallbackValues.set('users.testing', []);
configFallbackValues.set("users.canLogin", ["administrator"]); configFallbackValues.set('users.canLogin', ['administrator']);
configFallbackValues.set("users.canUpdate", []); configFallbackValues.set('users.canUpdate', []);
configFallbackValues.set("users.isAdmin", ["administrator"]); configFallbackValues.set('users.isAdmin', ['administrator']);
configFallbackValues.set("aliases.lot", "Lot"); configFallbackValues.set('aliases.lot', 'Lot');
configFallbackValues.set("aliases.lots", "Lots"); configFallbackValues.set('aliases.lots', 'Lots');
configFallbackValues.set("aliases.map", "Map"); configFallbackValues.set('aliases.map', 'Map');
configFallbackValues.set("aliases.maps", "Maps"); configFallbackValues.set('aliases.maps', 'Maps');
configFallbackValues.set("aliases.occupancy", "Occupancy"); configFallbackValues.set('aliases.occupancy', 'Occupancy');
configFallbackValues.set("aliases.occupancies", "Occupancies"); configFallbackValues.set('aliases.occupancies', 'Occupancies');
configFallbackValues.set("aliases.occupancyStartDate", "Start Date"); configFallbackValues.set('aliases.occupancyStartDate', 'Start Date');
configFallbackValues.set("aliases.occupant", "Occupant"); configFallbackValues.set('aliases.occupant', 'Occupant');
configFallbackValues.set("aliases.occupants", "Occupants"); configFallbackValues.set('aliases.occupants', 'Occupants');
configFallbackValues.set("aliases.externalReceiptNumber", "External Receipt Number"); configFallbackValues.set('aliases.externalReceiptNumber', 'External Receipt Number');
configFallbackValues.set("aliases.workOrderOpenDate", "Open Date"); configFallbackValues.set('aliases.workOrderOpenDate', 'Open Date');
configFallbackValues.set("aliases.workOrderCloseDate", "Close Date"); configFallbackValues.set('aliases.workOrderCloseDate', 'Close Date');
configFallbackValues.set("settings.map.mapCityDefault", ""); configFallbackValues.set('settings.map.mapCityDefault', '');
configFallbackValues.set("settings.map.mapProvinceDefault", ""); configFallbackValues.set('settings.map.mapProvinceDefault', '');
configFallbackValues.set("settings.lot.lotNameSortNameFunction", (lotName) => lotName); configFallbackValues.set('settings.lot.lotNameSortNameFunction', (lotName) => lotName);
configFallbackValues.set("settings.lotOccupancy.occupancyEndDateIsRequired", true); configFallbackValues.set('settings.lotOccupancy.occupancyEndDateIsRequired', true);
configFallbackValues.set("settings.lotOccupancy.occupantCityDefault", ""); configFallbackValues.set('settings.lotOccupancy.occupantCityDefault', '');
configFallbackValues.set("settings.lotOccupancy.occupantProvinceDefault", ""); configFallbackValues.set('settings.lotOccupancy.occupantProvinceDefault', '');
configFallbackValues.set("settings.lotOccupancy.prints", ["screen/lotOccupancy"]); configFallbackValues.set('settings.lotOccupancy.prints', [
configFallbackValues.set("settings.fees.taxPercentageDefault", 0); 'screen/lotOccupancy'
configFallbackValues.set("settings.workOrders.workOrderNumberLength", 6);
configFallbackValues.set("settings.workOrders.workOrderMilestoneDateRecentBeforeDays", 5);
configFallbackValues.set("settings.workOrders.workOrderMilestoneDateRecentAfterDays", 60);
configFallbackValues.set("settings.workOrders.calendarEmailAddress", "no-reply@127.0.0.1");
configFallbackValues.set("settings.workOrders.prints", [
"pdf/workOrder",
"pdf/workOrder-commentLog"
]); ]);
configFallbackValues.set("settings.adminCleanup.recordDeleteAgeDays", 60); configFallbackValues.set('settings.fees.taxPercentageDefault', 0);
configFallbackValues.set("settings.printPdf.contentDisposition", "attachment"); configFallbackValues.set('settings.workOrders.workOrderNumberLength', 6);
configFallbackValues.set('settings.workOrders.workOrderMilestoneDateRecentBeforeDays', 5);
configFallbackValues.set('settings.workOrders.workOrderMilestoneDateRecentAfterDays', 60);
configFallbackValues.set('settings.workOrders.calendarEmailAddress', 'no-reply@127.0.0.1');
configFallbackValues.set('settings.workOrders.prints', [
'pdf/workOrder',
'pdf/workOrder-commentLog'
]);
configFallbackValues.set('settings.adminCleanup.recordDeleteAgeDays', 60);
configFallbackValues.set('settings.printPdf.contentDisposition', 'attachment');
export function getProperty(propertyName) { export function getProperty(propertyName) {
const propertyNameSplit = propertyName.split("."); const propertyNameSplit = propertyName.split('.');
let currentObject = config; let currentObject = config;
for (const propertyNamePiece of propertyNameSplit) { for (const propertyNamePiece of propertyNameSplit) {
if (Object.prototype.hasOwnProperty.call(currentObject, propertyNamePiece)) { if (Object.prototype.hasOwnProperty.call(currentObject, propertyNamePiece)) {
@ -58,6 +60,6 @@ export function getProperty(propertyName) {
} }
return currentObject; return currentObject;
} }
export const keepAliveMillis = getProperty("session.doKeepAlive") export const keepAliveMillis = getProperty('session.doKeepAlive')
? Math.max(getProperty("session.maxAgeMillis") / 2, getProperty("session.maxAgeMillis") - 10 * 60 * 1000) ? Math.max(getProperty('session.maxAgeMillis') / 2, getProperty('session.maxAgeMillis') - 10 * 60 * 1000)
: 0; : 0;

View File

@ -1,176 +1,231 @@
/* eslint-disable node/no-unpublished-import */ /* eslint-disable @typescript-eslint/indent, node/no-unpublished-import */
import { config } from "../data/config.js"; import { config } from '../data/config.js'
import type * as configTypes from "../types/configTypes"; import type * as configTypes from '../types/configTypes'
/* /*
* SET UP FALLBACK VALUES * SET UP FALLBACK VALUES
*/ */
const configFallbackValues = new Map<string, unknown>(); const configFallbackValues = new Map<string, unknown>()
configFallbackValues.set("application.applicationName", "Lot Occupancy System"); configFallbackValues.set('application.applicationName', 'Lot Occupancy System')
configFallbackValues.set("application.backgroundURL", "/images/cemetery-background.jpg"); configFallbackValues.set(
configFallbackValues.set("application.logoURL", "/images/cemetery-logo.png"); 'application.backgroundURL',
configFallbackValues.set("application.httpPort", 7000); '/images/cemetery-background.jpg'
configFallbackValues.set("application.useTestDatabases", false); )
configFallbackValues.set('application.logoURL', '/images/cemetery-logo.png')
configFallbackValues.set('application.httpPort', 7000)
configFallbackValues.set('application.useTestDatabases', false)
configFallbackValues.set("reverseProxy.disableCompression", false); configFallbackValues.set('reverseProxy.disableCompression', false)
configFallbackValues.set("reverseProxy.disableEtag", false); configFallbackValues.set('reverseProxy.disableEtag', false)
configFallbackValues.set("reverseProxy.urlPrefix", ""); configFallbackValues.set('reverseProxy.urlPrefix', '')
configFallbackValues.set("session.cookieName", "lot-occupancy-system-user-sid"); configFallbackValues.set('session.cookieName', 'lot-occupancy-system-user-sid')
configFallbackValues.set("session.secret", "cityssm/lot-occupancy-system"); configFallbackValues.set('session.secret', 'cityssm/lot-occupancy-system')
configFallbackValues.set("session.maxAgeMillis", 60 * 60 * 1000); configFallbackValues.set('session.maxAgeMillis', 60 * 60 * 1000)
configFallbackValues.set("session.doKeepAlive", false); configFallbackValues.set('session.doKeepAlive', false)
configFallbackValues.set("users.testing", []); configFallbackValues.set('users.testing', [])
configFallbackValues.set("users.canLogin", ["administrator"]); configFallbackValues.set('users.canLogin', ['administrator'])
configFallbackValues.set("users.canUpdate", []); configFallbackValues.set('users.canUpdate', [])
configFallbackValues.set("users.isAdmin", ["administrator"]); configFallbackValues.set('users.isAdmin', ['administrator'])
configFallbackValues.set("aliases.lot", "Lot"); configFallbackValues.set('aliases.lot', 'Lot')
configFallbackValues.set("aliases.lots", "Lots"); configFallbackValues.set('aliases.lots', 'Lots')
configFallbackValues.set("aliases.map", "Map"); configFallbackValues.set('aliases.map', 'Map')
configFallbackValues.set("aliases.maps", "Maps"); configFallbackValues.set('aliases.maps', 'Maps')
configFallbackValues.set("aliases.occupancy", "Occupancy"); configFallbackValues.set('aliases.occupancy', 'Occupancy')
configFallbackValues.set("aliases.occupancies", "Occupancies"); configFallbackValues.set('aliases.occupancies', 'Occupancies')
configFallbackValues.set("aliases.occupancyStartDate", "Start Date"); configFallbackValues.set('aliases.occupancyStartDate', 'Start Date')
configFallbackValues.set("aliases.occupant", "Occupant"); configFallbackValues.set('aliases.occupant', 'Occupant')
configFallbackValues.set("aliases.occupants", "Occupants"); configFallbackValues.set('aliases.occupants', 'Occupants')
configFallbackValues.set("aliases.externalReceiptNumber", "External Receipt Number"); configFallbackValues.set(
configFallbackValues.set("aliases.workOrderOpenDate", "Open Date"); 'aliases.externalReceiptNumber',
configFallbackValues.set("aliases.workOrderCloseDate", "Close Date"); 'External Receipt Number'
)
configFallbackValues.set('aliases.workOrderOpenDate', 'Open Date')
configFallbackValues.set('aliases.workOrderCloseDate', 'Close Date')
configFallbackValues.set("settings.map.mapCityDefault", ""); configFallbackValues.set('settings.map.mapCityDefault', '')
configFallbackValues.set("settings.map.mapProvinceDefault", ""); configFallbackValues.set('settings.map.mapProvinceDefault', '')
configFallbackValues.set("settings.lot.lotNameSortNameFunction", (lotName: string) => lotName); configFallbackValues.set(
'settings.lot.lotNameSortNameFunction',
(lotName: string) => lotName
)
configFallbackValues.set("settings.lotOccupancy.occupancyEndDateIsRequired", true); configFallbackValues.set(
configFallbackValues.set("settings.lotOccupancy.occupantCityDefault", ""); 'settings.lotOccupancy.occupancyEndDateIsRequired',
configFallbackValues.set("settings.lotOccupancy.occupantProvinceDefault", ""); true
configFallbackValues.set("settings.lotOccupancy.prints", ["screen/lotOccupancy"]); )
configFallbackValues.set('settings.lotOccupancy.occupantCityDefault', '')
configFallbackValues.set('settings.lotOccupancy.occupantProvinceDefault', '')
configFallbackValues.set('settings.lotOccupancy.prints', [
'screen/lotOccupancy'
])
configFallbackValues.set("settings.fees.taxPercentageDefault", 0); configFallbackValues.set('settings.fees.taxPercentageDefault', 0)
configFallbackValues.set("settings.workOrders.workOrderNumberLength", 6); configFallbackValues.set('settings.workOrders.workOrderNumberLength', 6)
configFallbackValues.set("settings.workOrders.workOrderMilestoneDateRecentBeforeDays", 5); configFallbackValues.set(
configFallbackValues.set("settings.workOrders.workOrderMilestoneDateRecentAfterDays", 60); 'settings.workOrders.workOrderMilestoneDateRecentBeforeDays',
configFallbackValues.set("settings.workOrders.calendarEmailAddress", "no-reply@127.0.0.1"); 5
configFallbackValues.set("settings.workOrders.prints", [ )
"pdf/workOrder", configFallbackValues.set(
"pdf/workOrder-commentLog" 'settings.workOrders.workOrderMilestoneDateRecentAfterDays',
]); 60
)
configFallbackValues.set(
'settings.workOrders.calendarEmailAddress',
'no-reply@127.0.0.1'
)
configFallbackValues.set('settings.workOrders.prints', [
'pdf/workOrder',
'pdf/workOrder-commentLog'
])
configFallbackValues.set("settings.adminCleanup.recordDeleteAgeDays", 60); configFallbackValues.set('settings.adminCleanup.recordDeleteAgeDays', 60)
configFallbackValues.set("settings.printPdf.contentDisposition", "attachment"); configFallbackValues.set('settings.printPdf.contentDisposition', 'attachment')
/* /*
* Set up function overloads * Set up function overloads
*/ */
export function getProperty(propertyName: "application.applicationName"): string; export function getProperty(propertyName: 'application.applicationName'): string
export function getProperty(propertyName: "application.logoURL"): string; export function getProperty(propertyName: 'application.logoURL'): string
export function getProperty(propertyName: "application.httpPort"): number; export function getProperty(propertyName: 'application.httpPort'): number
export function getProperty(propertyName: "application.userDomain"): string; export function getProperty(propertyName: 'application.userDomain'): string
export function getProperty(propertyName: "application.useTestDatabases"): boolean; export function getProperty(
export function getProperty(propertyName: "application.ntfyStartup"): configTypes.ConfigNtfyStartup; propertyName: 'application.useTestDatabases'
): boolean
export function getProperty(propertyName: "activeDirectory"): configTypes.ConfigActiveDirectory; export function getProperty(
propertyName: 'application.ntfyStartup'
export function getProperty(propertyName: "users.testing"): string[]; ): configTypes.ConfigNtfyStartup
export function getProperty(propertyName: "users.canLogin"): string[];
export function getProperty(propertyName: "users.canUpdate"): string[];
export function getProperty(propertyName: "users.isAdmin"): string[];
export function getProperty(propertyName: "reverseProxy.disableCompression"): boolean;
export function getProperty(propertyName: "reverseProxy.disableEtag"): boolean;
export function getProperty(propertyName: "reverseProxy.urlPrefix"): string;
export function getProperty(propertyName: "session.cookieName"): string;
export function getProperty(propertyName: "session.doKeepAlive"): boolean;
export function getProperty(propertyName: "session.maxAgeMillis"): number;
export function getProperty(propertyName: "session.secret"): string;
export function getProperty(propertyName: "aliases.lot"): string;
export function getProperty(propertyName: "aliases.lots"): string;
export function getProperty(propertyName: "aliases.map"): string;
export function getProperty(propertyName: "aliases.maps"): string;
export function getProperty(propertyName: "aliases.occupancy"): string;
export function getProperty(propertyName: "aliases.occupancies"): string;
export function getProperty(propertyName: "aliases.occupancyStartDate"): string;
export function getProperty(propertyName: "aliases.occupant"): string;
export function getProperty(propertyName: "aliases.occupants"): string;
export function getProperty(propertyName: "aliases.workOrderOpenDate"): string;
export function getProperty(propertyName: "aliases.workOrderCloseDate"): string;
export function getProperty(propertyName: "aliases.externalReceiptNumber"): string;
export function getProperty(propertyName: "settings.map.mapCityDefault"): string;
export function getProperty(propertyName: "settings.map.mapProvinceDefault"): string;
export function getProperty(propertyName: "settings.lot.lotNamePattern"): RegExp;
export function getProperty(propertyName: "settings.lot.lotNameHelpText"): string;
export function getProperty( export function getProperty(
propertyName: "settings.lot.lotNameSortNameFunction" propertyName: 'activeDirectory'
): (lotName: string) => string; ): configTypes.ConfigActiveDirectory
export function getProperty(propertyName: 'users.testing'): string[]
export function getProperty(propertyName: 'users.canLogin'): string[]
export function getProperty(propertyName: 'users.canUpdate'): string[]
export function getProperty(propertyName: 'users.isAdmin'): string[]
export function getProperty( export function getProperty(
propertyName: "settings.lotOccupancy.occupancyEndDateIsRequired" propertyName: 'reverseProxy.disableCompression'
): boolean; ): boolean
export function getProperty(propertyName: "settings.lotOccupancy.occupantCityDefault"): string; export function getProperty(propertyName: 'reverseProxy.disableEtag'): boolean
export function getProperty(propertyName: "settings.lotOccupancy.occupantProvinceDefault"): string; export function getProperty(propertyName: 'reverseProxy.urlPrefix'): string
export function getProperty(propertyName: "settings.lotOccupancy.prints"): string[];
export function getProperty(propertyName: "settings.fees.taxPercentageDefault"): number; export function getProperty(propertyName: 'session.cookieName'): string
export function getProperty(propertyName: 'session.doKeepAlive'): boolean
export function getProperty(propertyName: 'session.maxAgeMillis'): number
export function getProperty(propertyName: 'session.secret'): string
export function getProperty(propertyName: "settings.workOrders.workOrderNumberLength"): number; export function getProperty(propertyName: 'aliases.lot'): string
export function getProperty(propertyName: 'aliases.lots'): string
export function getProperty(propertyName: 'aliases.map'): string
export function getProperty(propertyName: 'aliases.maps'): string
export function getProperty(propertyName: 'aliases.occupancy'): string
export function getProperty(propertyName: 'aliases.occupancies'): string
export function getProperty(propertyName: 'aliases.occupancyStartDate'): string
export function getProperty(propertyName: 'aliases.occupant'): string
export function getProperty(propertyName: 'aliases.occupants'): string
export function getProperty(propertyName: 'aliases.workOrderOpenDate'): string
export function getProperty(propertyName: 'aliases.workOrderCloseDate'): string
export function getProperty( export function getProperty(
propertyName: "settings.workOrders.workOrderMilestoneDateRecentBeforeDays" propertyName: 'aliases.externalReceiptNumber'
): number; ): string
export function getProperty(propertyName: 'settings.map.mapCityDefault'): string
export function getProperty( export function getProperty(
propertyName: "settings.workOrders.workOrderMilestoneDateRecentAfterDays" propertyName: 'settings.map.mapProvinceDefault'
): number; ): string
export function getProperty(propertyName: "settings.workOrders.calendarEmailAddress"): string; export function getProperty(propertyName: 'settings.lot.lotNamePattern'): RegExp
export function getProperty(propertyName: "settings.workOrders.prints"): string[]; export function getProperty(
propertyName: 'settings.lot.lotNameHelpText'
export function getProperty(propertyName: "settings.adminCleanup.recordDeleteAgeDays"): number; ): string
export function getProperty( export function getProperty(
propertyName: "settings.printPdf.contentDisposition" propertyName: 'settings.lot.lotNameSortNameFunction'
): "attachment" | "inline"; ): (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
export function getProperty(
propertyName: 'settings.lotOccupancy.prints'
): string[]
export function getProperty(
propertyName: 'settings.fees.taxPercentageDefault'
): number
export function getProperty(
propertyName: 'settings.workOrders.workOrderNumberLength'
): number
export function getProperty(
propertyName: 'settings.workOrders.workOrderMilestoneDateRecentBeforeDays'
): number
export function getProperty(
propertyName: 'settings.workOrders.workOrderMilestoneDateRecentAfterDays'
): number
export function getProperty(
propertyName: 'settings.workOrders.calendarEmailAddress'
): string
export function getProperty(
propertyName: 'settings.workOrders.prints'
): string[]
export function getProperty(
propertyName: 'settings.adminCleanup.recordDeleteAgeDays'
): number
export function getProperty(
propertyName: 'settings.printPdf.contentDisposition'
): 'attachment' | 'inline'
export function getProperty(propertyName: string): unknown { export function getProperty(propertyName: string): unknown {
const propertyNameSplit = propertyName.split("."); const propertyNameSplit = propertyName.split('.')
let currentObject = config; let currentObject = config
for (const propertyNamePiece of propertyNameSplit) { for (const propertyNamePiece of propertyNameSplit) {
if (Object.prototype.hasOwnProperty.call(currentObject, propertyNamePiece)) { if (
currentObject = currentObject[propertyNamePiece]; Object.prototype.hasOwnProperty.call(currentObject, propertyNamePiece)
continue; ) {
currentObject = currentObject[propertyNamePiece]
continue
} }
return configFallbackValues.get(propertyName); return configFallbackValues.get(propertyName)
} }
return currentObject; return currentObject
} }
export const keepAliveMillis = getProperty("session.doKeepAlive") export const keepAliveMillis = getProperty('session.doKeepAlive')
? Math.max( ? Math.max(
getProperty("session.maxAgeMillis") / 2, getProperty('session.maxAgeMillis') / 2,
getProperty("session.maxAgeMillis") - 10 * 60 * 1000 getProperty('session.maxAgeMillis') - 10 * 60 * 1000
) )
: 0; : 0

View File

@ -1,3 +1,3 @@
import * as recordTypes from "../types/recordTypes"; import * as recordTypes from '../types/recordTypes';
export declare const calculateFeeAmount: (fee: recordTypes.Fee, lotOccupancy: recordTypes.LotOccupancy) => number; export declare const calculateFeeAmount: (fee: recordTypes.Fee, lotOccupancy: recordTypes.LotOccupancy) => number;
export declare function calculateTaxAmount(fee: recordTypes.Fee, feeAmount: number): number; export declare function calculateTaxAmount(fee: recordTypes.Fee, feeAmount: number): number;

View File

@ -1,6 +1,8 @@
export const calculateFeeAmount = (fee, lotOccupancy) => { export const calculateFeeAmount = (fee, lotOccupancy) => {
return fee.feeFunction ? 0 : fee.feeAmount || 0; return fee.feeFunction ? 0 : fee.feeAmount ?? 0;
}; };
export function calculateTaxAmount(fee, feeAmount) { export function calculateTaxAmount(fee, feeAmount) {
return fee.taxPercentage ? feeAmount * (fee.taxPercentage / 100) : fee.taxAmount || 0; return fee.taxPercentage
? feeAmount * (fee.taxPercentage / 100)
: fee.taxAmount ?? 0;
} }

View File

@ -1,12 +1,14 @@
import * as recordTypes from "../types/recordTypes"; import * as recordTypes from '../types/recordTypes'
export const calculateFeeAmount = ( export const calculateFeeAmount = (
fee: recordTypes.Fee, fee: recordTypes.Fee,
lotOccupancy: recordTypes.LotOccupancy lotOccupancy: recordTypes.LotOccupancy
): number => { ): number => {
return fee.feeFunction ? 0 : fee.feeAmount || 0; return fee.feeFunction ? 0 : fee.feeAmount ?? 0
}; }
export function calculateTaxAmount(fee: recordTypes.Fee, feeAmount: number) { export function calculateTaxAmount(fee: recordTypes.Fee, feeAmount: number): number {
return fee.taxPercentage ? feeAmount * (fee.taxPercentage / 100) : fee.taxAmount || 0; return fee.taxPercentage
? feeAmount * (fee.taxPercentage / 100)
: fee.taxAmount ?? 0
} }

View File

@ -1,4 +1,4 @@
import type * as recordTypes from "../types/recordTypes"; import type * as recordTypes from '../types/recordTypes';
export declare function filterOccupantsByLotOccupantType(lotOccupancy: recordTypes.LotOccupancy, lotOccupantType: string): recordTypes.LotOccupancyOccupant[]; export declare function filterOccupantsByLotOccupantType(lotOccupancy: recordTypes.LotOccupancy, lotOccupantType: string): recordTypes.LotOccupancyOccupant[];
export declare function getFieldValueByOccupancyTypeField(lotOccupancy: recordTypes.LotOccupancy, occupancyTypeField: string): string | undefined; export declare function getFieldValueByOccupancyTypeField(lotOccupancy: recordTypes.LotOccupancy, occupancyTypeField: string): string | undefined;
export declare function getFeesByFeeCategory(lotOccupancy: recordTypes.LotOccupancy, feeCategory: string, feeCategoryContains?: boolean): recordTypes.LotOccupancyFee[]; export declare function getFeesByFeeCategory(lotOccupancy: recordTypes.LotOccupancy, feeCategory: string, feeCategoryContains?: boolean): recordTypes.LotOccupancyFee[];

View File

@ -1,13 +1,14 @@
export function filterOccupantsByLotOccupantType(lotOccupancy, lotOccupantType) { export function filterOccupantsByLotOccupantType(lotOccupancy, lotOccupantType) {
const lotOccupantTypeLowerCase = lotOccupantType.toLowerCase(); const lotOccupantTypeLowerCase = lotOccupantType.toLowerCase();
const occupants = (lotOccupancy.lotOccupancyOccupants || []).filter((possibleOccupant) => { const occupants = (lotOccupancy.lotOccupancyOccupants ?? []).filter((possibleOccupant) => {
return (possibleOccupant.lotOccupantType.toLowerCase() === lotOccupantTypeLowerCase); return (possibleOccupant.lotOccupantType.toLowerCase() ===
lotOccupantTypeLowerCase);
}); });
return occupants; return occupants;
} }
export function getFieldValueByOccupancyTypeField(lotOccupancy, occupancyTypeField) { export function getFieldValueByOccupancyTypeField(lotOccupancy, occupancyTypeField) {
const occupancyTypeFieldLowerCase = occupancyTypeField.toLowerCase(); const occupancyTypeFieldLowerCase = occupancyTypeField.toLowerCase();
const field = (lotOccupancy.lotOccupancyFields || []).find((possibleField) => { const field = (lotOccupancy.lotOccupancyFields ?? []).find((possibleField) => {
return (possibleField.occupancyTypeField.toLowerCase() === return (possibleField.occupancyTypeField.toLowerCase() ===
occupancyTypeFieldLowerCase); occupancyTypeFieldLowerCase);
}); });
@ -18,16 +19,19 @@ export function getFieldValueByOccupancyTypeField(lotOccupancy, occupancyTypeFie
} }
export function getFeesByFeeCategory(lotOccupancy, feeCategory, feeCategoryContains = false) { export function getFeesByFeeCategory(lotOccupancy, feeCategory, feeCategoryContains = false) {
const feeCategoryLowerCase = feeCategory.toLowerCase(); const feeCategoryLowerCase = feeCategory.toLowerCase();
const fees = (lotOccupancy.lotOccupancyFees || []).filter((possibleFee) => { const fees = (lotOccupancy.lotOccupancyFees ?? []).filter((possibleFee) => {
return feeCategoryContains return feeCategoryContains
? possibleFee.feeCategory.toLowerCase().includes(feeCategoryLowerCase) ? possibleFee.feeCategory
: possibleFee.feeCategory.toLowerCase() === feeCategoryLowerCase; .toLowerCase()
.includes(feeCategoryLowerCase)
: possibleFee.feeCategory.toLowerCase() ===
feeCategoryLowerCase;
}); });
return fees; return fees;
} }
export function getTransactionTotal(lotOccupancy) { export function getTransactionTotal(lotOccupancy) {
let transactionTotal = 0; let transactionTotal = 0;
for (const transaction of lotOccupancy.lotOccupancyTransactions || []) { for (const transaction of lotOccupancy.lotOccupancyTransactions ?? []) {
transactionTotal += transaction.transactionAmount; transactionTotal += transaction.transactionAmount;
} }
return transactionTotal; return transactionTotal;

View File

@ -1,62 +1,72 @@
import type * as recordTypes from "../types/recordTypes"; import type * as recordTypes from '../types/recordTypes'
export function filterOccupantsByLotOccupantType( export function filterOccupantsByLotOccupantType(
lotOccupancy: recordTypes.LotOccupancy, lotOccupancy: recordTypes.LotOccupancy,
lotOccupantType: string lotOccupantType: string
): recordTypes.LotOccupancyOccupant[] { ): recordTypes.LotOccupancyOccupant[] {
const lotOccupantTypeLowerCase = lotOccupantType.toLowerCase(); const lotOccupantTypeLowerCase = lotOccupantType.toLowerCase()
const occupants = (lotOccupancy.lotOccupancyOccupants || []).filter((possibleOccupant) => { const occupants = (lotOccupancy.lotOccupancyOccupants ?? []).filter(
(possibleOccupant) => {
return ( return (
(possibleOccupant.lotOccupantType as string).toLowerCase() === lotOccupantTypeLowerCase (possibleOccupant.lotOccupantType as string).toLowerCase() ===
); lotOccupantTypeLowerCase
}); )
}
)
return occupants; return occupants
} }
export function getFieldValueByOccupancyTypeField( export function getFieldValueByOccupancyTypeField(
lotOccupancy: recordTypes.LotOccupancy, lotOccupancy: recordTypes.LotOccupancy,
occupancyTypeField: string occupancyTypeField: string
): string | undefined { ): string | undefined {
const occupancyTypeFieldLowerCase = occupancyTypeField.toLowerCase(); const occupancyTypeFieldLowerCase = occupancyTypeField.toLowerCase()
const field = (lotOccupancy.lotOccupancyFields || []).find((possibleField) => { const field = (lotOccupancy.lotOccupancyFields ?? []).find(
(possibleField) => {
return ( return (
(possibleField.occupancyTypeField as string).toLowerCase() === (possibleField.occupancyTypeField as string).toLowerCase() ===
occupancyTypeFieldLowerCase occupancyTypeFieldLowerCase
); )
}); }
)
if (field) { if (field) {
return field.lotOccupancyFieldValue; return field.lotOccupancyFieldValue
} }
return undefined; return undefined
} }
export function getFeesByFeeCategory( export function getFeesByFeeCategory(
lotOccupancy: recordTypes.LotOccupancy, lotOccupancy: recordTypes.LotOccupancy,
feeCategory: string, feeCategory: string,
feeCategoryContains = false feeCategoryContains = false
) { ): recordTypes.LotOccupancyFee[] {
const feeCategoryLowerCase = feeCategory.toLowerCase(); const feeCategoryLowerCase = feeCategory.toLowerCase()
const fees = (lotOccupancy.lotOccupancyFees || []).filter((possibleFee) => { const fees = (lotOccupancy.lotOccupancyFees ?? []).filter((possibleFee) => {
return feeCategoryContains return feeCategoryContains
? (possibleFee.feeCategory as string).toLowerCase().includes(feeCategoryLowerCase) ? (possibleFee.feeCategory as string)
: (possibleFee.feeCategory as string).toLowerCase() === feeCategoryLowerCase; .toLowerCase()
}); .includes(feeCategoryLowerCase)
: (possibleFee.feeCategory as string).toLowerCase() ===
feeCategoryLowerCase
})
return fees; return fees
} }
export function getTransactionTotal(lotOccupancy: recordTypes.LotOccupancy) { export function getTransactionTotal(
let transactionTotal = 0; lotOccupancy: recordTypes.LotOccupancy
): number {
let transactionTotal = 0
for (const transaction of lotOccupancy.lotOccupancyTransactions || []) { for (const transaction of lotOccupancy.lotOccupancyTransactions ?? []) {
transactionTotal += transaction.transactionAmount; transactionTotal += transaction.transactionAmount
} }
return transactionTotal; return transactionTotal
} }

View File

@ -1,11 +1,11 @@
import fs from "node:fs/promises"; import fs from 'node:fs/promises';
let mapSVGs; let mapSVGs;
export async function getMapSVGs() { export async function getMapSVGs() {
if (!mapSVGs) { if (!mapSVGs) {
const files = await fs.readdir("./public/images/maps/"); const files = await fs.readdir('./public/images/maps/');
const SVGs = []; const SVGs = [];
for (const file of files) { for (const file of files) {
if (file.toLowerCase().endsWith(".svg")) { if (file.toLowerCase().endsWith('.svg')) {
SVGs.push(file); SVGs.push(file);
} }
} }

View File

@ -1,21 +1,21 @@
import fs from "node:fs/promises"; import fs from 'node:fs/promises'
let mapSVGs: string[]; let mapSVGs: string[]
export async function getMapSVGs(): Promise<string[]> { export async function getMapSVGs(): Promise<string[]> {
if (!mapSVGs) { if (!mapSVGs) {
const files = await fs.readdir("./public/images/maps/"); const files = await fs.readdir('./public/images/maps/')
const SVGs: string[] = []; const SVGs: string[] = []
for (const file of files) { for (const file of files) {
if (file.toLowerCase().endsWith(".svg")) { if (file.toLowerCase().endsWith('.svg')) {
SVGs.push(file); SVGs.push(file)
} }
} }
mapSVGs = SVGs; mapSVGs = SVGs
} }
return mapSVGs; return mapSVGs
} }

View File

@ -4,10 +4,6 @@ interface PrintConfig {
} }
export declare function getScreenPrintConfig(printName: string): PrintConfig; export declare function getScreenPrintConfig(printName: string): PrintConfig;
export declare function getPdfPrintConfig(printName: string): PrintConfig; export declare function getPdfPrintConfig(printName: string): PrintConfig;
export declare function getPrintConfig(screenOrPdf_printName: string): PrintConfig | undefined; export declare function getPrintConfig(screenOrPdfPrintName: string): PrintConfig | undefined;
export declare function getReportData(printConfig: PrintConfig, requestQuery: { export declare function getReportData(printConfig: PrintConfig, requestQuery: Record<string, unknown>): Record<string, unknown>;
[paramName: string]: unknown;
}): {
[dataName: string]: unknown;
};
export {}; export {};

View File

@ -1,14 +1,14 @@
import * as configFunctions from "./functions.config.js"; import * as configFunctions from './functions.config.js';
import { getLot } from "./lotOccupancyDB/getLot.js"; import { getLot } from './lotOccupancyDB/getLot.js';
import { getLotOccupancy } from "./lotOccupancyDB/getLotOccupancy.js"; import { getLotOccupancy } from './lotOccupancyDB/getLotOccupancy.js';
import { getWorkOrder } from "./lotOccupancyDB/getWorkOrder.js"; import { getWorkOrder } from './lotOccupancyDB/getWorkOrder.js';
const screenPrintConfigs = { const screenPrintConfigs = {
lotOccupancy: { lotOccupancy: {
title: configFunctions.getProperty("aliases.lot") + title: configFunctions.getProperty('aliases.lot') +
" " + ' ' +
configFunctions.getProperty("aliases.occupancy") + configFunctions.getProperty('aliases.occupancy') +
" Print", ' Print',
params: ["lotOccupancyId"] params: ['lotOccupancyId']
} }
}; };
export function getScreenPrintConfig(printName) { export function getScreenPrintConfig(printName) {
@ -16,32 +16,32 @@ export function getScreenPrintConfig(printName) {
} }
const pdfPrintConfigs = { const pdfPrintConfigs = {
workOrder: { workOrder: {
title: "Work Order Field Sheet", title: 'Work Order Field Sheet',
params: ["workOrderId"] params: ['workOrderId']
}, },
"workOrder-commentLog": { 'workOrder-commentLog': {
title: "Work Order Field Sheet - Comment Log", title: 'Work Order Field Sheet - Comment Log',
params: ["workOrderId"] params: ['workOrderId']
}, },
"ssm.cemetery.burialPermit": { 'ssm.cemetery.burialPermit': {
title: "Burial Permit", title: 'Burial Permit',
params: ["lotOccupancyId"] params: ['lotOccupancyId']
}, },
"ssm.cemetery.contract": { 'ssm.cemetery.contract': {
title: "Contract for Purchase of Interment Rights", title: 'Contract for Purchase of Interment Rights',
params: ["lotOccupancyId"] params: ['lotOccupancyId']
} }
}; };
export function getPdfPrintConfig(printName) { export function getPdfPrintConfig(printName) {
return pdfPrintConfigs[printName]; return pdfPrintConfigs[printName];
} }
export function getPrintConfig(screenOrPdf_printName) { export function getPrintConfig(screenOrPdfPrintName) {
const printNameSplit = screenOrPdf_printName.split("/"); const printNameSplit = screenOrPdfPrintName.split('/');
switch (printNameSplit[0]) { switch (printNameSplit[0]) {
case "screen": { case 'screen': {
return getScreenPrintConfig(printNameSplit[1]); return getScreenPrintConfig(printNameSplit[1]);
} }
case "pdf": { case 'pdf': {
return getPdfPrintConfig(printNameSplit[1]); return getPdfPrintConfig(printNameSplit[1]);
} }
} }
@ -51,16 +51,16 @@ export function getReportData(printConfig, requestQuery) {
const reportData = { const reportData = {
headTitle: printConfig.title headTitle: printConfig.title
}; };
if (printConfig.params.includes("lotOccupancyId") && if (printConfig.params.includes('lotOccupancyId') &&
typeof requestQuery.lotOccupancyId === "string") { typeof requestQuery.lotOccupancyId === 'string') {
const lotOccupancy = getLotOccupancy(requestQuery.lotOccupancyId); const lotOccupancy = getLotOccupancy(requestQuery.lotOccupancyId);
if (lotOccupancy && lotOccupancy.lotId) { if (lotOccupancy?.lotId) {
reportData.lot = getLot(lotOccupancy.lotId); reportData.lot = getLot(lotOccupancy.lotId);
} }
reportData.lotOccupancy = lotOccupancy; reportData.lotOccupancy = lotOccupancy;
} }
if (printConfig.params.includes("workOrderId") && if (printConfig.params.includes('workOrderId') &&
typeof requestQuery.workOrderId === "string") { typeof requestQuery.workOrderId === 'string') {
reportData.workOrder = getWorkOrder(requestQuery.workOrderId, { reportData.workOrder = getWorkOrder(requestQuery.workOrderId, {
includeLotsAndLotOccupancies: true, includeLotsAndLotOccupancies: true,
includeComments: true, includeComments: true,

View File

@ -1,100 +1,102 @@
import * as configFunctions from "./functions.config.js"; import * as configFunctions from './functions.config.js'
import { getLot } from "./lotOccupancyDB/getLot.js"; import { getLot } from './lotOccupancyDB/getLot.js'
import { getLotOccupancy } from "./lotOccupancyDB/getLotOccupancy.js"; import { getLotOccupancy } from './lotOccupancyDB/getLotOccupancy.js'
import { getWorkOrder } from "./lotOccupancyDB/getWorkOrder.js"; import { getWorkOrder } from './lotOccupancyDB/getWorkOrder.js'
interface PrintConfig { interface PrintConfig {
title: string; title: string
params: string[]; params: string[]
} }
const screenPrintConfigs: { [printName: string]: PrintConfig } = { const screenPrintConfigs: Record<string, PrintConfig> = {
lotOccupancy: { lotOccupancy: {
title: title:
configFunctions.getProperty("aliases.lot") + configFunctions.getProperty('aliases.lot') +
" " + ' ' +
configFunctions.getProperty("aliases.occupancy") + configFunctions.getProperty('aliases.occupancy') +
" Print", ' Print',
params: ["lotOccupancyId"] params: ['lotOccupancyId']
} }
};
export function getScreenPrintConfig(printName: string): PrintConfig {
return screenPrintConfigs[printName];
} }
const pdfPrintConfigs: { [printName: string]: PrintConfig } = { export function getScreenPrintConfig(printName: string): PrintConfig {
return screenPrintConfigs[printName]
}
const pdfPrintConfigs: Record<string, PrintConfig> = {
workOrder: { workOrder: {
title: "Work Order Field Sheet", title: 'Work Order Field Sheet',
params: ["workOrderId"] params: ['workOrderId']
}, },
"workOrder-commentLog": { 'workOrder-commentLog': {
title: "Work Order Field Sheet - Comment Log", title: 'Work Order Field Sheet - Comment Log',
params: ["workOrderId"] params: ['workOrderId']
}, },
// Occupancy // Occupancy
"ssm.cemetery.burialPermit": { 'ssm.cemetery.burialPermit': {
title: "Burial Permit", title: 'Burial Permit',
params: ["lotOccupancyId"] params: ['lotOccupancyId']
}, },
"ssm.cemetery.contract": { 'ssm.cemetery.contract': {
title: "Contract for Purchase of Interment Rights", title: 'Contract for Purchase of Interment Rights',
params: ["lotOccupancyId"] params: ['lotOccupancyId']
} }
};
export function getPdfPrintConfig(printName: string): PrintConfig {
return pdfPrintConfigs[printName];
} }
export function getPrintConfig(screenOrPdf_printName: string): PrintConfig | undefined { export function getPdfPrintConfig(printName: string): PrintConfig {
const printNameSplit = screenOrPdf_printName.split("/"); return pdfPrintConfigs[printName]
}
export function getPrintConfig(
screenOrPdfPrintName: string
): PrintConfig | undefined {
const printNameSplit = screenOrPdfPrintName.split('/')
switch (printNameSplit[0]) { switch (printNameSplit[0]) {
case "screen": { case 'screen': {
return getScreenPrintConfig(printNameSplit[1]); return getScreenPrintConfig(printNameSplit[1])
} }
case "pdf": { case 'pdf': {
return getPdfPrintConfig(printNameSplit[1]); return getPdfPrintConfig(printNameSplit[1])
} }
} }
return undefined; return undefined
} }
export function getReportData( export function getReportData(
printConfig: PrintConfig, printConfig: PrintConfig,
requestQuery: { [paramName: string]: unknown } requestQuery: Record<string, unknown>
) { ): Record<string, unknown> {
const reportData: { [dataName: string]: unknown } = { const reportData: Record<string, unknown> = {
headTitle: printConfig.title headTitle: printConfig.title
}; }
if ( if (
printConfig.params.includes("lotOccupancyId") && printConfig.params.includes('lotOccupancyId') &&
typeof requestQuery.lotOccupancyId === "string" typeof requestQuery.lotOccupancyId === 'string'
) { ) {
const lotOccupancy = getLotOccupancy(requestQuery.lotOccupancyId); const lotOccupancy = getLotOccupancy(requestQuery.lotOccupancyId)
if (lotOccupancy && lotOccupancy.lotId) { if (lotOccupancy?.lotId) {
reportData.lot = getLot(lotOccupancy.lotId); reportData.lot = getLot(lotOccupancy.lotId)
} }
reportData.lotOccupancy = lotOccupancy; reportData.lotOccupancy = lotOccupancy
} }
if ( if (
printConfig.params.includes("workOrderId") && printConfig.params.includes('workOrderId') &&
typeof requestQuery.workOrderId === "string" typeof requestQuery.workOrderId === 'string'
) { ) {
reportData.workOrder = getWorkOrder(requestQuery.workOrderId, { reportData.workOrder = getWorkOrder(requestQuery.workOrderId, {
includeLotsAndLotOccupancies: true, includeLotsAndLotOccupancies: true,
includeComments: true, includeComments: true,
includeMilestones: true includeMilestones: true
}); })
} }
return reportData; return reportData
} }

View File

@ -1,4 +1,4 @@
import type { User } from "../types/recordTypes"; import type { User } from '../types/recordTypes';
export interface UserRequest { export interface UserRequest {
session?: { session?: {
user?: User; user?: User;

View File

@ -1,15 +1,15 @@
import { getUserNameFromApiKey } from "./functions.api.js"; import { getUserNameFromApiKey } from './functions.api.js';
import * as configFunctions from "./functions.config.js"; import * as configFunctions from './functions.config.js';
export function userIsAdmin(request) { export function userIsAdmin(request) {
const user = request.session?.user; const user = request.session?.user;
if (!user || !user.userProperties) { if (!user?.userProperties) {
return false; return false;
} }
return user.userProperties.isAdmin; return user.userProperties.isAdmin;
} }
export function userCanUpdate(request) { export function userCanUpdate(request) {
const user = request.session?.user; const user = request.session?.user;
if (!user || !user.userProperties) { if (!user?.userProperties) {
return false; return false;
} }
return user.userProperties.canUpdate; return user.userProperties.canUpdate;
@ -23,7 +23,9 @@ export async function apiKeyIsValid(request) {
if (!userName) { if (!userName) {
return false; return false;
} }
const canLogin = configFunctions.getProperty("users.canLogin").some((currentUserName) => { const canLogin = configFunctions
.getProperty('users.canLogin')
.some((currentUserName) => {
return userName === currentUserName.toLowerCase(); return userName === currentUserName.toLowerCase();
}); });
return canLogin; return canLogin;

View File

@ -1,56 +1,58 @@
import { getUserNameFromApiKey } from "./functions.api.js"; import { getUserNameFromApiKey } from './functions.api.js'
import * as configFunctions from "./functions.config.js"; import * as configFunctions from './functions.config.js'
import type { User } from "../types/recordTypes"; import type { User } from '../types/recordTypes'
export interface UserRequest { export interface UserRequest {
session?: { session?: {
user?: User; user?: User
}; }
} }
export interface APIRequest { export interface APIRequest {
params?: { params?: {
apiKey?: string; apiKey?: string
}; }
} }
export function userIsAdmin(request: UserRequest): boolean { export function userIsAdmin(request: UserRequest): boolean {
const user = request.session?.user; const user = request.session?.user
if (!user || !user.userProperties) { if (!user?.userProperties) {
return false; return false
} }
return user.userProperties.isAdmin; return user.userProperties.isAdmin
} }
export function userCanUpdate(request: UserRequest): boolean { export function userCanUpdate(request: UserRequest): boolean {
const user = request.session?.user; const user = request.session?.user
if (!user || !user.userProperties) { if (!user?.userProperties) {
return false; return false
} }
return user.userProperties.canUpdate; return user.userProperties.canUpdate
} }
export async function apiKeyIsValid(request: APIRequest): Promise<boolean> { export async function apiKeyIsValid(request: APIRequest): Promise<boolean> {
const apiKey = request.params?.apiKey; const apiKey = request.params?.apiKey
if (!apiKey) { if (!apiKey) {
return false; return false
} }
const userName = await getUserNameFromApiKey(apiKey); const userName = await getUserNameFromApiKey(apiKey)
if (!userName) { if (!userName) {
return false; return false
} }
const canLogin = configFunctions.getProperty("users.canLogin").some((currentUserName) => { const canLogin = configFunctions
return userName === currentUserName.toLowerCase(); .getProperty('users.canLogin')
}); .some((currentUserName) => {
return userName === currentUserName.toLowerCase()
})
return canLogin; return canLogin
} }

View File

@ -1,75 +1,77 @@
import { lotOccupancyDB as databasePath } from "../data/databasePaths.js"; import { lotOccupancyDB as databasePath } from '../data/databasePaths.js';
import { initializeDatabase } from "./initializer.database.js"; import { initializeDatabase } from './initializer.database.js';
import { addOccupancyTypeField } from "./lotOccupancyDB/addOccupancyTypeField.js"; import { addOccupancyTypeField } from './lotOccupancyDB/addOccupancyTypeField.js';
import { addLotOccupantType } from "./lotOccupancyDB/addLotOccupantType.js"; import { addLotOccupantType } from './lotOccupancyDB/addLotOccupantType.js';
import Debug from "debug"; import Debug from 'debug';
import { addRecord } from "./lotOccupancyDB/addRecord.js"; import { addRecord } from './lotOccupancyDB/addRecord.js';
const debug = Debug("lot-occupancy-system:initialize"); const debug = Debug('lot-occupancy-system:initialize');
const session = { const session = {
user: { user: {
userName: "init.cemetery", userName: 'init.cemetery',
userProperties: { userProperties: {
canUpdate: true, canUpdate: true,
isAdmin: true, isAdmin: true,
apiKey: "" apiKey: ''
} }
} }
}; };
function initializeCemeteryDatabase() { function initializeCemeteryDatabase() {
debug("Checking for " + databasePath + "..."); debug('Checking for ' + databasePath + '...');
const databaseInitialized = initializeDatabase(); const databaseInitialized = initializeDatabase();
if (!databaseInitialized) { if (!databaseInitialized) {
debug("Database already created.\n" + debug('Database already created.\n' +
"To initialize this database with cemetery types, delete the database file first, then rerun this script."); 'To initialize this database with cemetery types, delete the database file first, then rerun this script.');
return; return;
} }
debug("New database file created. Proceeding with initialization."); debug('New database file created. Proceeding with initialization.');
addRecord("LotTypes", "Casket Grave", 1, session); addRecord('LotTypes', 'Casket Grave', 1, session);
addRecord("LotTypes", "Columbarium", 2, session); addRecord('LotTypes', 'Columbarium', 2, session);
addRecord("LotTypes", "Mausoleum", 2, session); addRecord('LotTypes', 'Mausoleum', 2, session);
addRecord("LotTypes", "Niche Wall", 2, session); addRecord('LotTypes', 'Niche Wall', 2, session);
addRecord("LotTypes", "Urn Garden", 2, session); addRecord('LotTypes', 'Urn Garden', 2, session);
addRecord("LotTypes", "Crematorium", 2, session); addRecord('LotTypes', 'Crematorium', 2, session);
addRecord("LotStatuses", "Available", 1, session); addRecord('LotStatuses', 'Available', 1, session);
addRecord("LotStatuses", "Reserved", 2, session); addRecord('LotStatuses', 'Reserved', 2, session);
addRecord("LotStatuses", "Taken", 3, session); addRecord('LotStatuses', 'Taken', 3, session);
addLotOccupantType({ addLotOccupantType({
lotOccupantType: "Deceased", lotOccupantType: 'Deceased',
orderNumber: 1 orderNumber: 1
}, session); }, session);
addLotOccupantType({ addLotOccupantType({
lotOccupantType: "Funeral Director", lotOccupantType: 'Funeral Director',
orderNumber: 2 orderNumber: 2
}, session); }, session);
addLotOccupantType({ addLotOccupantType({
lotOccupantType: "Preneed Owner", lotOccupantType: 'Preneed Owner',
orderNumber: 3 orderNumber: 3
}, session); }, session);
addLotOccupantType({ addLotOccupantType({
lotOccupantType: "Purchaser", lotOccupantType: 'Purchaser',
orderNumber: 4 orderNumber: 4
}, session); }, session);
addRecord("OccupancyTypes", "Preneed", 1, session); addRecord('OccupancyTypes', 'Preneed', 1, session);
const intermentOccupancyTypeId = addRecord("OccupancyTypes", "Interment", 2, session); const intermentOccupancyTypeId = addRecord('OccupancyTypes', 'Interment', 2, session);
const cremationOccupancyTypeId = addRecord("OccupancyTypes", "Cremation", 3, session); const cremationOccupancyTypeId = addRecord('OccupancyTypes', 'Cremation', 3, session);
const deathDateField = { const deathDateField = {
occupancyTypeId: intermentOccupancyTypeId, occupancyTypeId: intermentOccupancyTypeId,
occupancyTypeField: "Death Date", occupancyTypeField: 'Death Date',
occupancyTypeFieldValues: "", occupancyTypeFieldValues: '',
pattern: "\\d{4}([\\/-]\\d{2}){2}", pattern: '\\d{4}([\\/-]\\d{2}){2}',
isRequired: "", isRequired: '',
minimumLength: 10, minimumLength: 10,
maximumLength: 10, maximumLength: 10,
orderNumber: 1 orderNumber: 1
}; };
addOccupancyTypeField(deathDateField, session); addOccupancyTypeField(deathDateField, session);
addOccupancyTypeField(Object.assign(deathDateField, { occupancyTypeId: cremationOccupancyTypeId }), session); addOccupancyTypeField(Object.assign(deathDateField, {
occupancyTypeId: cremationOccupancyTypeId
}), session);
const deathAgeField = { const deathAgeField = {
occupancyTypeId: intermentOccupancyTypeId, occupancyTypeId: intermentOccupancyTypeId,
occupancyTypeField: "Death Age", occupancyTypeField: 'Death Age',
occupancyTypeFieldValues: "", occupancyTypeFieldValues: '',
pattern: "\\d+", pattern: '\\d+',
isRequired: "", isRequired: '',
minimumLength: 1, minimumLength: 1,
maximumLength: 3, maximumLength: 3,
orderNumber: 2 orderNumber: 2
@ -78,22 +80,24 @@ function initializeCemeteryDatabase() {
addOccupancyTypeField(Object.assign(deathAgeField, { occupancyTypeId: cremationOccupancyTypeId }), session); addOccupancyTypeField(Object.assign(deathAgeField, { occupancyTypeId: cremationOccupancyTypeId }), session);
const deathAgePeriod = { const deathAgePeriod = {
occupancyTypeId: intermentOccupancyTypeId, occupancyTypeId: intermentOccupancyTypeId,
occupancyTypeField: "Death Age Period", occupancyTypeField: 'Death Age Period',
occupancyTypeFieldValues: "Years\nMonths\nDays\nStillborn", occupancyTypeFieldValues: 'Years\nMonths\nDays\nStillborn',
pattern: "", pattern: '',
isRequired: "", isRequired: '',
minimumLength: 1, minimumLength: 1,
maximumLength: 10, maximumLength: 10,
orderNumber: 3 orderNumber: 3
}; };
addOccupancyTypeField(deathAgePeriod, session); addOccupancyTypeField(deathAgePeriod, session);
addOccupancyTypeField(Object.assign(deathAgePeriod, { occupancyTypeId: cremationOccupancyTypeId }), session); addOccupancyTypeField(Object.assign(deathAgePeriod, {
occupancyTypeId: cremationOccupancyTypeId
}), session);
const deathPlace = { const deathPlace = {
occupancyTypeId: intermentOccupancyTypeId, occupancyTypeId: intermentOccupancyTypeId,
occupancyTypeField: "Death Place", occupancyTypeField: 'Death Place',
occupancyTypeFieldValues: "", occupancyTypeFieldValues: '',
pattern: "", pattern: '',
isRequired: "", isRequired: '',
minimumLength: 1, minimumLength: 1,
maximumLength: 100, maximumLength: 100,
orderNumber: 4 orderNumber: 4
@ -102,10 +106,10 @@ function initializeCemeteryDatabase() {
addOccupancyTypeField(Object.assign(deathPlace, { occupancyTypeId: cremationOccupancyTypeId }), session); addOccupancyTypeField(Object.assign(deathPlace, { occupancyTypeId: cremationOccupancyTypeId }), session);
const funeralHome = { const funeralHome = {
occupancyTypeId: intermentOccupancyTypeId, occupancyTypeId: intermentOccupancyTypeId,
occupancyTypeField: "Funeral Home", occupancyTypeField: 'Funeral Home',
occupancyTypeFieldValues: "", occupancyTypeFieldValues: '',
pattern: "", pattern: '',
isRequired: "", isRequired: '',
minimumLength: 1, minimumLength: 1,
maximumLength: 100, maximumLength: 100,
orderNumber: 10 orderNumber: 10
@ -114,10 +118,10 @@ function initializeCemeteryDatabase() {
addOccupancyTypeField(Object.assign(funeralHome, { occupancyTypeId: cremationOccupancyTypeId }), session); addOccupancyTypeField(Object.assign(funeralHome, { occupancyTypeId: cremationOccupancyTypeId }), session);
const funeralDate = { const funeralDate = {
occupancyTypeId: intermentOccupancyTypeId, occupancyTypeId: intermentOccupancyTypeId,
occupancyTypeField: "Funeral Date", occupancyTypeField: 'Funeral Date',
occupancyTypeFieldValues: "", occupancyTypeFieldValues: '',
pattern: "\\d{4}([\\/-]\\d{2}){2}", pattern: '\\d{4}([\\/-]\\d{2}){2}',
isRequired: "", isRequired: '',
minimumLength: 10, minimumLength: 10,
maximumLength: 10, maximumLength: 10,
orderNumber: 11 orderNumber: 11
@ -126,10 +130,10 @@ function initializeCemeteryDatabase() {
addOccupancyTypeField(Object.assign(funeralDate, { occupancyTypeId: cremationOccupancyTypeId }), session); addOccupancyTypeField(Object.assign(funeralDate, { occupancyTypeId: cremationOccupancyTypeId }), session);
const containerType = { const containerType = {
occupancyTypeId: intermentOccupancyTypeId, occupancyTypeId: intermentOccupancyTypeId,
occupancyTypeField: "Container Type", occupancyTypeField: 'Container Type',
occupancyTypeFieldValues: "", occupancyTypeFieldValues: '',
pattern: "", pattern: '',
isRequired: "", isRequired: '',
minimumLength: 1, minimumLength: 1,
maximumLength: 100, maximumLength: 100,
orderNumber: 20 orderNumber: 20
@ -138,20 +142,20 @@ function initializeCemeteryDatabase() {
addOccupancyTypeField(Object.assign(containerType, { occupancyTypeId: cremationOccupancyTypeId }), session); addOccupancyTypeField(Object.assign(containerType, { occupancyTypeId: cremationOccupancyTypeId }), session);
const committalType = { const committalType = {
occupancyTypeId: intermentOccupancyTypeId, occupancyTypeId: intermentOccupancyTypeId,
occupancyTypeField: "Committal Type", occupancyTypeField: 'Committal Type',
occupancyTypeFieldValues: "", occupancyTypeFieldValues: '',
pattern: "", pattern: '',
isRequired: "", isRequired: '',
minimumLength: 1, minimumLength: 1,
maximumLength: 100, maximumLength: 100,
orderNumber: 21 orderNumber: 21
}; };
addOccupancyTypeField(committalType, session); addOccupancyTypeField(committalType, session);
addOccupancyTypeField(Object.assign(committalType, { occupancyTypeId: cremationOccupancyTypeId }), session); addOccupancyTypeField(Object.assign(committalType, { occupancyTypeId: cremationOccupancyTypeId }), session);
addRecord("FeeCategories", "Interment Rights", 1, session); addRecord('FeeCategories', 'Interment Rights', 1, session);
addRecord("FeeCategories", "Cremation Services", 2, session); addRecord('FeeCategories', 'Cremation Services', 2, session);
addRecord("FeeCategories", "Burial Charges", 3, session); addRecord('FeeCategories', 'Burial Charges', 3, session);
addRecord("FeeCategories", "Disinterment of Human Remains", 4, session); addRecord('FeeCategories', 'Disinterment of Human Remains', 4, session);
addRecord("FeeCategories", "Additional Services", 4, session); addRecord('FeeCategories', 'Additional Services', 4, session);
} }
initializeCemeteryDatabase(); initializeCemeteryDatabase();

View File

@ -1,64 +1,64 @@
import { lotOccupancyDB as databasePath } from "../data/databasePaths.js"; import { lotOccupancyDB as databasePath } from '../data/databasePaths.js'
import { initializeDatabase } from "./initializer.database.js"; import { initializeDatabase } from './initializer.database.js'
import { addOccupancyTypeField } from "./lotOccupancyDB/addOccupancyTypeField.js"; import { addOccupancyTypeField } from './lotOccupancyDB/addOccupancyTypeField.js'
import { addLotOccupantType } from "./lotOccupancyDB/addLotOccupantType.js"; import { addLotOccupantType } from './lotOccupancyDB/addLotOccupantType.js'
import type { PartialSession } from "../types/recordTypes.js"; import type { PartialSession } from '../types/recordTypes.js'
import Debug from "debug"; import Debug from 'debug'
import { addRecord } from "./lotOccupancyDB/addRecord.js"; import { addRecord } from './lotOccupancyDB/addRecord.js'
const debug = Debug("lot-occupancy-system:initialize"); const debug = Debug('lot-occupancy-system:initialize')
const session: PartialSession = { const session: PartialSession = {
user: { user: {
userName: "init.cemetery", userName: 'init.cemetery',
userProperties: { userProperties: {
canUpdate: true, canUpdate: true,
isAdmin: true, isAdmin: true,
apiKey: "" apiKey: ''
} }
} }
}; }
function initializeCemeteryDatabase() { function initializeCemeteryDatabase(): void {
/* /*
* Ensure database does not already exist * Ensure database does not already exist
*/ */
debug("Checking for " + databasePath + "..."); debug('Checking for ' + databasePath + '...')
const databaseInitialized = initializeDatabase(); const databaseInitialized = initializeDatabase()
if (!databaseInitialized) { if (!databaseInitialized) {
debug( debug(
"Database already created.\n" + 'Database already created.\n' +
"To initialize this database with cemetery types, delete the database file first, then rerun this script." 'To initialize this database with cemetery types, delete the database file first, then rerun this script.'
); )
return; return
} }
debug("New database file created. Proceeding with initialization."); debug('New database file created. Proceeding with initialization.')
/* /*
* Lot Types * Lot Types
*/ */
addRecord("LotTypes", "Casket Grave", 1, session); addRecord('LotTypes', 'Casket Grave', 1, session)
addRecord("LotTypes", "Columbarium", 2, session); addRecord('LotTypes', 'Columbarium', 2, session)
addRecord("LotTypes", "Mausoleum", 2, session); addRecord('LotTypes', 'Mausoleum', 2, session)
addRecord("LotTypes", "Niche Wall", 2, session); addRecord('LotTypes', 'Niche Wall', 2, session)
addRecord("LotTypes", "Urn Garden", 2, session); addRecord('LotTypes', 'Urn Garden', 2, session)
addRecord("LotTypes", "Crematorium", 2, session); addRecord('LotTypes', 'Crematorium', 2, session)
/* /*
* Lot Statuses * Lot Statuses
*/ */
addRecord("LotStatuses", "Available", 1, session); addRecord('LotStatuses', 'Available', 1, session)
addRecord("LotStatuses", "Reserved", 2, session); addRecord('LotStatuses', 'Reserved', 2, session)
addRecord("LotStatuses", "Taken", 3, session); addRecord('LotStatuses', 'Taken', 3, session)
/* /*
* Lot Occupant Types * Lot Occupant Types
@ -66,196 +66,219 @@ function initializeCemeteryDatabase() {
addLotOccupantType( addLotOccupantType(
{ {
lotOccupantType: "Deceased", lotOccupantType: 'Deceased',
orderNumber: 1 orderNumber: 1
}, },
session session
); )
addLotOccupantType( addLotOccupantType(
{ {
lotOccupantType: "Funeral Director", lotOccupantType: 'Funeral Director',
orderNumber: 2 orderNumber: 2
}, },
session session
); )
addLotOccupantType( addLotOccupantType(
{ {
lotOccupantType: "Preneed Owner", lotOccupantType: 'Preneed Owner',
orderNumber: 3 orderNumber: 3
}, },
session session
); )
addLotOccupantType( addLotOccupantType(
{ {
lotOccupantType: "Purchaser", lotOccupantType: 'Purchaser',
orderNumber: 4 orderNumber: 4
}, },
session session
); )
/* /*
* Occupancy Types * Occupancy Types
*/ */
addRecord("OccupancyTypes", "Preneed", 1, session); addRecord('OccupancyTypes', 'Preneed', 1, session)
const intermentOccupancyTypeId = addRecord("OccupancyTypes", "Interment", 2, session); const intermentOccupancyTypeId = addRecord(
const cremationOccupancyTypeId = addRecord("OccupancyTypes", "Cremation", 3, session); 'OccupancyTypes',
'Interment',
2,
session
)
const cremationOccupancyTypeId = addRecord(
'OccupancyTypes',
'Cremation',
3,
session
)
// Death Date // Death Date
const deathDateField = { const deathDateField = {
occupancyTypeId: intermentOccupancyTypeId, occupancyTypeId: intermentOccupancyTypeId,
occupancyTypeField: "Death Date", occupancyTypeField: 'Death Date',
occupancyTypeFieldValues: "", occupancyTypeFieldValues: '',
pattern: "\\d{4}([\\/-]\\d{2}){2}", pattern: '\\d{4}([\\/-]\\d{2}){2}',
isRequired: "", isRequired: '',
minimumLength: 10, minimumLength: 10,
maximumLength: 10, maximumLength: 10,
orderNumber: 1 orderNumber: 1
}; }
addOccupancyTypeField(deathDateField, session); addOccupancyTypeField(deathDateField, session)
addOccupancyTypeField( addOccupancyTypeField(
Object.assign(deathDateField, { occupancyTypeId: cremationOccupancyTypeId }), Object.assign(deathDateField, {
occupancyTypeId: cremationOccupancyTypeId
}),
session session
); )
// Death Age // Death Age
const deathAgeField = { const deathAgeField = {
occupancyTypeId: intermentOccupancyTypeId, occupancyTypeId: intermentOccupancyTypeId,
occupancyTypeField: "Death Age", occupancyTypeField: 'Death Age',
occupancyTypeFieldValues: "", occupancyTypeFieldValues: '',
pattern: "\\d+", pattern: '\\d+',
isRequired: "", isRequired: '',
minimumLength: 1, minimumLength: 1,
maximumLength: 3, maximumLength: 3,
orderNumber: 2 orderNumber: 2
}; }
addOccupancyTypeField(deathAgeField, session); addOccupancyTypeField(deathAgeField, session)
addOccupancyTypeField( addOccupancyTypeField(
Object.assign(deathAgeField, { occupancyTypeId: cremationOccupancyTypeId }), Object.assign(deathAgeField, { occupancyTypeId: cremationOccupancyTypeId }),
session session
); )
// Death Age Period // Death Age Period
const deathAgePeriod = { const deathAgePeriod = {
occupancyTypeId: intermentOccupancyTypeId, occupancyTypeId: intermentOccupancyTypeId,
occupancyTypeField: "Death Age Period", occupancyTypeField: 'Death Age Period',
occupancyTypeFieldValues: "Years\nMonths\nDays\nStillborn", occupancyTypeFieldValues: 'Years\nMonths\nDays\nStillborn',
pattern: "", pattern: '',
isRequired: "", isRequired: '',
minimumLength: 1, minimumLength: 1,
maximumLength: 10, maximumLength: 10,
orderNumber: 3 orderNumber: 3
}; }
addOccupancyTypeField(deathAgePeriod, session); addOccupancyTypeField(deathAgePeriod, session)
addOccupancyTypeField( addOccupancyTypeField(
Object.assign(deathAgePeriod, { occupancyTypeId: cremationOccupancyTypeId }), Object.assign(deathAgePeriod, {
occupancyTypeId: cremationOccupancyTypeId
}),
session session
); )
// Death Place // Death Place
const deathPlace = { const deathPlace = {
occupancyTypeId: intermentOccupancyTypeId, occupancyTypeId: intermentOccupancyTypeId,
occupancyTypeField: "Death Place", occupancyTypeField: 'Death Place',
occupancyTypeFieldValues: "", occupancyTypeFieldValues: '',
pattern: "", pattern: '',
isRequired: "", isRequired: '',
minimumLength: 1, minimumLength: 1,
maximumLength: 100, maximumLength: 100,
orderNumber: 4 orderNumber: 4
}; }
addOccupancyTypeField(deathPlace, session); addOccupancyTypeField(deathPlace, session)
addOccupancyTypeField(Object.assign(deathPlace, { occupancyTypeId: cremationOccupancyTypeId }), session); addOccupancyTypeField(
Object.assign(deathPlace, { occupancyTypeId: cremationOccupancyTypeId }),
session
)
// Funeral Home // Funeral Home
const funeralHome = { const funeralHome = {
occupancyTypeId: intermentOccupancyTypeId, occupancyTypeId: intermentOccupancyTypeId,
occupancyTypeField: "Funeral Home", occupancyTypeField: 'Funeral Home',
occupancyTypeFieldValues: "", occupancyTypeFieldValues: '',
pattern: "", pattern: '',
isRequired: "", isRequired: '',
minimumLength: 1, minimumLength: 1,
maximumLength: 100, maximumLength: 100,
orderNumber: 10 orderNumber: 10
}; }
addOccupancyTypeField(funeralHome, session); addOccupancyTypeField(funeralHome, session)
addOccupancyTypeField(Object.assign(funeralHome, { occupancyTypeId: cremationOccupancyTypeId }), session); addOccupancyTypeField(
Object.assign(funeralHome, { occupancyTypeId: cremationOccupancyTypeId }),
session
)
// Funeral Date // Funeral Date
const funeralDate = { const funeralDate = {
occupancyTypeId: intermentOccupancyTypeId, occupancyTypeId: intermentOccupancyTypeId,
occupancyTypeField: "Funeral Date", occupancyTypeField: 'Funeral Date',
occupancyTypeFieldValues: "", occupancyTypeFieldValues: '',
pattern: "\\d{4}([\\/-]\\d{2}){2}", pattern: '\\d{4}([\\/-]\\d{2}){2}',
isRequired: "", isRequired: '',
minimumLength: 10, minimumLength: 10,
maximumLength: 10, maximumLength: 10,
orderNumber: 11 orderNumber: 11
}; }
addOccupancyTypeField(funeralDate, session); addOccupancyTypeField(funeralDate, session)
addOccupancyTypeField(Object.assign(funeralDate, { occupancyTypeId: cremationOccupancyTypeId }), session); addOccupancyTypeField(
Object.assign(funeralDate, { occupancyTypeId: cremationOccupancyTypeId }),
session
)
// Container Type // Container Type
const containerType = { const containerType = {
occupancyTypeId: intermentOccupancyTypeId, occupancyTypeId: intermentOccupancyTypeId,
occupancyTypeField: "Container Type", occupancyTypeField: 'Container Type',
occupancyTypeFieldValues: "", occupancyTypeFieldValues: '',
pattern: "", pattern: '',
isRequired: "", isRequired: '',
minimumLength: 1, minimumLength: 1,
maximumLength: 100, maximumLength: 100,
orderNumber: 20 orderNumber: 20
}; }
addOccupancyTypeField(containerType, session); addOccupancyTypeField(containerType, session)
addOccupancyTypeField( addOccupancyTypeField(
Object.assign(containerType, { occupancyTypeId: cremationOccupancyTypeId }), Object.assign(containerType, { occupancyTypeId: cremationOccupancyTypeId }),
session session
); )
// Committal Type // Committal Type
const committalType = { const committalType = {
occupancyTypeId: intermentOccupancyTypeId, occupancyTypeId: intermentOccupancyTypeId,
occupancyTypeField: "Committal Type", occupancyTypeField: 'Committal Type',
occupancyTypeFieldValues: "", occupancyTypeFieldValues: '',
pattern: "", pattern: '',
isRequired: "", isRequired: '',
minimumLength: 1, minimumLength: 1,
maximumLength: 100, maximumLength: 100,
orderNumber: 21 orderNumber: 21
}; }
addOccupancyTypeField(committalType, session); addOccupancyTypeField(committalType, session)
addOccupancyTypeField( addOccupancyTypeField(
Object.assign(committalType, { occupancyTypeId: cremationOccupancyTypeId }), Object.assign(committalType, { occupancyTypeId: cremationOccupancyTypeId }),
session session
); )
/* /*
* Fee Categories * Fee Categories
*/ */
addRecord("FeeCategories", "Interment Rights", 1, session); addRecord('FeeCategories', 'Interment Rights', 1, session)
addRecord("FeeCategories", "Cremation Services", 2, session); addRecord('FeeCategories', 'Cremation Services', 2, session)
addRecord("FeeCategories", "Burial Charges", 3, session); addRecord('FeeCategories', 'Burial Charges', 3, session)
addRecord("FeeCategories", "Disinterment of Human Remains", 4, session); addRecord('FeeCategories', 'Disinterment of Human Remains', 4, session)
addRecord("FeeCategories", "Additional Services", 4, session); addRecord('FeeCategories', 'Additional Services', 4, session)
} }
initializeCemeteryDatabase(); initializeCemeteryDatabase()

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';
import debug from "debug"; import debug from 'debug';
const debugSQL = debug("lot-occupancy-system:databaseInitializer"); const debugSQL = debug('lot-occupancy-system:databaseInitializer');
const recordColumns = `recordCreate_userName varchar(30) not null, const recordColumns = `recordCreate_userName varchar(30) not null,
recordCreate_timeMillis integer not null, recordCreate_timeMillis integer not null,
recordUpdate_userName varchar(30) not null, recordUpdate_userName varchar(30) not null,
@ -10,42 +10,42 @@ const recordColumns = `recordCreate_userName varchar(30) not null,
recordDelete_timeMillis integer`; recordDelete_timeMillis integer`;
const createStatements = [ const createStatements = [
`create table if not exists LotTypes (lotTypeId integer not null primary key autoincrement, lotType varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`, `create table if not exists LotTypes (lotTypeId integer not null primary key autoincrement, lotType varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`,
`create index if not exists idx_lottypes_ordernumber on LotTypes (orderNumber, lotType)`, 'create index if not exists idx_lottypes_ordernumber on LotTypes (orderNumber, lotType)',
`create table if not exists LotTypeFields (lotTypeFieldId integer not null primary key autoincrement, lotTypeId integer not null, lotTypeField varchar(100) not null, lotTypeFieldValues text, isRequired bit not null default 0, pattern varchar(100), minimumLength smallint not null default 1 check (minimumLength >= 0), maximumLength smallint not null default 100 check (maximumLength >= 0), orderNumber smallint not null default 0, ${recordColumns}, foreign key (lotTypeId) references LotTypes (lotTypeId))`, `create table if not exists LotTypeFields (lotTypeFieldId integer not null primary key autoincrement, lotTypeId integer not null, lotTypeField varchar(100) not null, lotTypeFieldValues text, isRequired bit not null default 0, pattern varchar(100), minimumLength smallint not null default 1 check (minimumLength >= 0), maximumLength smallint not null default 100 check (maximumLength >= 0), orderNumber smallint not null default 0, ${recordColumns}, foreign key (lotTypeId) references LotTypes (lotTypeId))`,
`create index if not exists idx_lottypefields_ordernumber on LotTypeFields (lotTypeId, orderNumber, lotTypeField)`, 'create index if not exists idx_lottypefields_ordernumber on LotTypeFields (lotTypeId, orderNumber, lotTypeField)',
`create table if not exists LotStatuses (lotStatusId integer not null primary key autoincrement, lotStatus varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`, `create table if not exists LotStatuses (lotStatusId integer not null primary key autoincrement, lotStatus varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`,
`create index if not exists idx_lotstatuses_ordernumber on LotStatuses (orderNumber, lotStatus)`, 'create index if not exists idx_lotstatuses_ordernumber on LotStatuses (orderNumber, lotStatus)',
`create table if not exists Maps (mapId integer not null primary key autoincrement, mapName varchar(200) not null, mapDescription text, mapLatitude decimal(10, 8) check (mapLatitude between -90 and 90), mapLongitude decimal(11, 8) check (mapLongitude between -180 and 180), mapSVG varchar(50), mapAddress1 varchar(50), mapAddress2 varchar(50), mapCity varchar(20), mapProvince varchar(2), mapPostalCode varchar(7), mapPhoneNumber varchar(30), ${recordColumns})`, `create table if not exists Maps (mapId integer not null primary key autoincrement, mapName varchar(200) not null, mapDescription text, mapLatitude decimal(10, 8) check (mapLatitude between -90 and 90), mapLongitude decimal(11, 8) check (mapLongitude between -180 and 180), mapSVG varchar(50), mapAddress1 varchar(50), mapAddress2 varchar(50), mapCity varchar(20), mapProvince varchar(2), mapPostalCode varchar(7), mapPhoneNumber varchar(30), ${recordColumns})`,
`create table if not exists Lots (lotId integer not null primary key autoincrement, lotTypeId integer not null, lotName varchar(100), mapId integer, mapKey varchar(100), lotLatitude decimal(10, 8) check (lotLatitude between -90 and 90), lotLongitude decimal(11, 8) check (lotLongitude between -180 and 180), lotStatusId integer, ${recordColumns}, foreign key (lotTypeId) references LotTypes (lotTypeId), foreign key (mapId) references Maps (mapId), foreign key (lotStatusId) references LotStatuses (lotStatusId))`, `create table if not exists Lots (lotId integer not null primary key autoincrement, lotTypeId integer not null, lotName varchar(100), mapId integer, mapKey varchar(100), lotLatitude decimal(10, 8) check (lotLatitude between -90 and 90), lotLongitude decimal(11, 8) check (lotLongitude between -180 and 180), lotStatusId integer, ${recordColumns}, foreign key (lotTypeId) references LotTypes (lotTypeId), foreign key (mapId) references Maps (mapId), foreign key (lotStatusId) references LotStatuses (lotStatusId))`,
`create table if not exists LotFields (lotId integer not null, lotTypeFieldId integer not null, lotFieldValue text not null, ${recordColumns}, primary key (lotId, lotTypeFieldId), foreign key (lotId) references Lots (lotId), foreign key (lotTypeFieldId) references LotTypeFields (lotTypeFieldId)) without rowid`, `create table if not exists LotFields (lotId integer not null, lotTypeFieldId integer not null, lotFieldValue text not null, ${recordColumns}, primary key (lotId, lotTypeFieldId), foreign key (lotId) references Lots (lotId), foreign key (lotTypeFieldId) references LotTypeFields (lotTypeFieldId)) without rowid`,
`create table if not exists LotComments (lotCommentId integer not null primary key autoincrement, lotId integer not null, lotCommentDate integer not null check (lotCommentDate > 0), lotCommentTime integer not null check (lotCommentTime >= 0), lotComment text not null, ${recordColumns}, foreign key (lotId) references Lots (lotId))`, `create table if not exists LotComments (lotCommentId integer not null primary key autoincrement, lotId integer not null, lotCommentDate integer not null check (lotCommentDate > 0), lotCommentTime integer not null check (lotCommentTime >= 0), lotComment text not null, ${recordColumns}, foreign key (lotId) references Lots (lotId))`,
`create index if not exists idx_lotcomments_datetime on LotComments (lotId, lotCommentDate, lotCommentTime)`, 'create index if not exists idx_lotcomments_datetime on LotComments (lotId, lotCommentDate, lotCommentTime)',
`create table if not exists OccupancyTypes (occupancyTypeId integer not null primary key autoincrement, occupancyType varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`, `create table if not exists OccupancyTypes (occupancyTypeId integer not null primary key autoincrement, occupancyType varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`,
`create index if not exists idx_occupancytypes_ordernumber on OccupancyTypes (orderNumber, occupancyType)`, 'create index if not exists idx_occupancytypes_ordernumber on OccupancyTypes (orderNumber, occupancyType)',
`create table if not exists OccupancyTypeFields (occupancyTypeFieldId integer not null primary key autoincrement, occupancyTypeId integer, occupancyTypeField varchar(100) not null, occupancyTypeFieldValues text, isRequired bit not null default 0, pattern varchar(100), minimumLength smallint not null default 1 check (minimumLength >= 0), maximumLength smallint not null default 100 check (maximumLength >= 0), orderNumber smallint not null default 0, ${recordColumns}, foreign key (occupancyTypeId) references OccupancyTypes (occupancyTypeId))`, `create table if not exists OccupancyTypeFields (occupancyTypeFieldId integer not null primary key autoincrement, occupancyTypeId integer, occupancyTypeField varchar(100) not null, occupancyTypeFieldValues text, isRequired bit not null default 0, pattern varchar(100), minimumLength smallint not null default 1 check (minimumLength >= 0), maximumLength smallint not null default 100 check (maximumLength >= 0), orderNumber smallint not null default 0, ${recordColumns}, foreign key (occupancyTypeId) references OccupancyTypes (occupancyTypeId))`,
`create index if not exists idx_occupancytypefields_ordernumber on OccupancyTypeFields (occupancyTypeId, orderNumber, occupancyTypeField)`, 'create index if not exists idx_occupancytypefields_ordernumber on OccupancyTypeFields (occupancyTypeId, orderNumber, occupancyTypeField)',
`create table if not exists OccupancyTypePrints (occupancyTypeId integer not null, printEJS varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns}, primary key (occupancyTypeId, printEJS), foreign key (occupancyTypeId) references OccupancyTypes (occupancyTypeId))`, `create table if not exists OccupancyTypePrints (occupancyTypeId integer not null, printEJS varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns}, primary key (occupancyTypeId, printEJS), foreign key (occupancyTypeId) references OccupancyTypes (occupancyTypeId))`,
`create index if not exists idx_occupancytypeprints_ordernumber on OccupancyTypePrints (occupancyTypeId, orderNumber, printEJS)`, 'create index if not exists idx_occupancytypeprints_ordernumber on OccupancyTypePrints (occupancyTypeId, orderNumber, printEJS)',
`create table if not exists LotOccupantTypes (lotOccupantTypeId integer not null primary key autoincrement, lotOccupantType varchar(100) not null, fontAwesomeIconClass varchar(50) not null default '', orderNumber smallint not null default 0, ${recordColumns})`, `create table if not exists LotOccupantTypes (lotOccupantTypeId integer not null primary key autoincrement, lotOccupantType varchar(100) not null, fontAwesomeIconClass varchar(50) not null default '', orderNumber smallint not null default 0, ${recordColumns})`,
`create index if not exists idx_lotoccupanttypes_ordernumber on LotOccupantTypes (orderNumber, lotOccupantType)`, 'create index if not exists idx_lotoccupanttypes_ordernumber on LotOccupantTypes (orderNumber, lotOccupantType)',
`create table if not exists LotOccupancies (lotOccupancyId integer not null primary key autoincrement, occupancyTypeId integer not null, lotId integer, occupancyStartDate integer not null check (occupancyStartDate > 0), occupancyEndDate integer check (occupancyEndDate > 0), ${recordColumns}, foreign key (lotId) references Lots (lotId), foreign key (occupancyTypeId) references OccupancyTypes (occupancyTypeId))`, `create table if not exists LotOccupancies (lotOccupancyId integer not null primary key autoincrement, occupancyTypeId integer not null, lotId integer, occupancyStartDate integer not null check (occupancyStartDate > 0), occupancyEndDate integer check (occupancyEndDate > 0), ${recordColumns}, foreign key (lotId) references Lots (lotId), foreign key (occupancyTypeId) references OccupancyTypes (occupancyTypeId))`,
`create table if not exists LotOccupancyOccupants (lotOccupancyId integer not null, lotOccupantIndex integer not null, occupantName varchar(200) not null, occupantAddress1 varchar(50), occupantAddress2 varchar(50), occupantCity varchar(20), occupantProvince varchar(2), occupantPostalCode varchar(7), occupantPhoneNumber varchar(30), occupantEmailAddress varchar(200), lotOccupantTypeId integer not null, occupantComment text not null default '', ${recordColumns}, primary key (lotOccupancyId, lotOccupantIndex), foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId), foreign key (lotOccupantTypeId) references LotOccupantTypes (lotOccupantTypeId)) without rowid`, `create table if not exists LotOccupancyOccupants (lotOccupancyId integer not null, lotOccupantIndex integer not null, occupantName varchar(200) not null, occupantAddress1 varchar(50), occupantAddress2 varchar(50), occupantCity varchar(20), occupantProvince varchar(2), occupantPostalCode varchar(7), occupantPhoneNumber varchar(30), occupantEmailAddress varchar(200), lotOccupantTypeId integer not null, occupantComment text not null default '', ${recordColumns}, primary key (lotOccupancyId, lotOccupantIndex), foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId), foreign key (lotOccupantTypeId) references LotOccupantTypes (lotOccupantTypeId)) without rowid`,
`create table if not exists LotOccupancyFields (lotOccupancyId integer not null, occupancyTypeFieldId integer not null, lotOccupancyFieldValue text not null, ${recordColumns}, primary key (lotOccupancyId, occupancyTypeFieldId), foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId), foreign key (occupancyTypeFieldId) references OccupancyTypeFields (occupancyTypeFieldId)) without rowid`, `create table if not exists LotOccupancyFields (lotOccupancyId integer not null, occupancyTypeFieldId integer not null, lotOccupancyFieldValue text not null, ${recordColumns}, primary key (lotOccupancyId, occupancyTypeFieldId), foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId), foreign key (occupancyTypeFieldId) references OccupancyTypeFields (occupancyTypeFieldId)) without rowid`,
`create table if not exists LotOccupancyComments (lotOccupancyCommentId integer not null primary key autoincrement, lotOccupancyId integer not null, lotOccupancyCommentDate integer not null check (lotOccupancyCommentDate > 0), lotOccupancyCommentTime integer not null check (lotOccupancyCommentTime >= 0), lotOccupancyComment text not null, ${recordColumns}, foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId))`, `create table if not exists LotOccupancyComments (lotOccupancyCommentId integer not null primary key autoincrement, lotOccupancyId integer not null, lotOccupancyCommentDate integer not null check (lotOccupancyCommentDate > 0), lotOccupancyCommentTime integer not null check (lotOccupancyCommentTime >= 0), lotOccupancyComment text not null, ${recordColumns}, foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId))`,
`create index if not exists idx_lotoccupancycomments_datetime on LotOccupancyComments (lotOccupancyId, lotOccupancyCommentDate, lotOccupancyCommentTime)`, 'create index if not exists idx_lotoccupancycomments_datetime on LotOccupancyComments (lotOccupancyId, lotOccupancyCommentDate, lotOccupancyCommentTime)',
`create table if not exists FeeCategories (feeCategoryId integer not null primary key autoincrement, feeCategory varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`, `create table if not exists FeeCategories (feeCategoryId integer not null primary key autoincrement, feeCategory varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`,
`create table if not exists Fees (feeId integer not null primary key autoincrement, feeCategoryId integer not null, feeName varchar(100) not null, feeDescription text, occupancyTypeId integer, lotTypeId integer, includeQuantity boolean not null default 0, quantityUnit varchar(30), feeAmount decimal(8, 2), feeFunction varchar(100), taxAmount decimal(6, 2), taxPercentage decimal(5, 2), isRequired bit not null default 0, orderNumber smallint not null default 0, ${recordColumns}, foreign key (feeCategoryId) references FeeCategories (feeCategoryId), foreign key (occupancyTypeId) references OccupancyTypes (occupancyTypeId), foreign key (lotTypeId) references LotTypes (lotTypeId))`, `create table if not exists Fees (feeId integer not null primary key autoincrement, feeCategoryId integer not null, feeName varchar(100) not null, feeDescription text, occupancyTypeId integer, lotTypeId integer, includeQuantity boolean not null default 0, quantityUnit varchar(30), feeAmount decimal(8, 2), feeFunction varchar(100), taxAmount decimal(6, 2), taxPercentage decimal(5, 2), isRequired bit not null default 0, orderNumber smallint not null default 0, ${recordColumns}, foreign key (feeCategoryId) references FeeCategories (feeCategoryId), foreign key (occupancyTypeId) references OccupancyTypes (occupancyTypeId), foreign key (lotTypeId) references LotTypes (lotTypeId))`,
`create index if not exists idx_fees_ordernumber on Fees (orderNumber, feeName)`, 'create index if not exists idx_fees_ordernumber on Fees (orderNumber, feeName)',
`create table if not exists LotOccupancyFees (lotOccupancyId integer not null, feeId integer not null, quantity decimal(4, 1) not null default 1, feeAmount decimal(8, 2) not null, taxAmount decmial(8, 2) not null, ${recordColumns}, primary key (lotOccupancyId, feeId), foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId), foreign key (feeId) references Fees (feeId)) without rowid`, `create table if not exists LotOccupancyFees (lotOccupancyId integer not null, feeId integer not null, quantity decimal(4, 1) not null default 1, feeAmount decimal(8, 2) not null, taxAmount decmial(8, 2) not null, ${recordColumns}, primary key (lotOccupancyId, feeId), foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId), foreign key (feeId) references Fees (feeId)) without rowid`,
`create table if not exists LotOccupancyTransactions (lotOccupancyId integer not null, transactionIndex integer not null, transactionDate integer not null check (transactionDate > 0), transactionTime integer not null check (transactionTime >= 0), transactionAmount decimal(8, 2) not null, externalReceiptNumber varchar(100), transactionNote text, ${recordColumns}, primary key (lotOccupancyId, transactionIndex), foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId)) without rowid`, `create table if not exists LotOccupancyTransactions (lotOccupancyId integer not null, transactionIndex integer not null, transactionDate integer not null check (transactionDate > 0), transactionTime integer not null check (transactionTime >= 0), transactionAmount decimal(8, 2) not null, externalReceiptNumber varchar(100), transactionNote text, ${recordColumns}, primary key (lotOccupancyId, transactionIndex), foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId)) without rowid`,
`create index if not exists idx_lotoccupancytransactions_ordernumber on LotOccupancyTransactions (lotOccupancyId, transactionDate, transactionTime)`, 'create index if not exists idx_lotoccupancytransactions_ordernumber on LotOccupancyTransactions (lotOccupancyId, transactionDate, transactionTime)',
`create table if not exists WorkOrderTypes (workOrderTypeId integer not null primary key autoincrement, workOrderType varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`, `create table if not exists WorkOrderTypes (workOrderTypeId integer not null primary key autoincrement, workOrderType varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`,
`create index if not exists idx_workordertypes_ordernumber on WorkOrderTypes (orderNumber, workOrderType)`, 'create index if not exists idx_workordertypes_ordernumber on WorkOrderTypes (orderNumber, workOrderType)',
`create table if not exists WorkOrders (workOrderId integer not null primary key autoincrement, workOrderTypeId integer not null, workOrderNumber varchar(50) not null, workOrderDescription text, workOrderOpenDate integer check (workOrderOpenDate > 0), workOrderCloseDate integer check (workOrderCloseDate > 0), ${recordColumns}, foreign key (workOrderTypeId) references WorkOrderTypes (workOrderTypeId))`, `create table if not exists WorkOrders (workOrderId integer not null primary key autoincrement, workOrderTypeId integer not null, workOrderNumber varchar(50) not null, workOrderDescription text, workOrderOpenDate integer check (workOrderOpenDate > 0), workOrderCloseDate integer check (workOrderCloseDate > 0), ${recordColumns}, foreign key (workOrderTypeId) references WorkOrderTypes (workOrderTypeId))`,
`create table if not exists WorkOrderLots (workOrderId integer not null, lotId integer not null, ${recordColumns}, primary key (workOrderId, lotId), foreign key (workOrderId) references WorkOrders (workOrderId), foreign key (lotId) references Lots (lotId)) without rowid`, `create table if not exists WorkOrderLots (workOrderId integer not null, lotId integer not null, ${recordColumns}, primary key (workOrderId, lotId), foreign key (workOrderId) references WorkOrders (workOrderId), foreign key (lotId) references Lots (lotId)) without rowid`,
`create table if not exists WorkOrderLotOccupancies (workOrderId integer not null, lotOccupancyId integer not null, ${recordColumns}, primary key (workOrderId, lotOccupancyId), foreign key (workOrderId) references WorkOrders (workOrderId), foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId)) without rowid`, `create table if not exists WorkOrderLotOccupancies (workOrderId integer not null, lotOccupancyId integer not null, ${recordColumns}, primary key (workOrderId, lotOccupancyId), foreign key (workOrderId) references WorkOrders (workOrderId), foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId)) without rowid`,
`create table if not exists WorkOrderComments (workOrderCommentId integer not null primary key autoincrement, workOrderId integer not null, workOrderCommentDate integer not null check (workOrderCommentDate > 0), workOrderCommentTime integer not null check (workOrderCommentTime >= 0), workOrderComment text not null, ${recordColumns}, foreign key (workOrderId) references WorkOrders (workOrderId))`, `create table if not exists WorkOrderComments (workOrderCommentId integer not null primary key autoincrement, workOrderId integer not null, workOrderCommentDate integer not null check (workOrderCommentDate > 0), workOrderCommentTime integer not null check (workOrderCommentTime >= 0), workOrderComment text not null, ${recordColumns}, foreign key (workOrderId) references WorkOrders (workOrderId))`,
`create index if not exists idx_workordercomments_datetime on WorkOrderComments (workOrderId, workOrderCommentDate, workOrderCommentTime)`, 'create index if not exists idx_workordercomments_datetime on WorkOrderComments (workOrderId, workOrderCommentDate, workOrderCommentTime)',
`create table if not exists WorkOrderMilestoneTypes (workOrderMilestoneTypeId integer not null primary key autoincrement, workOrderMilestoneType varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`, `create table if not exists WorkOrderMilestoneTypes (workOrderMilestoneTypeId integer not null primary key autoincrement, workOrderMilestoneType varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`,
`create table if not exists WorkOrderMilestones (workOrderMilestoneId integer not null primary key autoincrement, workOrderId integer not null, workOrderMilestoneTypeId integer, workOrderMilestoneDate integer not null check (workOrderMilestoneDate > 0), workOrderMilestoneTime integer not null check (workOrderMilestoneTime >= 0), workOrderMilestoneDescription text not null, workOrderMilestoneCompletionDate integer check (workOrderMilestoneCompletionDate > 0), workOrderMilestoneCompletionTime integer check (workOrderMilestoneCompletionTime >= 0), ${recordColumns}, foreign key (workOrderId) references WorkOrders (workOrderId), foreign key (workOrderMilestoneTypeId) references WorkOrderMilestoneTypes (workOrderMilestoneTypeId))` `create table if not exists WorkOrderMilestones (workOrderMilestoneId integer not null primary key autoincrement, workOrderId integer not null, workOrderMilestoneTypeId integer, workOrderMilestoneDate integer not null check (workOrderMilestoneDate > 0), workOrderMilestoneTime integer not null check (workOrderMilestoneTime >= 0), workOrderMilestoneDescription text not null, workOrderMilestoneCompletionDate integer check (workOrderMilestoneCompletionDate > 0), workOrderMilestoneCompletionTime integer check (workOrderMilestoneCompletionTime >= 0), ${recordColumns}, foreign key (workOrderId) references WorkOrders (workOrderId), foreign key (workOrderMilestoneTypeId) references WorkOrderMilestoneTypes (workOrderMilestoneTypeId))`
]; ];
@ -55,7 +55,7 @@ export function initializeDatabase() {
.prepare("select name from sqlite_master where type = 'table' and name = 'WorkOrderMilestones'") .prepare("select name from sqlite_master where type = 'table' and name = 'WorkOrderMilestones'")
.get(); .get();
if (!row) { if (!row) {
debugSQL("Creating " + databasePath); debugSQL('Creating ' + databasePath);
for (const sql of createStatements) { for (const sql of createStatements) {
lotOccupancyDB.prepare(sql).run(); lotOccupancyDB.prepare(sql).run();
} }

View File

@ -1,88 +1,90 @@
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'
import debug from "debug"; import debug from 'debug'
const debugSQL = debug("lot-occupancy-system:databaseInitializer"); const debugSQL = debug('lot-occupancy-system:databaseInitializer')
const recordColumns = `recordCreate_userName varchar(30) not null, const recordColumns = `recordCreate_userName varchar(30) not null,
recordCreate_timeMillis integer not null, recordCreate_timeMillis integer not null,
recordUpdate_userName varchar(30) not null, recordUpdate_userName varchar(30) not null,
recordUpdate_timeMillis integer not null, recordUpdate_timeMillis integer not null,
recordDelete_userName varchar(30), recordDelete_userName varchar(30),
recordDelete_timeMillis integer`; recordDelete_timeMillis integer`
const createStatements = [ const createStatements = [
// Lot Types // Lot Types
`create table if not exists LotTypes (lotTypeId integer not null primary key autoincrement, lotType varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`, `create table if not exists LotTypes (lotTypeId integer not null primary key autoincrement, lotType varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`,
`create index if not exists idx_lottypes_ordernumber on LotTypes (orderNumber, lotType)`, 'create index if not exists idx_lottypes_ordernumber on LotTypes (orderNumber, lotType)',
`create table if not exists LotTypeFields (lotTypeFieldId integer not null primary key autoincrement, lotTypeId integer not null, lotTypeField varchar(100) not null, lotTypeFieldValues text, isRequired bit not null default 0, pattern varchar(100), minimumLength smallint not null default 1 check (minimumLength >= 0), maximumLength smallint not null default 100 check (maximumLength >= 0), orderNumber smallint not null default 0, ${recordColumns}, foreign key (lotTypeId) references LotTypes (lotTypeId))`, `create table if not exists LotTypeFields (lotTypeFieldId integer not null primary key autoincrement, lotTypeId integer not null, lotTypeField varchar(100) not null, lotTypeFieldValues text, isRequired bit not null default 0, pattern varchar(100), minimumLength smallint not null default 1 check (minimumLength >= 0), maximumLength smallint not null default 100 check (maximumLength >= 0), orderNumber smallint not null default 0, ${recordColumns}, foreign key (lotTypeId) references LotTypes (lotTypeId))`,
`create index if not exists idx_lottypefields_ordernumber on LotTypeFields (lotTypeId, orderNumber, lotTypeField)`, 'create index if not exists idx_lottypefields_ordernumber on LotTypeFields (lotTypeId, orderNumber, lotTypeField)',
// Lot Statuses // Lot Statuses
`create table if not exists LotStatuses (lotStatusId integer not null primary key autoincrement, lotStatus varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`, `create table if not exists LotStatuses (lotStatusId integer not null primary key autoincrement, lotStatus varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`,
`create index if not exists idx_lotstatuses_ordernumber on LotStatuses (orderNumber, lotStatus)`, 'create index if not exists idx_lotstatuses_ordernumber on LotStatuses (orderNumber, lotStatus)',
// Maps and Lots // Maps and Lots
`create table if not exists Maps (mapId integer not null primary key autoincrement, mapName varchar(200) not null, mapDescription text, mapLatitude decimal(10, 8) check (mapLatitude between -90 and 90), mapLongitude decimal(11, 8) check (mapLongitude between -180 and 180), mapSVG varchar(50), mapAddress1 varchar(50), mapAddress2 varchar(50), mapCity varchar(20), mapProvince varchar(2), mapPostalCode varchar(7), mapPhoneNumber varchar(30), ${recordColumns})`, `create table if not exists Maps (mapId integer not null primary key autoincrement, mapName varchar(200) not null, mapDescription text, mapLatitude decimal(10, 8) check (mapLatitude between -90 and 90), mapLongitude decimal(11, 8) check (mapLongitude between -180 and 180), mapSVG varchar(50), mapAddress1 varchar(50), mapAddress2 varchar(50), mapCity varchar(20), mapProvince varchar(2), mapPostalCode varchar(7), mapPhoneNumber varchar(30), ${recordColumns})`,
`create table if not exists Lots (lotId integer not null primary key autoincrement, lotTypeId integer not null, lotName varchar(100), mapId integer, mapKey varchar(100), lotLatitude decimal(10, 8) check (lotLatitude between -90 and 90), lotLongitude decimal(11, 8) check (lotLongitude between -180 and 180), lotStatusId integer, ${recordColumns}, foreign key (lotTypeId) references LotTypes (lotTypeId), foreign key (mapId) references Maps (mapId), foreign key (lotStatusId) references LotStatuses (lotStatusId))`, `create table if not exists Lots (lotId integer not null primary key autoincrement, lotTypeId integer not null, lotName varchar(100), mapId integer, mapKey varchar(100), lotLatitude decimal(10, 8) check (lotLatitude between -90 and 90), lotLongitude decimal(11, 8) check (lotLongitude between -180 and 180), lotStatusId integer, ${recordColumns}, foreign key (lotTypeId) references LotTypes (lotTypeId), foreign key (mapId) references Maps (mapId), foreign key (lotStatusId) references LotStatuses (lotStatusId))`,
`create table if not exists LotFields (lotId integer not null, lotTypeFieldId integer not null, lotFieldValue text not null, ${recordColumns}, primary key (lotId, lotTypeFieldId), foreign key (lotId) references Lots (lotId), foreign key (lotTypeFieldId) references LotTypeFields (lotTypeFieldId)) without rowid`, `create table if not exists LotFields (lotId integer not null, lotTypeFieldId integer not null, lotFieldValue text not null, ${recordColumns}, primary key (lotId, lotTypeFieldId), foreign key (lotId) references Lots (lotId), foreign key (lotTypeFieldId) references LotTypeFields (lotTypeFieldId)) without rowid`,
`create table if not exists LotComments (lotCommentId integer not null primary key autoincrement, lotId integer not null, lotCommentDate integer not null check (lotCommentDate > 0), lotCommentTime integer not null check (lotCommentTime >= 0), lotComment text not null, ${recordColumns}, foreign key (lotId) references Lots (lotId))`, `create table if not exists LotComments (lotCommentId integer not null primary key autoincrement, lotId integer not null, lotCommentDate integer not null check (lotCommentDate > 0), lotCommentTime integer not null check (lotCommentTime >= 0), lotComment text not null, ${recordColumns}, foreign key (lotId) references Lots (lotId))`,
`create index if not exists idx_lotcomments_datetime on LotComments (lotId, lotCommentDate, lotCommentTime)`, 'create index if not exists idx_lotcomments_datetime on LotComments (lotId, lotCommentDate, lotCommentTime)',
// Occupancies // Occupancies
`create table if not exists OccupancyTypes (occupancyTypeId integer not null primary key autoincrement, occupancyType varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`, `create table if not exists OccupancyTypes (occupancyTypeId integer not null primary key autoincrement, occupancyType varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`,
`create index if not exists idx_occupancytypes_ordernumber on OccupancyTypes (orderNumber, occupancyType)`, 'create index if not exists idx_occupancytypes_ordernumber on OccupancyTypes (orderNumber, occupancyType)',
`create table if not exists OccupancyTypeFields (occupancyTypeFieldId integer not null primary key autoincrement, occupancyTypeId integer, occupancyTypeField varchar(100) not null, occupancyTypeFieldValues text, isRequired bit not null default 0, pattern varchar(100), minimumLength smallint not null default 1 check (minimumLength >= 0), maximumLength smallint not null default 100 check (maximumLength >= 0), orderNumber smallint not null default 0, ${recordColumns}, foreign key (occupancyTypeId) references OccupancyTypes (occupancyTypeId))`, `create table if not exists OccupancyTypeFields (occupancyTypeFieldId integer not null primary key autoincrement, occupancyTypeId integer, occupancyTypeField varchar(100) not null, occupancyTypeFieldValues text, isRequired bit not null default 0, pattern varchar(100), minimumLength smallint not null default 1 check (minimumLength >= 0), maximumLength smallint not null default 100 check (maximumLength >= 0), orderNumber smallint not null default 0, ${recordColumns}, foreign key (occupancyTypeId) references OccupancyTypes (occupancyTypeId))`,
`create index if not exists idx_occupancytypefields_ordernumber on OccupancyTypeFields (occupancyTypeId, orderNumber, occupancyTypeField)`, 'create index if not exists idx_occupancytypefields_ordernumber on OccupancyTypeFields (occupancyTypeId, orderNumber, occupancyTypeField)',
`create table if not exists OccupancyTypePrints (occupancyTypeId integer not null, printEJS varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns}, primary key (occupancyTypeId, printEJS), foreign key (occupancyTypeId) references OccupancyTypes (occupancyTypeId))`, `create table if not exists OccupancyTypePrints (occupancyTypeId integer not null, printEJS varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns}, primary key (occupancyTypeId, printEJS), foreign key (occupancyTypeId) references OccupancyTypes (occupancyTypeId))`,
`create index if not exists idx_occupancytypeprints_ordernumber on OccupancyTypePrints (occupancyTypeId, orderNumber, printEJS)`, 'create index if not exists idx_occupancytypeprints_ordernumber on OccupancyTypePrints (occupancyTypeId, orderNumber, printEJS)',
`create table if not exists LotOccupantTypes (lotOccupantTypeId integer not null primary key autoincrement, lotOccupantType varchar(100) not null, fontAwesomeIconClass varchar(50) not null default '', orderNumber smallint not null default 0, ${recordColumns})`, `create table if not exists LotOccupantTypes (lotOccupantTypeId integer not null primary key autoincrement, lotOccupantType varchar(100) not null, fontAwesomeIconClass varchar(50) not null default '', orderNumber smallint not null default 0, ${recordColumns})`,
`create index if not exists idx_lotoccupanttypes_ordernumber on LotOccupantTypes (orderNumber, lotOccupantType)`, 'create index if not exists idx_lotoccupanttypes_ordernumber on LotOccupantTypes (orderNumber, lotOccupantType)',
`create table if not exists LotOccupancies (lotOccupancyId integer not null primary key autoincrement, occupancyTypeId integer not null, lotId integer, occupancyStartDate integer not null check (occupancyStartDate > 0), occupancyEndDate integer check (occupancyEndDate > 0), ${recordColumns}, foreign key (lotId) references Lots (lotId), foreign key (occupancyTypeId) references OccupancyTypes (occupancyTypeId))`, `create table if not exists LotOccupancies (lotOccupancyId integer not null primary key autoincrement, occupancyTypeId integer not null, lotId integer, occupancyStartDate integer not null check (occupancyStartDate > 0), occupancyEndDate integer check (occupancyEndDate > 0), ${recordColumns}, foreign key (lotId) references Lots (lotId), foreign key (occupancyTypeId) references OccupancyTypes (occupancyTypeId))`,
`create table if not exists LotOccupancyOccupants (lotOccupancyId integer not null, lotOccupantIndex integer not null, occupantName varchar(200) not null, occupantAddress1 varchar(50), occupantAddress2 varchar(50), occupantCity varchar(20), occupantProvince varchar(2), occupantPostalCode varchar(7), occupantPhoneNumber varchar(30), occupantEmailAddress varchar(200), lotOccupantTypeId integer not null, occupantComment text not null default '', ${recordColumns}, primary key (lotOccupancyId, lotOccupantIndex), foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId), foreign key (lotOccupantTypeId) references LotOccupantTypes (lotOccupantTypeId)) without rowid`, `create table if not exists LotOccupancyOccupants (lotOccupancyId integer not null, lotOccupantIndex integer not null, occupantName varchar(200) not null, occupantAddress1 varchar(50), occupantAddress2 varchar(50), occupantCity varchar(20), occupantProvince varchar(2), occupantPostalCode varchar(7), occupantPhoneNumber varchar(30), occupantEmailAddress varchar(200), lotOccupantTypeId integer not null, occupantComment text not null default '', ${recordColumns}, primary key (lotOccupancyId, lotOccupantIndex), foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId), foreign key (lotOccupantTypeId) references LotOccupantTypes (lotOccupantTypeId)) without rowid`,
`create table if not exists LotOccupancyFields (lotOccupancyId integer not null, occupancyTypeFieldId integer not null, lotOccupancyFieldValue text not null, ${recordColumns}, primary key (lotOccupancyId, occupancyTypeFieldId), foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId), foreign key (occupancyTypeFieldId) references OccupancyTypeFields (occupancyTypeFieldId)) without rowid`, `create table if not exists LotOccupancyFields (lotOccupancyId integer not null, occupancyTypeFieldId integer not null, lotOccupancyFieldValue text not null, ${recordColumns}, primary key (lotOccupancyId, occupancyTypeFieldId), foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId), foreign key (occupancyTypeFieldId) references OccupancyTypeFields (occupancyTypeFieldId)) without rowid`,
`create table if not exists LotOccupancyComments (lotOccupancyCommentId integer not null primary key autoincrement, lotOccupancyId integer not null, lotOccupancyCommentDate integer not null check (lotOccupancyCommentDate > 0), lotOccupancyCommentTime integer not null check (lotOccupancyCommentTime >= 0), lotOccupancyComment text not null, ${recordColumns}, foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId))`, `create table if not exists LotOccupancyComments (lotOccupancyCommentId integer not null primary key autoincrement, lotOccupancyId integer not null, lotOccupancyCommentDate integer not null check (lotOccupancyCommentDate > 0), lotOccupancyCommentTime integer not null check (lotOccupancyCommentTime >= 0), lotOccupancyComment text not null, ${recordColumns}, foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId))`,
`create index if not exists idx_lotoccupancycomments_datetime on LotOccupancyComments (lotOccupancyId, lotOccupancyCommentDate, lotOccupancyCommentTime)`, 'create index if not exists idx_lotoccupancycomments_datetime on LotOccupancyComments (lotOccupancyId, lotOccupancyCommentDate, lotOccupancyCommentTime)',
// Fees and Transactions // Fees and Transactions
`create table if not exists FeeCategories (feeCategoryId integer not null primary key autoincrement, feeCategory varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`, `create table if not exists FeeCategories (feeCategoryId integer not null primary key autoincrement, feeCategory varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`,
`create table if not exists Fees (feeId integer not null primary key autoincrement, feeCategoryId integer not null, feeName varchar(100) not null, feeDescription text, occupancyTypeId integer, lotTypeId integer, includeQuantity boolean not null default 0, quantityUnit varchar(30), feeAmount decimal(8, 2), feeFunction varchar(100), taxAmount decimal(6, 2), taxPercentage decimal(5, 2), isRequired bit not null default 0, orderNumber smallint not null default 0, ${recordColumns}, foreign key (feeCategoryId) references FeeCategories (feeCategoryId), foreign key (occupancyTypeId) references OccupancyTypes (occupancyTypeId), foreign key (lotTypeId) references LotTypes (lotTypeId))`, `create table if not exists Fees (feeId integer not null primary key autoincrement, feeCategoryId integer not null, feeName varchar(100) not null, feeDescription text, occupancyTypeId integer, lotTypeId integer, includeQuantity boolean not null default 0, quantityUnit varchar(30), feeAmount decimal(8, 2), feeFunction varchar(100), taxAmount decimal(6, 2), taxPercentage decimal(5, 2), isRequired bit not null default 0, orderNumber smallint not null default 0, ${recordColumns}, foreign key (feeCategoryId) references FeeCategories (feeCategoryId), foreign key (occupancyTypeId) references OccupancyTypes (occupancyTypeId), foreign key (lotTypeId) references LotTypes (lotTypeId))`,
`create index if not exists idx_fees_ordernumber on Fees (orderNumber, feeName)`, 'create index if not exists idx_fees_ordernumber on Fees (orderNumber, feeName)',
`create table if not exists LotOccupancyFees (lotOccupancyId integer not null, feeId integer not null, quantity decimal(4, 1) not null default 1, feeAmount decimal(8, 2) not null, taxAmount decmial(8, 2) not null, ${recordColumns}, primary key (lotOccupancyId, feeId), foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId), foreign key (feeId) references Fees (feeId)) without rowid`, `create table if not exists LotOccupancyFees (lotOccupancyId integer not null, feeId integer not null, quantity decimal(4, 1) not null default 1, feeAmount decimal(8, 2) not null, taxAmount decmial(8, 2) not null, ${recordColumns}, primary key (lotOccupancyId, feeId), foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId), foreign key (feeId) references Fees (feeId)) without rowid`,
`create table if not exists LotOccupancyTransactions (lotOccupancyId integer not null, transactionIndex integer not null, transactionDate integer not null check (transactionDate > 0), transactionTime integer not null check (transactionTime >= 0), transactionAmount decimal(8, 2) not null, externalReceiptNumber varchar(100), transactionNote text, ${recordColumns}, primary key (lotOccupancyId, transactionIndex), foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId)) without rowid`, `create table if not exists LotOccupancyTransactions (lotOccupancyId integer not null, transactionIndex integer not null, transactionDate integer not null check (transactionDate > 0), transactionTime integer not null check (transactionTime >= 0), transactionAmount decimal(8, 2) not null, externalReceiptNumber varchar(100), transactionNote text, ${recordColumns}, primary key (lotOccupancyId, transactionIndex), foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId)) without rowid`,
`create index if not exists idx_lotoccupancytransactions_ordernumber on LotOccupancyTransactions (lotOccupancyId, transactionDate, transactionTime)`, 'create index if not exists idx_lotoccupancytransactions_ordernumber on LotOccupancyTransactions (lotOccupancyId, transactionDate, transactionTime)',
// Work Orders // Work Orders
`create table if not exists WorkOrderTypes (workOrderTypeId integer not null primary key autoincrement, workOrderType varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`, `create table if not exists WorkOrderTypes (workOrderTypeId integer not null primary key autoincrement, workOrderType varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`,
`create index if not exists idx_workordertypes_ordernumber on WorkOrderTypes (orderNumber, workOrderType)`, 'create index if not exists idx_workordertypes_ordernumber on WorkOrderTypes (orderNumber, workOrderType)',
`create table if not exists WorkOrders (workOrderId integer not null primary key autoincrement, workOrderTypeId integer not null, workOrderNumber varchar(50) not null, workOrderDescription text, workOrderOpenDate integer check (workOrderOpenDate > 0), workOrderCloseDate integer check (workOrderCloseDate > 0), ${recordColumns}, foreign key (workOrderTypeId) references WorkOrderTypes (workOrderTypeId))`, `create table if not exists WorkOrders (workOrderId integer not null primary key autoincrement, workOrderTypeId integer not null, workOrderNumber varchar(50) not null, workOrderDescription text, workOrderOpenDate integer check (workOrderOpenDate > 0), workOrderCloseDate integer check (workOrderCloseDate > 0), ${recordColumns}, foreign key (workOrderTypeId) references WorkOrderTypes (workOrderTypeId))`,
`create table if not exists WorkOrderLots (workOrderId integer not null, lotId integer not null, ${recordColumns}, primary key (workOrderId, lotId), foreign key (workOrderId) references WorkOrders (workOrderId), foreign key (lotId) references Lots (lotId)) without rowid`, `create table if not exists WorkOrderLots (workOrderId integer not null, lotId integer not null, ${recordColumns}, primary key (workOrderId, lotId), foreign key (workOrderId) references WorkOrders (workOrderId), foreign key (lotId) references Lots (lotId)) without rowid`,
`create table if not exists WorkOrderLotOccupancies (workOrderId integer not null, lotOccupancyId integer not null, ${recordColumns}, primary key (workOrderId, lotOccupancyId), foreign key (workOrderId) references WorkOrders (workOrderId), foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId)) without rowid`, `create table if not exists WorkOrderLotOccupancies (workOrderId integer not null, lotOccupancyId integer not null, ${recordColumns}, primary key (workOrderId, lotOccupancyId), foreign key (workOrderId) references WorkOrders (workOrderId), foreign key (lotOccupancyId) references LotOccupancies (lotOccupancyId)) without rowid`,
`create table if not exists WorkOrderComments (workOrderCommentId integer not null primary key autoincrement, workOrderId integer not null, workOrderCommentDate integer not null check (workOrderCommentDate > 0), workOrderCommentTime integer not null check (workOrderCommentTime >= 0), workOrderComment text not null, ${recordColumns}, foreign key (workOrderId) references WorkOrders (workOrderId))`, `create table if not exists WorkOrderComments (workOrderCommentId integer not null primary key autoincrement, workOrderId integer not null, workOrderCommentDate integer not null check (workOrderCommentDate > 0), workOrderCommentTime integer not null check (workOrderCommentTime >= 0), workOrderComment text not null, ${recordColumns}, foreign key (workOrderId) references WorkOrders (workOrderId))`,
`create index if not exists idx_workordercomments_datetime on WorkOrderComments (workOrderId, workOrderCommentDate, workOrderCommentTime)`, 'create index if not exists idx_workordercomments_datetime on WorkOrderComments (workOrderId, workOrderCommentDate, workOrderCommentTime)',
`create table if not exists WorkOrderMilestoneTypes (workOrderMilestoneTypeId integer not null primary key autoincrement, workOrderMilestoneType varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`, `create table if not exists WorkOrderMilestoneTypes (workOrderMilestoneTypeId integer not null primary key autoincrement, workOrderMilestoneType varchar(100) not null, orderNumber smallint not null default 0, ${recordColumns})`,
`create table if not exists WorkOrderMilestones (workOrderMilestoneId integer not null primary key autoincrement, workOrderId integer not null, workOrderMilestoneTypeId integer, workOrderMilestoneDate integer not null check (workOrderMilestoneDate > 0), workOrderMilestoneTime integer not null check (workOrderMilestoneTime >= 0), workOrderMilestoneDescription text not null, workOrderMilestoneCompletionDate integer check (workOrderMilestoneCompletionDate > 0), workOrderMilestoneCompletionTime integer check (workOrderMilestoneCompletionTime >= 0), ${recordColumns}, foreign key (workOrderId) references WorkOrders (workOrderId), foreign key (workOrderMilestoneTypeId) references WorkOrderMilestoneTypes (workOrderMilestoneTypeId))` `create table if not exists WorkOrderMilestones (workOrderMilestoneId integer not null primary key autoincrement, workOrderId integer not null, workOrderMilestoneTypeId integer, workOrderMilestoneDate integer not null check (workOrderMilestoneDate > 0), workOrderMilestoneTime integer not null check (workOrderMilestoneTime >= 0), workOrderMilestoneDescription text not null, workOrderMilestoneCompletionDate integer check (workOrderMilestoneCompletionDate > 0), workOrderMilestoneCompletionTime integer check (workOrderMilestoneCompletionTime >= 0), ${recordColumns}, foreign key (workOrderId) references WorkOrders (workOrderId), foreign key (workOrderMilestoneTypeId) references WorkOrderMilestoneTypes (workOrderMilestoneTypeId))`
]; ]
export function initializeDatabase(): boolean { export function initializeDatabase(): boolean {
const lotOccupancyDB = sqlite(databasePath); const lotOccupancyDB = sqlite(databasePath)
const row = lotOccupancyDB const row = lotOccupancyDB
.prepare("select name from sqlite_master where type = 'table' and name = 'WorkOrderMilestones'") .prepare(
.get(); "select name from sqlite_master where type = 'table' and name = 'WorkOrderMilestones'"
)
.get()
if (!row) { if (!row) {
debugSQL("Creating " + databasePath); debugSQL('Creating ' + databasePath)
for (const sql of createStatements) { for (const sql of createStatements) {
lotOccupancyDB.prepare(sql).run(); lotOccupancyDB.prepare(sql).run()
} }
lotOccupancyDB.close(); lotOccupancyDB.close()
return true; return true
} }
return false; return false
} }

View File

@ -1,3 +1,3 @@
import type * as recordTypes from "../../types/recordTypes"; import type * as recordTypes from '../../types/recordTypes';
export declare function getOccupancyTypes(): recordTypes.OccupancyType[]; export declare function getOccupancyTypes(): recordTypes.OccupancyType[];
export default getOccupancyTypes; export default getOccupancyTypes;

View File

@ -1,8 +1,8 @@
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';
import { getOccupancyTypeFields } from "./getOccupancyTypeFields.js"; import { getOccupancyTypeFields } from './getOccupancyTypeFields.js';
import { getOccupancyTypePrints } from "./getOccupancyTypePrints.js"; import { getOccupancyTypePrints } from './getOccupancyTypePrints.js';
import { updateRecordOrderNumber } from "./updateRecordOrderNumber.js"; import { updateRecordOrderNumber } from './updateRecordOrderNumber.js';
export function getOccupancyTypes() { export function getOccupancyTypes() {
const database = sqlite(databasePath); const database = sqlite(databasePath);
const occupancyTypes = database const occupancyTypes = database
@ -15,7 +15,7 @@ export function getOccupancyTypes() {
for (const occupancyType of occupancyTypes) { for (const occupancyType of occupancyTypes) {
expectedTypeOrderNumber += 1; expectedTypeOrderNumber += 1;
if (occupancyType.orderNumber !== expectedTypeOrderNumber) { if (occupancyType.orderNumber !== expectedTypeOrderNumber) {
updateRecordOrderNumber("OccupancyTypes", occupancyType.occupancyTypeId, expectedTypeOrderNumber, database); updateRecordOrderNumber('OccupancyTypes', occupancyType.occupancyTypeId, expectedTypeOrderNumber, database);
occupancyType.orderNumber = expectedTypeOrderNumber; occupancyType.orderNumber = expectedTypeOrderNumber;
} }
occupancyType.occupancyTypeFields = getOccupancyTypeFields(occupancyType.occupancyTypeId, database); occupancyType.occupancyTypeFields = getOccupancyTypeFields(occupancyType.occupancyTypeId, database);

View File

@ -1,15 +1,15 @@
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'
import { getOccupancyTypeFields } from "./getOccupancyTypeFields.js"; import { getOccupancyTypeFields } from './getOccupancyTypeFields.js'
import { getOccupancyTypePrints } from "./getOccupancyTypePrints.js"; import { getOccupancyTypePrints } from './getOccupancyTypePrints.js'
import type * as recordTypes from "../../types/recordTypes"; import type * as recordTypes from '../../types/recordTypes'
import { updateRecordOrderNumber } from "./updateRecordOrderNumber.js"; import { updateRecordOrderNumber } from './updateRecordOrderNumber.js'
export function getOccupancyTypes(): recordTypes.OccupancyType[] { export function getOccupancyTypes(): recordTypes.OccupancyType[] {
const database = sqlite(databasePath); const database = sqlite(databasePath)
const occupancyTypes: recordTypes.OccupancyType[] = database const occupancyTypes: recordTypes.OccupancyType[] = database
.prepare( .prepare(
@ -18,32 +18,38 @@ export function getOccupancyTypes(): recordTypes.OccupancyType[] {
where recordDelete_timeMillis is null where recordDelete_timeMillis is null
order by orderNumber, occupancyType` order by orderNumber, occupancyType`
) )
.all(); .all()
let expectedTypeOrderNumber = -1; let expectedTypeOrderNumber = -1
for (const occupancyType of occupancyTypes) { for (const occupancyType of occupancyTypes) {
expectedTypeOrderNumber += 1; expectedTypeOrderNumber += 1
if (occupancyType.orderNumber !== expectedTypeOrderNumber) { if (occupancyType.orderNumber !== expectedTypeOrderNumber) {
updateRecordOrderNumber( updateRecordOrderNumber(
"OccupancyTypes", 'OccupancyTypes',
occupancyType.occupancyTypeId, occupancyType.occupancyTypeId,
expectedTypeOrderNumber, expectedTypeOrderNumber,
database database
); )
occupancyType.orderNumber = expectedTypeOrderNumber; occupancyType.orderNumber = expectedTypeOrderNumber
} }
occupancyType.occupancyTypeFields = getOccupancyTypeFields(occupancyType.occupancyTypeId, database); occupancyType.occupancyTypeFields = getOccupancyTypeFields(
occupancyType.occupancyTypeId,
database
)
occupancyType.occupancyTypePrints = getOccupancyTypePrints(occupancyType.occupancyTypeId, database); occupancyType.occupancyTypePrints = getOccupancyTypePrints(
occupancyType.occupancyTypeId,
database
)
} }
database.close(); database.close()
return occupancyTypes; return occupancyTypes
} }
export default getOccupancyTypes; export default getOccupancyTypes

View File

@ -1,11 +1,11 @@
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';
import * as configFunctions from "../functions.config.js"; import * as configFunctions from '../functions.config.js';
export function getPreviousLotId(lotId) { export function getPreviousLotId(lotId) {
const database = sqlite(databasePath, { const database = sqlite(databasePath, {
readonly: true readonly: true
}); });
database.function("userFn_lotNameSortName", configFunctions.getProperty("settings.lot.lotNameSortNameFunction")); database.function('userFn_lotNameSortName', configFunctions.getProperty('settings.lot.lotNameSortNameFunction'));
const result = database const result = database
.prepare(`select lotId from Lots .prepare(`select lotId from Lots
where recordDelete_timeMillis is null where recordDelete_timeMillis is null

View File

@ -1,21 +1,21 @@
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'
import * as configFunctions from "../functions.config.js"; import * as configFunctions from '../functions.config.js'
export function getPreviousLotId(lotId: number | string): number | undefined { export function getPreviousLotId(lotId: number | string): number | undefined {
const database = sqlite(databasePath, { const database = sqlite(databasePath, {
readonly: true readonly: true
}); })
database.function( database.function(
"userFn_lotNameSortName", 'userFn_lotNameSortName',
configFunctions.getProperty("settings.lot.lotNameSortNameFunction") configFunctions.getProperty('settings.lot.lotNameSortNameFunction')
); )
const result: { const result: {
lotId: number; lotId: number
} = database } = database
.prepare( .prepare(
`select lotId from Lots `select lotId from Lots
@ -24,15 +24,15 @@ export function getPreviousLotId(lotId: number | string): number | undefined {
order by userFn_lotNameSortName(lotName) desc order by userFn_lotNameSortName(lotName) desc
limit 1` limit 1`
) )
.get(lotId); .get(lotId)
database.close(); database.close()
if (result) { if (result) {
return result.lotId; return result.lotId
} }
return undefined; return undefined
} }
export default getPreviousLotId; export default getPreviousLotId

View File

@ -1,5 +1,5 @@
import sqlite from "better-sqlite3"; import sqlite from 'better-sqlite3';
import type * as recordTypes from "../../types/recordTypes"; import type * as recordTypes from '../../types/recordTypes';
interface WorkOrderOptions { interface WorkOrderOptions {
includeLotsAndLotOccupancies: boolean; includeLotsAndLotOccupancies: boolean;
includeComments: boolean; includeComments: boolean;

View File

@ -1,10 +1,10 @@
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';
import { dateIntegerToString } from "@cityssm/expressjs-server-js/dateTimeFns.js"; import { dateIntegerToString } from '@cityssm/expressjs-server-js/dateTimeFns.js';
import { getLots } from "./getLots.js"; import { getLots } from './getLots.js';
import { getLotOccupancies } from "./getLotOccupancies.js"; import { getLotOccupancies } from './getLotOccupancies.js';
import { getWorkOrderComments } from "./getWorkOrderComments.js"; import { getWorkOrderComments } from './getWorkOrderComments.js';
import { getWorkOrderMilestones } from "./getWorkOrderMilestones.js"; import { getWorkOrderMilestones } from './getWorkOrderMilestones.js';
const baseSQL = `select w.workOrderId, const baseSQL = `select w.workOrderId,
w.workOrderTypeId, t.workOrderType, w.workOrderTypeId, t.workOrderType,
w.workOrderNumber, w.workOrderDescription, w.workOrderNumber, w.workOrderDescription,
@ -14,15 +14,15 @@ const baseSQL = `select w.workOrderId,
from WorkOrders w from WorkOrders w
left join WorkOrderTypes t on w.workOrderTypeId = t.workOrderTypeId left join WorkOrderTypes t on w.workOrderTypeId = t.workOrderTypeId
where w.recordDelete_timeMillis is null`; where w.recordDelete_timeMillis is null`;
function _getWorkOrder(sql, workOrderId_or_workOrderNumber, options, connectedDatabase) { function _getWorkOrder(sql, workOrderIdOrWorkOrderNumber, options, connectedDatabase) {
const database = connectedDatabase || const database = connectedDatabase ??
sqlite(databasePath, { sqlite(databasePath, {
readonly: true readonly: true
}); });
database.function("userFn_dateIntegerToString", dateIntegerToString); database.function('userFn_dateIntegerToString', dateIntegerToString);
const workOrder = database const workOrder = database
.prepare(sql) .prepare(sql)
.get(workOrderId_or_workOrderNumber); .get(workOrderIdOrWorkOrderNumber);
if (workOrder) { if (workOrder) {
if (options.includeLotsAndLotOccupancies) { if (options.includeLotsAndLotOccupancies) {
workOrder.workOrderLots = getLots({ workOrder.workOrderLots = getLots({
@ -47,7 +47,7 @@ function _getWorkOrder(sql, workOrderId_or_workOrderNumber, options, connectedDa
workOrderId: workOrder.workOrderId workOrderId: workOrder.workOrderId
}, { }, {
includeWorkOrders: false, includeWorkOrders: false,
orderBy: "completion" orderBy: 'completion'
}, database); }, database);
} }
} }
@ -57,13 +57,13 @@ function _getWorkOrder(sql, workOrderId_or_workOrderNumber, options, connectedDa
return workOrder; return workOrder;
} }
export function getWorkOrderByWorkOrderNumber(workOrderNumber) { export function getWorkOrderByWorkOrderNumber(workOrderNumber) {
return _getWorkOrder(baseSQL + " and w.workOrderNumber = ?", workOrderNumber, { return _getWorkOrder(baseSQL + ' and w.workOrderNumber = ?', workOrderNumber, {
includeLotsAndLotOccupancies: true, includeLotsAndLotOccupancies: true,
includeComments: true, includeComments: true,
includeMilestones: true includeMilestones: true
}); });
} }
export function getWorkOrder(workOrderId, options, connectedDatabase) { export function getWorkOrder(workOrderId, options, connectedDatabase) {
return _getWorkOrder(baseSQL + " and w.workOrderId = ?", workOrderId, options, connectedDatabase); return _getWorkOrder(baseSQL + ' and w.workOrderId = ?', workOrderId, options, connectedDatabase);
} }
export default getWorkOrder; export default getWorkOrder;

View File

@ -1,23 +1,23 @@
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'
import { dateIntegerToString } from "@cityssm/expressjs-server-js/dateTimeFns.js"; import { dateIntegerToString } from '@cityssm/expressjs-server-js/dateTimeFns.js'
import { getLots } from "./getLots.js"; import { getLots } from './getLots.js'
import { getLotOccupancies } from "./getLotOccupancies.js"; import { getLotOccupancies } from './getLotOccupancies.js'
import { getWorkOrderComments } from "./getWorkOrderComments.js"; import { getWorkOrderComments } from './getWorkOrderComments.js'
import { getWorkOrderMilestones } from "./getWorkOrderMilestones.js"; import { getWorkOrderMilestones } from './getWorkOrderMilestones.js'
import type * as recordTypes from "../../types/recordTypes"; import type * as recordTypes from '../../types/recordTypes'
interface WorkOrderOptions { interface WorkOrderOptions {
includeLotsAndLotOccupancies: boolean; includeLotsAndLotOccupancies: boolean
includeComments: boolean; includeComments: boolean
includeMilestones: boolean; includeMilestones: boolean
} }
const baseSQL = `select w.workOrderId, const baseSQL = `select w.workOrderId,
@ -28,25 +28,25 @@ const baseSQL = `select w.workOrderId,
w.recordCreate_timeMillis, w.recordUpdate_timeMillis w.recordCreate_timeMillis, w.recordUpdate_timeMillis
from WorkOrders w from WorkOrders w
left join WorkOrderTypes t on w.workOrderTypeId = t.workOrderTypeId left join WorkOrderTypes t on w.workOrderTypeId = t.workOrderTypeId
where w.recordDelete_timeMillis is null`; where w.recordDelete_timeMillis is null`
function _getWorkOrder( function _getWorkOrder(
sql: string, sql: string,
workOrderId_or_workOrderNumber: number | string, workOrderIdOrWorkOrderNumber: number | string,
options: WorkOrderOptions, options: WorkOrderOptions,
connectedDatabase?: sqlite.Database connectedDatabase?: sqlite.Database
): recordTypes.WorkOrder { ): recordTypes.WorkOrder {
const database = const database =
connectedDatabase || connectedDatabase ??
sqlite(databasePath, { sqlite(databasePath, {
readonly: true readonly: true
}); })
database.function("userFn_dateIntegerToString", dateIntegerToString); database.function('userFn_dateIntegerToString', dateIntegerToString)
const workOrder: recordTypes.WorkOrder = database const workOrder: recordTypes.WorkOrder = database
.prepare(sql) .prepare(sql)
.get(workOrderId_or_workOrderNumber); .get(workOrderIdOrWorkOrderNumber)
if (workOrder) { if (workOrder) {
if (options.includeLotsAndLotOccupancies) { if (options.includeLotsAndLotOccupancies) {
@ -59,7 +59,7 @@ function _getWorkOrder(
offset: 0 offset: 0
}, },
database database
).lots; ).lots
workOrder.workOrderLotOccupancies = getLotOccupancies( workOrder.workOrderLotOccupancies = getLotOccupancies(
{ {
@ -71,14 +71,14 @@ function _getWorkOrder(
includeOccupants: true includeOccupants: true
}, },
database database
).lotOccupancies; ).lotOccupancies
} }
if (options.includeComments) { if (options.includeComments) {
workOrder.workOrderComments = getWorkOrderComments( workOrder.workOrderComments = getWorkOrderComments(
workOrder.workOrderId as number, workOrder.workOrderId as number,
database database
); )
} }
if (options.includeMilestones) { if (options.includeMilestones) {
@ -88,26 +88,32 @@ function _getWorkOrder(
}, },
{ {
includeWorkOrders: false, includeWorkOrders: false,
orderBy: "completion" orderBy: 'completion'
}, },
database database
); )
} }
} }
if (!connectedDatabase) { if (!connectedDatabase) {
database.close(); database.close()
} }
return workOrder; return workOrder
} }
export function getWorkOrderByWorkOrderNumber(workOrderNumber: string): recordTypes.WorkOrder { export function getWorkOrderByWorkOrderNumber(
return _getWorkOrder(baseSQL + " and w.workOrderNumber = ?", workOrderNumber, { workOrderNumber: string
): recordTypes.WorkOrder {
return _getWorkOrder(
baseSQL + ' and w.workOrderNumber = ?',
workOrderNumber,
{
includeLotsAndLotOccupancies: true, includeLotsAndLotOccupancies: true,
includeComments: true, includeComments: true,
includeMilestones: true includeMilestones: true
}); }
)
} }
export function getWorkOrder( export function getWorkOrder(
@ -116,11 +122,11 @@ export function getWorkOrder(
connectedDatabase?: sqlite.Database connectedDatabase?: sqlite.Database
): recordTypes.WorkOrder { ): recordTypes.WorkOrder {
return _getWorkOrder( return _getWorkOrder(
baseSQL + " and w.workOrderId = ?", baseSQL + ' and w.workOrderId = ?',
workOrderId, workOrderId,
options, options,
connectedDatabase connectedDatabase
); )
} }
export default getWorkOrder; export default getWorkOrder

View File

@ -1,4 +1,4 @@
import sqlite from "better-sqlite3"; import sqlite from 'better-sqlite3';
import type * as recordTypes from "../../types/recordTypes"; import type * as recordTypes from '../../types/recordTypes';
export declare function getWorkOrderComments(workOrderId: number | string, connectedDatabase?: sqlite.Database): recordTypes.WorkOrderComment[]; export declare function getWorkOrderComments(workOrderId: number | string, connectedDatabase?: sqlite.Database): recordTypes.WorkOrderComment[];
export default getWorkOrderComments; export default getWorkOrderComments;

View File

@ -1,13 +1,13 @@
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';
import { dateIntegerToString, timeIntegerToString } from "@cityssm/expressjs-server-js/dateTimeFns.js"; import { dateIntegerToString, timeIntegerToString } from '@cityssm/expressjs-server-js/dateTimeFns.js';
export function getWorkOrderComments(workOrderId, connectedDatabase) { export function getWorkOrderComments(workOrderId, connectedDatabase) {
const database = connectedDatabase || const database = connectedDatabase ??
sqlite(databasePath, { sqlite(databasePath, {
readonly: true readonly: true
}); });
database.function("userFn_dateIntegerToString", dateIntegerToString); database.function('userFn_dateIntegerToString', dateIntegerToString);
database.function("userFn_timeIntegerToString", timeIntegerToString); database.function('userFn_timeIntegerToString', timeIntegerToString);
const workOrderComments = database const workOrderComments = database
.prepare(`select workOrderCommentId, .prepare(`select workOrderCommentId,
workOrderCommentDate, userFn_dateIntegerToString(workOrderCommentDate) as workOrderCommentDateString, workOrderCommentDate, userFn_dateIntegerToString(workOrderCommentDate) as workOrderCommentDateString,

View File

@ -1,26 +1,26 @@
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'
import { import {
dateIntegerToString, dateIntegerToString,
timeIntegerToString timeIntegerToString
} from "@cityssm/expressjs-server-js/dateTimeFns.js"; } from '@cityssm/expressjs-server-js/dateTimeFns.js'
import type * as recordTypes from "../../types/recordTypes"; import type * as recordTypes from '../../types/recordTypes'
export function getWorkOrderComments( export function getWorkOrderComments(
workOrderId: number | string, workOrderId: number | string,
connectedDatabase?: sqlite.Database connectedDatabase?: sqlite.Database
): recordTypes.WorkOrderComment[] { ): recordTypes.WorkOrderComment[] {
const database = const database =
connectedDatabase || connectedDatabase ??
sqlite(databasePath, { sqlite(databasePath, {
readonly: true readonly: true
}); })
database.function("userFn_dateIntegerToString", dateIntegerToString); database.function('userFn_dateIntegerToString', dateIntegerToString)
database.function("userFn_timeIntegerToString", timeIntegerToString); database.function('userFn_timeIntegerToString', timeIntegerToString)
const workOrderComments = database const workOrderComments = database
.prepare( .prepare(
@ -34,13 +34,13 @@ export function getWorkOrderComments(
and workOrderId = ? and workOrderId = ?
order by workOrderCommentDate desc, workOrderCommentTime desc, workOrderCommentId desc` order by workOrderCommentDate desc, workOrderCommentTime desc, workOrderCommentId desc`
) )
.all(workOrderId); .all(workOrderId)
if (!connectedDatabase) { if (!connectedDatabase) {
database.close(); database.close()
} }
return workOrderComments; return workOrderComments
} }
export default getWorkOrderComments; export default getWorkOrderComments

View File

@ -1,3 +1,3 @@
import type * as recordTypes from "../../types/recordTypes"; import type * as recordTypes from '../../types/recordTypes';
export declare function getWorkOrderMilestoneTypes(): recordTypes.WorkOrderMilestoneType[]; export declare function getWorkOrderMilestoneTypes(): recordTypes.WorkOrderMilestoneType[];
export default getWorkOrderMilestoneTypes; export default getWorkOrderMilestoneTypes;

View File

@ -1,6 +1,6 @@
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';
import { updateRecordOrderNumber } from "./updateRecordOrderNumber.js"; import { updateRecordOrderNumber } from './updateRecordOrderNumber.js';
export function getWorkOrderMilestoneTypes() { export function getWorkOrderMilestoneTypes() {
const database = sqlite(databasePath); const database = sqlite(databasePath);
const workOrderMilestoneTypes = database const workOrderMilestoneTypes = database
@ -12,7 +12,7 @@ export function getWorkOrderMilestoneTypes() {
let expectedOrderNumber = 0; let expectedOrderNumber = 0;
for (const workOrderMilestoneType of workOrderMilestoneTypes) { for (const workOrderMilestoneType of workOrderMilestoneTypes) {
if (workOrderMilestoneType.orderNumber !== expectedOrderNumber) { if (workOrderMilestoneType.orderNumber !== expectedOrderNumber) {
updateRecordOrderNumber("WorkOrderMilestoneTypes", workOrderMilestoneType.workOrderMilestoneTypeId, expectedOrderNumber, database); updateRecordOrderNumber('WorkOrderMilestoneTypes', workOrderMilestoneType.workOrderMilestoneTypeId, expectedOrderNumber, database);
workOrderMilestoneType.orderNumber = expectedOrderNumber; workOrderMilestoneType.orderNumber = expectedOrderNumber;
} }
expectedOrderNumber += 1; expectedOrderNumber += 1;

View File

@ -1,13 +1,13 @@
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'
import { updateRecordOrderNumber } from "./updateRecordOrderNumber.js"; import { updateRecordOrderNumber } from './updateRecordOrderNumber.js'
import type * as recordTypes from "../../types/recordTypes"; import type * as recordTypes from '../../types/recordTypes'
export function getWorkOrderMilestoneTypes(): recordTypes.WorkOrderMilestoneType[] { export function getWorkOrderMilestoneTypes(): recordTypes.WorkOrderMilestoneType[] {
const database = sqlite(databasePath); const database = sqlite(databasePath)
const workOrderMilestoneTypes: recordTypes.WorkOrderMilestoneType[] = database const workOrderMilestoneTypes: recordTypes.WorkOrderMilestoneType[] = database
.prepare( .prepare(
@ -16,28 +16,28 @@ export function getWorkOrderMilestoneTypes(): recordTypes.WorkOrderMilestoneType
where recordDelete_timeMillis is null where recordDelete_timeMillis is null
order by orderNumber, workOrderMilestoneType` order by orderNumber, workOrderMilestoneType`
) )
.all(); .all()
let expectedOrderNumber = 0; let expectedOrderNumber = 0
for (const workOrderMilestoneType of workOrderMilestoneTypes) { for (const workOrderMilestoneType of workOrderMilestoneTypes) {
if (workOrderMilestoneType.orderNumber !== expectedOrderNumber) { if (workOrderMilestoneType.orderNumber !== expectedOrderNumber) {
updateRecordOrderNumber( updateRecordOrderNumber(
"WorkOrderMilestoneTypes", 'WorkOrderMilestoneTypes',
workOrderMilestoneType.workOrderMilestoneTypeId, workOrderMilestoneType.workOrderMilestoneTypeId,
expectedOrderNumber, expectedOrderNumber,
database database
); )
workOrderMilestoneType.orderNumber = expectedOrderNumber; workOrderMilestoneType.orderNumber = expectedOrderNumber
} }
expectedOrderNumber += 1; expectedOrderNumber += 1
} }
database.close(); database.close()
return workOrderMilestoneTypes; return workOrderMilestoneTypes
} }
export default getWorkOrderMilestoneTypes; export default getWorkOrderMilestoneTypes

View File

@ -1,15 +1,15 @@
import sqlite from "better-sqlite3"; import sqlite from 'better-sqlite3';
import type * as recordTypes from "../../types/recordTypes"; import type * as recordTypes from '../../types/recordTypes';
export interface WorkOrderMilestoneFilters { export interface WorkOrderMilestoneFilters {
workOrderId?: number | string; workOrderId?: number | string;
workOrderMilestoneDateFilter?: "upcomingMissed" | "recent" | "date"; workOrderMilestoneDateFilter?: 'upcomingMissed' | 'recent' | 'date';
workOrderMilestoneDateString?: string; workOrderMilestoneDateString?: string;
workOrderTypeIds?: string; workOrderTypeIds?: string;
workOrderMilestoneTypeIds?: string; workOrderMilestoneTypeIds?: string;
} }
interface WorkOrderMilestoneOptions { interface WorkOrderMilestoneOptions {
includeWorkOrders?: boolean; includeWorkOrders?: boolean;
orderBy: "completion" | "date"; orderBy: 'completion' | 'date';
} }
export declare function getWorkOrderMilestones(filters: WorkOrderMilestoneFilters, options: WorkOrderMilestoneOptions, connectedDatabase?: sqlite.Database): recordTypes.WorkOrderMilestone[]; export declare function getWorkOrderMilestones(filters: WorkOrderMilestoneFilters, options: WorkOrderMilestoneOptions, connectedDatabase?: sqlite.Database): recordTypes.WorkOrderMilestone[];
export default getWorkOrderMilestones; export default getWorkOrderMilestones;

View File

@ -1,49 +1,55 @@
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';
import { dateIntegerToString, dateStringToInteger, dateToInteger, timeIntegerToString } from "@cityssm/expressjs-server-js/dateTimeFns.js"; import { dateIntegerToString, dateStringToInteger, dateToInteger, timeIntegerToString } from '@cityssm/expressjs-server-js/dateTimeFns.js';
import * as configFunctions from "../functions.config.js"; import * as configFunctions from '../functions.config.js';
import { getLots } from "./getLots.js"; import { getLots } from './getLots.js';
import { getLotOccupancies } from "./getLotOccupancies.js"; import { getLotOccupancies } from './getLotOccupancies.js';
const commaSeparatedNumbersRegex = /^\d+(,\d+)*$/; const commaSeparatedNumbersRegex = /^\d+(,\d+)*$/;
function buildWhereClause(filters) { function buildWhereClause(filters) {
let sqlWhereClause = " where m.recordDelete_timeMillis is null and w.recordDelete_timeMillis is null"; let sqlWhereClause = ' where m.recordDelete_timeMillis is null and w.recordDelete_timeMillis is null';
const sqlParameters = []; const sqlParameters = [];
if (filters.workOrderId) { if (filters.workOrderId) {
sqlWhereClause += " and m.workOrderId = ?"; sqlWhereClause += ' and m.workOrderId = ?';
sqlParameters.push(filters.workOrderId); sqlParameters.push(filters.workOrderId);
} }
const date = new Date(); const date = new Date();
const currentDateNumber = dateToInteger(date); const currentDateNumber = dateToInteger(date);
date.setDate(date.getDate() - date.setDate(date.getDate() -
configFunctions.getProperty("settings.workOrders.workOrderMilestoneDateRecentBeforeDays")); configFunctions.getProperty('settings.workOrders.workOrderMilestoneDateRecentBeforeDays'));
const recentBeforeDateNumber = dateToInteger(date); const recentBeforeDateNumber = dateToInteger(date);
date.setDate(date.getDate() + date.setDate(date.getDate() +
configFunctions.getProperty("settings.workOrders.workOrderMilestoneDateRecentBeforeDays") + configFunctions.getProperty('settings.workOrders.workOrderMilestoneDateRecentBeforeDays') +
configFunctions.getProperty("settings.workOrders.workOrderMilestoneDateRecentAfterDays")); configFunctions.getProperty('settings.workOrders.workOrderMilestoneDateRecentAfterDays'));
const recentAfterDateNumber = dateToInteger(date); const recentAfterDateNumber = dateToInteger(date);
switch (filters.workOrderMilestoneDateFilter) { switch (filters.workOrderMilestoneDateFilter) {
case "upcomingMissed": { case 'upcomingMissed': {
sqlWhereClause += sqlWhereClause +=
" and (m.workOrderMilestoneCompletionDate is null or m.workOrderMilestoneDate >= ?)"; ' and (m.workOrderMilestoneCompletionDate is null or m.workOrderMilestoneDate >= ?)';
sqlParameters.push(currentDateNumber); sqlParameters.push(currentDateNumber);
break; break;
} }
case "recent": { case 'recent': {
sqlWhereClause += " and m.workOrderMilestoneDate >= ? and m.workOrderMilestoneDate <= ?"; sqlWhereClause +=
' and m.workOrderMilestoneDate >= ? and m.workOrderMilestoneDate <= ?';
sqlParameters.push(recentBeforeDateNumber, recentAfterDateNumber); sqlParameters.push(recentBeforeDateNumber, recentAfterDateNumber);
break; break;
} }
} }
if (filters.workOrderMilestoneDateString) { if (filters.workOrderMilestoneDateString) {
sqlWhereClause += " and m.workOrderMilestoneDate = ?"; sqlWhereClause += ' and m.workOrderMilestoneDate = ?';
sqlParameters.push(dateStringToInteger(filters.workOrderMilestoneDateString)); sqlParameters.push(dateStringToInteger(filters.workOrderMilestoneDateString));
} }
if (filters.workOrderTypeIds && commaSeparatedNumbersRegex.test(filters.workOrderTypeIds)) { if (filters.workOrderTypeIds &&
sqlWhereClause += " and w.workOrderTypeId in (" + filters.workOrderTypeIds + ")"; commaSeparatedNumbersRegex.test(filters.workOrderTypeIds)) {
sqlWhereClause +=
' and w.workOrderTypeId in (' + filters.workOrderTypeIds + ')';
} }
if (filters.workOrderMilestoneTypeIds && if (filters.workOrderMilestoneTypeIds &&
commaSeparatedNumbersRegex.test(filters.workOrderMilestoneTypeIds)) { commaSeparatedNumbersRegex.test(filters.workOrderMilestoneTypeIds)) {
sqlWhereClause += " and m.workOrderMilestoneTypeId in (" + filters.workOrderMilestoneTypeIds + ")"; sqlWhereClause +=
' and m.workOrderMilestoneTypeId in (' +
filters.workOrderMilestoneTypeIds +
')';
} }
return { return {
sqlWhereClause, sqlWhereClause,
@ -51,52 +57,54 @@ function buildWhereClause(filters) {
}; };
} }
export function getWorkOrderMilestones(filters, options, connectedDatabase) { export function getWorkOrderMilestones(filters, options, connectedDatabase) {
const database = connectedDatabase || const database = connectedDatabase ??
sqlite(databasePath, { sqlite(databasePath, {
readonly: true readonly: true
}); });
database.function("userFn_dateIntegerToString", dateIntegerToString); database.function('userFn_dateIntegerToString', dateIntegerToString);
database.function("userFn_timeIntegerToString", timeIntegerToString); database.function('userFn_timeIntegerToString', timeIntegerToString);
const { sqlWhereClause, sqlParameters } = buildWhereClause(filters); const { sqlWhereClause, sqlParameters } = buildWhereClause(filters);
let orderByClause = ""; let orderByClause = '';
switch (options.orderBy) { switch (options.orderBy) {
case "completion": { case 'completion': {
orderByClause = orderByClause =
" order by" + ' order by' +
" m.workOrderMilestoneCompletionDate, m.workOrderMilestoneCompletionTime," + ' m.workOrderMilestoneCompletionDate, m.workOrderMilestoneCompletionTime,' +
" m.workOrderMilestoneDate, case when m.workOrderMilestoneTime = 0 then 9999 else m.workOrderMilestoneTime end," + ' m.workOrderMilestoneDate, case when m.workOrderMilestoneTime = 0 then 9999 else m.workOrderMilestoneTime end,' +
" t.orderNumber, m.workOrderMilestoneId"; ' t.orderNumber, m.workOrderMilestoneId';
break; break;
} }
case "date": { case 'date': {
orderByClause = orderByClause =
" order by m.workOrderMilestoneDate, case when m.workOrderMilestoneTime = 0 then 9999 else m.workOrderMilestoneTime end," + ' order by m.workOrderMilestoneDate, case when m.workOrderMilestoneTime = 0 then 9999 else m.workOrderMilestoneTime end,' +
" t.orderNumber, m.workOrderId, m.workOrderMilestoneId"; ' t.orderNumber, m.workOrderId, m.workOrderMilestoneId';
break; break;
} }
} }
const sql = "select m.workOrderMilestoneId," + const sql = 'select m.workOrderMilestoneId,' +
" m.workOrderMilestoneTypeId, t.workOrderMilestoneType," + ' m.workOrderMilestoneTypeId, t.workOrderMilestoneType,' +
" m.workOrderMilestoneDate, userFn_dateIntegerToString(m.workOrderMilestoneDate) as workOrderMilestoneDateString," + ' m.workOrderMilestoneDate, userFn_dateIntegerToString(m.workOrderMilestoneDate) as workOrderMilestoneDateString,' +
" m.workOrderMilestoneTime, userFn_timeIntegerToString(m.workOrderMilestoneTime) as workOrderMilestoneTimeString," + ' m.workOrderMilestoneTime, userFn_timeIntegerToString(m.workOrderMilestoneTime) as workOrderMilestoneTimeString,' +
" m.workOrderMilestoneDescription," + ' m.workOrderMilestoneDescription,' +
" m.workOrderMilestoneCompletionDate, userFn_dateIntegerToString(m.workOrderMilestoneCompletionDate) as workOrderMilestoneCompletionDateString," + ' m.workOrderMilestoneCompletionDate, userFn_dateIntegerToString(m.workOrderMilestoneCompletionDate) as workOrderMilestoneCompletionDateString,' +
" m.workOrderMilestoneCompletionTime, userFn_timeIntegerToString(m.workOrderMilestoneCompletionTime) as workOrderMilestoneCompletionTimeString," + ' m.workOrderMilestoneCompletionTime, userFn_timeIntegerToString(m.workOrderMilestoneCompletionTime) as workOrderMilestoneCompletionTimeString,' +
(options.includeWorkOrders (options.includeWorkOrders
? " m.workOrderId, w.workOrderNumber, wt.workOrderType, w.workOrderDescription," + ? ' m.workOrderId, w.workOrderNumber, wt.workOrderType, w.workOrderDescription,' +
" w.workOrderOpenDate, userFn_dateIntegerToString(w.workOrderOpenDate) as workOrderOpenDateString," + ' w.workOrderOpenDate, userFn_dateIntegerToString(w.workOrderOpenDate) as workOrderOpenDateString,' +
" w.workOrderCloseDate, userFn_dateIntegerToString(w.workOrderCloseDate) as workOrderCloseDateString," + ' w.workOrderCloseDate, userFn_dateIntegerToString(w.workOrderCloseDate) as workOrderCloseDateString,' +
" w.recordUpdate_timeMillis as workOrderRecordUpdate_timeMillis," ' w.recordUpdate_timeMillis as workOrderRecordUpdate_timeMillis,'
: "") + : '') +
" m.recordCreate_userName, m.recordCreate_timeMillis," + ' m.recordCreate_userName, m.recordCreate_timeMillis,' +
" m.recordUpdate_userName, m.recordUpdate_timeMillis" + ' m.recordUpdate_userName, m.recordUpdate_timeMillis' +
" from WorkOrderMilestones m" + ' from WorkOrderMilestones m' +
" left join WorkOrderMilestoneTypes t on m.workOrderMilestoneTypeId = t.workOrderMilestoneTypeId" + ' left join WorkOrderMilestoneTypes t on m.workOrderMilestoneTypeId = t.workOrderMilestoneTypeId' +
" left join WorkOrders w on m.workOrderId = w.workOrderId" + ' left join WorkOrders w on m.workOrderId = w.workOrderId' +
" left join WorkOrderTypes wt on w.workOrderTypeId = wt.workOrderTypeId" + ' left join WorkOrderTypes wt on w.workOrderTypeId = wt.workOrderTypeId' +
sqlWhereClause + sqlWhereClause +
orderByClause; orderByClause;
const workOrderMilestones = database.prepare(sql).all(sqlParameters); const workOrderMilestones = database
.prepare(sql)
.all(sqlParameters);
if (options.includeWorkOrders) { if (options.includeWorkOrders) {
for (const workOrderMilestone of workOrderMilestones) { for (const workOrderMilestone of workOrderMilestones) {
workOrderMilestone.workOrderLots = getLots({ workOrderMilestone.workOrderLots = getLots({

View File

@ -1,101 +1,118 @@
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'
import { import {
dateIntegerToString, dateIntegerToString,
dateStringToInteger, dateStringToInteger,
dateToInteger, dateToInteger,
timeIntegerToString timeIntegerToString
} from "@cityssm/expressjs-server-js/dateTimeFns.js"; } from '@cityssm/expressjs-server-js/dateTimeFns.js'
import * as configFunctions from "../functions.config.js"; import * as configFunctions from '../functions.config.js'
import { getLots } from "./getLots.js"; import { getLots } from './getLots.js'
import { getLotOccupancies } from "./getLotOccupancies.js"; import { getLotOccupancies } from './getLotOccupancies.js'
import type * as recordTypes from "../../types/recordTypes"; import type * as recordTypes from '../../types/recordTypes'
export interface WorkOrderMilestoneFilters { export interface WorkOrderMilestoneFilters {
workOrderId?: number | string; workOrderId?: number | string
workOrderMilestoneDateFilter?: "upcomingMissed" | "recent" | "date"; workOrderMilestoneDateFilter?: 'upcomingMissed' | 'recent' | 'date'
workOrderMilestoneDateString?: string; workOrderMilestoneDateString?: string
workOrderTypeIds?: string; workOrderTypeIds?: string
workOrderMilestoneTypeIds?: string; workOrderMilestoneTypeIds?: string
} }
interface WorkOrderMilestoneOptions { interface WorkOrderMilestoneOptions {
includeWorkOrders?: boolean; includeWorkOrders?: boolean
orderBy: "completion" | "date"; orderBy: 'completion' | 'date'
} }
const commaSeparatedNumbersRegex = /^\d+(,\d+)*$/; const commaSeparatedNumbersRegex = /^\d+(,\d+)*$/
function buildWhereClause(filters: WorkOrderMilestoneFilters): { function buildWhereClause(filters: WorkOrderMilestoneFilters): {
sqlWhereClause: string; sqlWhereClause: string
sqlParameters: unknown[]; sqlParameters: unknown[]
} { } {
let sqlWhereClause = " where m.recordDelete_timeMillis is null and w.recordDelete_timeMillis is null"; let sqlWhereClause =
const sqlParameters: unknown[] = []; ' where m.recordDelete_timeMillis is null and w.recordDelete_timeMillis is null'
const sqlParameters: unknown[] = []
if (filters.workOrderId) { if (filters.workOrderId) {
sqlWhereClause += " and m.workOrderId = ?"; sqlWhereClause += ' and m.workOrderId = ?'
sqlParameters.push(filters.workOrderId); sqlParameters.push(filters.workOrderId)
} }
const date = new Date(); const date = new Date()
const currentDateNumber = dateToInteger(date); const currentDateNumber = dateToInteger(date)
date.setDate( date.setDate(
date.getDate() - date.getDate() -
configFunctions.getProperty("settings.workOrders.workOrderMilestoneDateRecentBeforeDays") configFunctions.getProperty(
); 'settings.workOrders.workOrderMilestoneDateRecentBeforeDays'
)
)
const recentBeforeDateNumber = dateToInteger(date); const recentBeforeDateNumber = dateToInteger(date)
date.setDate( date.setDate(
date.getDate() + date.getDate() +
configFunctions.getProperty("settings.workOrders.workOrderMilestoneDateRecentBeforeDays") + configFunctions.getProperty(
configFunctions.getProperty("settings.workOrders.workOrderMilestoneDateRecentAfterDays") 'settings.workOrders.workOrderMilestoneDateRecentBeforeDays'
); ) +
configFunctions.getProperty(
'settings.workOrders.workOrderMilestoneDateRecentAfterDays'
)
)
const recentAfterDateNumber = dateToInteger(date); const recentAfterDateNumber = dateToInteger(date)
switch (filters.workOrderMilestoneDateFilter) { switch (filters.workOrderMilestoneDateFilter) {
case "upcomingMissed": { case 'upcomingMissed': {
sqlWhereClause += sqlWhereClause +=
" and (m.workOrderMilestoneCompletionDate is null or m.workOrderMilestoneDate >= ?)"; ' and (m.workOrderMilestoneCompletionDate is null or m.workOrderMilestoneDate >= ?)'
sqlParameters.push(currentDateNumber); sqlParameters.push(currentDateNumber)
break; break
} }
case "recent": { case 'recent': {
sqlWhereClause += " and m.workOrderMilestoneDate >= ? and m.workOrderMilestoneDate <= ?"; sqlWhereClause +=
sqlParameters.push(recentBeforeDateNumber, recentAfterDateNumber); ' and m.workOrderMilestoneDate >= ? and m.workOrderMilestoneDate <= ?'
break; sqlParameters.push(recentBeforeDateNumber, recentAfterDateNumber)
break
} }
} }
if (filters.workOrderMilestoneDateString) { if (filters.workOrderMilestoneDateString) {
sqlWhereClause += " and m.workOrderMilestoneDate = ?"; sqlWhereClause += ' and m.workOrderMilestoneDate = ?'
sqlParameters.push(dateStringToInteger(filters.workOrderMilestoneDateString)); sqlParameters.push(
dateStringToInteger(filters.workOrderMilestoneDateString)
)
} }
if (filters.workOrderTypeIds && commaSeparatedNumbersRegex.test(filters.workOrderTypeIds)) { if (
sqlWhereClause += " and w.workOrderTypeId in (" + filters.workOrderTypeIds + ")"; filters.workOrderTypeIds &&
commaSeparatedNumbersRegex.test(filters.workOrderTypeIds)
) {
sqlWhereClause +=
' and w.workOrderTypeId in (' + filters.workOrderTypeIds + ')'
} }
if ( if (
filters.workOrderMilestoneTypeIds && filters.workOrderMilestoneTypeIds &&
commaSeparatedNumbersRegex.test(filters.workOrderMilestoneTypeIds) commaSeparatedNumbersRegex.test(filters.workOrderMilestoneTypeIds)
) { ) {
sqlWhereClause += " and m.workOrderMilestoneTypeId in (" + filters.workOrderMilestoneTypeIds + ")"; sqlWhereClause +=
' and m.workOrderMilestoneTypeId in (' +
filters.workOrderMilestoneTypeIds +
')'
} }
return { return {
sqlWhereClause, sqlWhereClause,
sqlParameters sqlParameters
}; }
} }
export function getWorkOrderMilestones( export function getWorkOrderMilestones(
@ -104,63 +121,65 @@ export function getWorkOrderMilestones(
connectedDatabase?: sqlite.Database connectedDatabase?: sqlite.Database
): recordTypes.WorkOrderMilestone[] { ): recordTypes.WorkOrderMilestone[] {
const database = const database =
connectedDatabase || connectedDatabase ??
sqlite(databasePath, { sqlite(databasePath, {
readonly: true readonly: true
}); })
database.function("userFn_dateIntegerToString", dateIntegerToString); database.function('userFn_dateIntegerToString', dateIntegerToString)
database.function("userFn_timeIntegerToString", timeIntegerToString); database.function('userFn_timeIntegerToString', timeIntegerToString)
// Filters // Filters
const { sqlWhereClause, sqlParameters } = buildWhereClause(filters); const { sqlWhereClause, sqlParameters } = buildWhereClause(filters)
// Order By // Order By
let orderByClause = ""; let orderByClause = ''
switch (options.orderBy) { switch (options.orderBy) {
case "completion": { case 'completion': {
orderByClause = orderByClause =
" order by" + ' order by' +
" m.workOrderMilestoneCompletionDate, m.workOrderMilestoneCompletionTime," + ' m.workOrderMilestoneCompletionDate, m.workOrderMilestoneCompletionTime,' +
" m.workOrderMilestoneDate, case when m.workOrderMilestoneTime = 0 then 9999 else m.workOrderMilestoneTime end," + ' m.workOrderMilestoneDate, case when m.workOrderMilestoneTime = 0 then 9999 else m.workOrderMilestoneTime end,' +
" t.orderNumber, m.workOrderMilestoneId"; ' t.orderNumber, m.workOrderMilestoneId'
break; break
} }
case "date": { case 'date': {
orderByClause = orderByClause =
" order by m.workOrderMilestoneDate, case when m.workOrderMilestoneTime = 0 then 9999 else m.workOrderMilestoneTime end," + ' order by m.workOrderMilestoneDate, case when m.workOrderMilestoneTime = 0 then 9999 else m.workOrderMilestoneTime end,' +
" t.orderNumber, m.workOrderId, m.workOrderMilestoneId"; ' t.orderNumber, m.workOrderId, m.workOrderMilestoneId'
break; break
} }
} }
// Query // Query
const sql = const sql =
"select m.workOrderMilestoneId," + 'select m.workOrderMilestoneId,' +
" m.workOrderMilestoneTypeId, t.workOrderMilestoneType," + ' m.workOrderMilestoneTypeId, t.workOrderMilestoneType,' +
" m.workOrderMilestoneDate, userFn_dateIntegerToString(m.workOrderMilestoneDate) as workOrderMilestoneDateString," + ' m.workOrderMilestoneDate, userFn_dateIntegerToString(m.workOrderMilestoneDate) as workOrderMilestoneDateString,' +
" m.workOrderMilestoneTime, userFn_timeIntegerToString(m.workOrderMilestoneTime) as workOrderMilestoneTimeString," + ' m.workOrderMilestoneTime, userFn_timeIntegerToString(m.workOrderMilestoneTime) as workOrderMilestoneTimeString,' +
" m.workOrderMilestoneDescription," + ' m.workOrderMilestoneDescription,' +
" m.workOrderMilestoneCompletionDate, userFn_dateIntegerToString(m.workOrderMilestoneCompletionDate) as workOrderMilestoneCompletionDateString," + ' m.workOrderMilestoneCompletionDate, userFn_dateIntegerToString(m.workOrderMilestoneCompletionDate) as workOrderMilestoneCompletionDateString,' +
" m.workOrderMilestoneCompletionTime, userFn_timeIntegerToString(m.workOrderMilestoneCompletionTime) as workOrderMilestoneCompletionTimeString," + ' m.workOrderMilestoneCompletionTime, userFn_timeIntegerToString(m.workOrderMilestoneCompletionTime) as workOrderMilestoneCompletionTimeString,' +
(options.includeWorkOrders (options.includeWorkOrders
? " m.workOrderId, w.workOrderNumber, wt.workOrderType, w.workOrderDescription," + ? ' m.workOrderId, w.workOrderNumber, wt.workOrderType, w.workOrderDescription,' +
" w.workOrderOpenDate, userFn_dateIntegerToString(w.workOrderOpenDate) as workOrderOpenDateString," + ' w.workOrderOpenDate, userFn_dateIntegerToString(w.workOrderOpenDate) as workOrderOpenDateString,' +
" w.workOrderCloseDate, userFn_dateIntegerToString(w.workOrderCloseDate) as workOrderCloseDateString," + ' w.workOrderCloseDate, userFn_dateIntegerToString(w.workOrderCloseDate) as workOrderCloseDateString,' +
" w.recordUpdate_timeMillis as workOrderRecordUpdate_timeMillis," ' w.recordUpdate_timeMillis as workOrderRecordUpdate_timeMillis,'
: "") + : '') +
" m.recordCreate_userName, m.recordCreate_timeMillis," + ' m.recordCreate_userName, m.recordCreate_timeMillis,' +
" m.recordUpdate_userName, m.recordUpdate_timeMillis" + ' m.recordUpdate_userName, m.recordUpdate_timeMillis' +
" from WorkOrderMilestones m" + ' from WorkOrderMilestones m' +
" left join WorkOrderMilestoneTypes t on m.workOrderMilestoneTypeId = t.workOrderMilestoneTypeId" + ' left join WorkOrderMilestoneTypes t on m.workOrderMilestoneTypeId = t.workOrderMilestoneTypeId' +
" left join WorkOrders w on m.workOrderId = w.workOrderId" + ' left join WorkOrders w on m.workOrderId = w.workOrderId' +
" left join WorkOrderTypes wt on w.workOrderTypeId = wt.workOrderTypeId" + ' left join WorkOrderTypes wt on w.workOrderTypeId = wt.workOrderTypeId' +
sqlWhereClause + sqlWhereClause +
orderByClause; orderByClause
const workOrderMilestones: recordTypes.WorkOrderMilestone[] = database.prepare(sql).all(sqlParameters); const workOrderMilestones: recordTypes.WorkOrderMilestone[] = database
.prepare(sql)
.all(sqlParameters)
if (options.includeWorkOrders) { if (options.includeWorkOrders) {
for (const workOrderMilestone of workOrderMilestones) { for (const workOrderMilestone of workOrderMilestones) {
@ -173,7 +192,7 @@ export function getWorkOrderMilestones(
offset: 0 offset: 0
}, },
database database
).lots; ).lots
workOrderMilestone.workOrderLotOccupancies = getLotOccupancies( workOrderMilestone.workOrderLotOccupancies = getLotOccupancies(
{ {
@ -185,15 +204,15 @@ export function getWorkOrderMilestones(
includeOccupants: true includeOccupants: true
}, },
database database
).lotOccupancies; ).lotOccupancies
} }
} }
if (!connectedDatabase) { if (!connectedDatabase) {
database.close(); database.close()
} }
return workOrderMilestones; return workOrderMilestones
} }
export default getWorkOrderMilestones; export default getWorkOrderMilestones

View File

@ -1,8 +1,8 @@
import sqlite from "better-sqlite3"; import sqlite from 'better-sqlite3';
import type * as recordTypes from "../../types/recordTypes"; import type * as recordTypes from '../../types/recordTypes';
interface GetWorkOrdersFilters { interface GetWorkOrdersFilters {
workOrderTypeId?: number | string; workOrderTypeId?: number | string;
workOrderOpenStatus?: "" | "open" | "closed"; workOrderOpenStatus?: '' | 'open' | 'closed';
workOrderOpenDateString?: string; workOrderOpenDateString?: string;
occupantName?: string; occupantName?: string;
lotName?: string; lotName?: string;

View File

@ -1,54 +1,54 @@
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';
import { dateIntegerToString, dateStringToInteger } from "@cityssm/expressjs-server-js/dateTimeFns.js"; import { dateIntegerToString, dateStringToInteger } from '@cityssm/expressjs-server-js/dateTimeFns.js';
import { getWorkOrderComments } from "./getWorkOrderComments.js"; import { getWorkOrderComments } from './getWorkOrderComments.js';
import { getLots } from "./getLots.js"; import { getLots } from './getLots.js';
import { getLotOccupancies } from "./getLotOccupancies.js"; import { getLotOccupancies } from './getLotOccupancies.js';
import { getWorkOrderMilestones } from "./getWorkOrderMilestones.js"; import { getWorkOrderMilestones } from './getWorkOrderMilestones.js';
import { getLotNameWhereClause, getOccupantNameWhereClause } from "../functions.sqlFilters.js"; import { getLotNameWhereClause, getOccupantNameWhereClause } from '../functions.sqlFilters.js';
function buildWhereClause(filters) { function buildWhereClause(filters) {
let sqlWhereClause = " where w.recordDelete_timeMillis is null"; let sqlWhereClause = ' where w.recordDelete_timeMillis is null';
const sqlParameters = []; const sqlParameters = [];
if (filters.workOrderTypeId) { if (filters.workOrderTypeId) {
sqlWhereClause += " and w.workOrderTypeId = ?"; sqlWhereClause += ' and w.workOrderTypeId = ?';
sqlParameters.push(filters.workOrderTypeId); sqlParameters.push(filters.workOrderTypeId);
} }
if (filters.workOrderOpenStatus) { if (filters.workOrderOpenStatus) {
if (filters.workOrderOpenStatus === "open") { if (filters.workOrderOpenStatus === 'open') {
sqlWhereClause += " and w.workOrderCloseDate is null"; sqlWhereClause += ' and w.workOrderCloseDate is null';
} }
else if (filters.workOrderOpenStatus === "closed") { else if (filters.workOrderOpenStatus === 'closed') {
sqlWhereClause += " and w.workOrderCloseDate is not null"; sqlWhereClause += ' and w.workOrderCloseDate is not null';
} }
} }
if (filters.workOrderOpenDateString) { if (filters.workOrderOpenDateString) {
sqlWhereClause += " and w.workOrderOpenDate = ?"; sqlWhereClause += ' and w.workOrderOpenDate = ?';
sqlParameters.push(dateStringToInteger(filters.workOrderOpenDateString)); sqlParameters.push(dateStringToInteger(filters.workOrderOpenDateString));
} }
const occupantNameFilters = getOccupantNameWhereClause(filters.occupantName, "o"); const occupantNameFilters = getOccupantNameWhereClause(filters.occupantName, 'o');
if (occupantNameFilters.sqlParameters.length > 0) { if (occupantNameFilters.sqlParameters.length > 0) {
sqlWhereClause += sqlWhereClause +=
" and w.workOrderId in (" + ' and w.workOrderId in (' +
"select workOrderId from WorkOrderLotOccupancies o" + 'select workOrderId from WorkOrderLotOccupancies o' +
" where recordDelete_timeMillis is null" + ' where recordDelete_timeMillis is null' +
" and o.lotOccupancyId in (select lotOccupancyId from LotOccupancyOccupants o where recordDelete_timeMillis is null" + ' and o.lotOccupancyId in (select lotOccupancyId from LotOccupancyOccupants o where recordDelete_timeMillis is null' +
occupantNameFilters.sqlWhereClause + occupantNameFilters.sqlWhereClause +
")" + ')' +
")"; ')';
sqlParameters.push(...occupantNameFilters.sqlParameters); sqlParameters.push(...occupantNameFilters.sqlParameters);
} }
const lotNameFilters = getLotNameWhereClause(filters.lotName, "", "l"); const lotNameFilters = getLotNameWhereClause(filters.lotName, '', 'l');
if (lotNameFilters.sqlParameters.length > 0) { if (lotNameFilters.sqlParameters.length > 0) {
sqlWhereClause += sqlWhereClause +=
" and w.workOrderId in (" + ' and w.workOrderId in (' +
"select workOrderId from WorkOrderLots where recordDelete_timeMillis is null and lotId in (select lotId from Lots l where recordDelete_timeMillis is null" + 'select workOrderId from WorkOrderLots where recordDelete_timeMillis is null and lotId in (select lotId from Lots l where recordDelete_timeMillis is null' +
lotNameFilters.sqlWhereClause + lotNameFilters.sqlWhereClause +
"))"; '))';
sqlParameters.push(...lotNameFilters.sqlParameters); sqlParameters.push(...lotNameFilters.sqlParameters);
} }
if (filters.lotOccupancyId) { if (filters.lotOccupancyId) {
sqlWhereClause += sqlWhereClause +=
" and w.workOrderId in (select workOrderId from WorkOrderLotOccupancies where recordDelete_timeMillis is null and lotOccupancyId = ?)"; ' and w.workOrderId in (select workOrderId from WorkOrderLotOccupancies where recordDelete_timeMillis is null and lotOccupancyId = ?)';
sqlParameters.push(filters.lotOccupancyId); sqlParameters.push(filters.lotOccupancyId);
} }
return { return {
@ -57,40 +57,44 @@ function buildWhereClause(filters) {
}; };
} }
export function getWorkOrders(filters, options, connectedDatabase) { export function getWorkOrders(filters, options, connectedDatabase) {
const database = connectedDatabase || const database = connectedDatabase ??
sqlite(databasePath, { sqlite(databasePath, {
readonly: true readonly: true
}); });
database.function("userFn_dateIntegerToString", dateIntegerToString); database.function('userFn_dateIntegerToString', dateIntegerToString);
const { sqlWhereClause, sqlParameters } = buildWhereClause(filters); const { sqlWhereClause, sqlParameters } = buildWhereClause(filters);
const count = database const count = database
.prepare("select count(*) as recordCount from WorkOrders w" + sqlWhereClause) .prepare('select count(*) as recordCount from WorkOrders w' + sqlWhereClause)
.get(sqlParameters).recordCount; .get(sqlParameters).recordCount;
let workOrders = []; let workOrders = [];
if (count > 0) { if (count > 0) {
workOrders = database workOrders = database
.prepare("select w.workOrderId," + .prepare('select w.workOrderId,' +
" w.workOrderTypeId, t.workOrderType," + ' w.workOrderTypeId, t.workOrderType,' +
" w.workOrderNumber, w.workOrderDescription," + ' w.workOrderNumber, w.workOrderDescription,' +
" w.workOrderOpenDate, userFn_dateIntegerToString(w.workOrderOpenDate) as workOrderOpenDateString," + ' w.workOrderOpenDate, userFn_dateIntegerToString(w.workOrderOpenDate) as workOrderOpenDateString,' +
" w.workOrderCloseDate, userFn_dateIntegerToString(w.workOrderCloseDate) as workOrderCloseDateString," + ' w.workOrderCloseDate, userFn_dateIntegerToString(w.workOrderCloseDate) as workOrderCloseDateString,' +
" ifnull(m.workOrderMilestoneCount, 0) as workOrderMilestoneCount," + ' ifnull(m.workOrderMilestoneCount, 0) as workOrderMilestoneCount,' +
" ifnull(m.workOrderMilestoneCompletionCount, 0) as workOrderMilestoneCompletionCount" + ' ifnull(m.workOrderMilestoneCompletionCount, 0) as workOrderMilestoneCompletionCount' +
" from WorkOrders w" + ' from WorkOrders w' +
" left join WorkOrderTypes t on w.workOrderTypeId = t.workOrderTypeId" + ' left join WorkOrderTypes t on w.workOrderTypeId = t.workOrderTypeId' +
(" left join (select workOrderId," + (' left join (select workOrderId,' +
" count(workOrderMilestoneId) as workOrderMilestoneCount," + ' count(workOrderMilestoneId) as workOrderMilestoneCount,' +
" sum(case when workOrderMilestoneCompletionDate is null then 0 else 1 end) as workOrderMilestoneCompletionCount" + ' sum(case when workOrderMilestoneCompletionDate is null then 0 else 1 end) as workOrderMilestoneCompletionCount' +
" from WorkOrderMilestones" + ' from WorkOrderMilestones' +
" where recordDelete_timeMillis is null" + ' where recordDelete_timeMillis is null' +
" group by workOrderId) m on w.workOrderId = m.workOrderId") + ' group by workOrderId) m on w.workOrderId = m.workOrderId') +
sqlWhereClause + sqlWhereClause +
" order by w.workOrderOpenDate desc, w.workOrderNumber desc" + ' order by w.workOrderOpenDate desc, w.workOrderNumber desc' +
(options ? " limit " + options.limit + " offset " + options.offset : "")) (options
? ` limit ${options.limit} offset ${options.offset}`
: ''))
.all(sqlParameters); .all(sqlParameters);
} }
if (options && if (options &&
(options.includeComments || options.includeLotsAndLotOccupancies || options.includeMilestones)) { (options.includeComments ||
options.includeLotsAndLotOccupancies ||
options.includeMilestones)) {
for (const workOrder of workOrders) { for (const workOrder of workOrders) {
if (options.includeComments) { if (options.includeComments) {
workOrder.workOrderComments = getWorkOrderComments(workOrder.workOrderId, database); workOrder.workOrderComments = getWorkOrderComments(workOrder.workOrderId, database);
@ -114,7 +118,7 @@ export function getWorkOrders(filters, options, connectedDatabase) {
workOrder.workOrderMilestones = getWorkOrderMilestones({ workOrder.workOrderMilestones = getWorkOrderMilestones({
workOrderId: workOrder.workOrderId workOrderId: workOrder.workOrderId
}, { }, {
orderBy: "date" orderBy: 'date'
}, database); }, database);
} }
} }

View File

@ -1,92 +1,102 @@
import sqlite from "better-sqlite3"; /* eslint-disable @typescript-eslint/indent */
import sqlite from 'better-sqlite3'
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; import { lotOccupancyDB as databasePath } from '../../data/databasePaths.js'
import { dateIntegerToString, dateStringToInteger } from "@cityssm/expressjs-server-js/dateTimeFns.js"; import {
dateIntegerToString,
dateStringToInteger
} from '@cityssm/expressjs-server-js/dateTimeFns.js'
import { getWorkOrderComments } from "./getWorkOrderComments.js"; import { getWorkOrderComments } from './getWorkOrderComments.js'
import { getLots } from "./getLots.js"; import { getLots } from './getLots.js'
import { getLotOccupancies } from "./getLotOccupancies.js"; import { getLotOccupancies } from './getLotOccupancies.js'
import { getWorkOrderMilestones } from "./getWorkOrderMilestones.js"; import { getWorkOrderMilestones } from './getWorkOrderMilestones.js'
import type * as recordTypes from "../../types/recordTypes"; import type * as recordTypes from '../../types/recordTypes'
import { getLotNameWhereClause, getOccupantNameWhereClause } from "../functions.sqlFilters.js"; import {
getLotNameWhereClause,
getOccupantNameWhereClause
} from '../functions.sqlFilters.js'
interface GetWorkOrdersFilters { interface GetWorkOrdersFilters {
workOrderTypeId?: number | string; workOrderTypeId?: number | string
workOrderOpenStatus?: "" | "open" | "closed"; workOrderOpenStatus?: '' | 'open' | 'closed'
workOrderOpenDateString?: string; workOrderOpenDateString?: string
occupantName?: string; occupantName?: string
lotName?: string; lotName?: string
lotOccupancyId?: number | string; lotOccupancyId?: number | string
} }
interface GetWorkOrdersOptions { interface GetWorkOrdersOptions {
limit: number; limit: number
offset: number; offset: number
includeLotsAndLotOccupancies?: boolean; includeLotsAndLotOccupancies?: boolean
includeComments?: boolean; includeComments?: boolean
includeMilestones?: boolean; includeMilestones?: boolean
} }
function buildWhereClause(filters: GetWorkOrdersFilters): { function buildWhereClause(filters: GetWorkOrdersFilters): {
sqlWhereClause: string; sqlWhereClause: string
sqlParameters: unknown[]; sqlParameters: unknown[]
} { } {
let sqlWhereClause = " where w.recordDelete_timeMillis is null"; let sqlWhereClause = ' where w.recordDelete_timeMillis is null'
const sqlParameters: unknown[] = []; const sqlParameters: unknown[] = []
if (filters.workOrderTypeId) { if (filters.workOrderTypeId) {
sqlWhereClause += " and w.workOrderTypeId = ?"; sqlWhereClause += ' and w.workOrderTypeId = ?'
sqlParameters.push(filters.workOrderTypeId); sqlParameters.push(filters.workOrderTypeId)
} }
if (filters.workOrderOpenStatus) { if (filters.workOrderOpenStatus) {
if (filters.workOrderOpenStatus === "open") { if (filters.workOrderOpenStatus === 'open') {
sqlWhereClause += " and w.workOrderCloseDate is null"; sqlWhereClause += ' and w.workOrderCloseDate is null'
} else if (filters.workOrderOpenStatus === "closed") { } else if (filters.workOrderOpenStatus === 'closed') {
sqlWhereClause += " and w.workOrderCloseDate is not null"; sqlWhereClause += ' and w.workOrderCloseDate is not null'
} }
} }
if (filters.workOrderOpenDateString) { if (filters.workOrderOpenDateString) {
sqlWhereClause += " and w.workOrderOpenDate = ?"; sqlWhereClause += ' and w.workOrderOpenDate = ?'
sqlParameters.push(dateStringToInteger(filters.workOrderOpenDateString)); sqlParameters.push(dateStringToInteger(filters.workOrderOpenDateString))
} }
const occupantNameFilters = getOccupantNameWhereClause(filters.occupantName, "o"); const occupantNameFilters = getOccupantNameWhereClause(
filters.occupantName,
'o'
)
if (occupantNameFilters.sqlParameters.length > 0) { if (occupantNameFilters.sqlParameters.length > 0) {
sqlWhereClause += sqlWhereClause +=
" and w.workOrderId in (" + ' and w.workOrderId in (' +
"select workOrderId from WorkOrderLotOccupancies o" + 'select workOrderId from WorkOrderLotOccupancies o' +
" where recordDelete_timeMillis is null" + ' where recordDelete_timeMillis is null' +
" and o.lotOccupancyId in (select lotOccupancyId from LotOccupancyOccupants o where recordDelete_timeMillis is null" + ' and o.lotOccupancyId in (select lotOccupancyId from LotOccupancyOccupants o where recordDelete_timeMillis is null' +
occupantNameFilters.sqlWhereClause + occupantNameFilters.sqlWhereClause +
")" + ')' +
")"; ')'
sqlParameters.push(...occupantNameFilters.sqlParameters); sqlParameters.push(...occupantNameFilters.sqlParameters)
} }
const lotNameFilters = getLotNameWhereClause(filters.lotName, "", "l"); const lotNameFilters = getLotNameWhereClause(filters.lotName, '', 'l')
if (lotNameFilters.sqlParameters.length > 0) { if (lotNameFilters.sqlParameters.length > 0) {
sqlWhereClause += sqlWhereClause +=
" and w.workOrderId in (" + ' and w.workOrderId in (' +
"select workOrderId from WorkOrderLots where recordDelete_timeMillis is null and lotId in (select lotId from Lots l where recordDelete_timeMillis is null" + 'select workOrderId from WorkOrderLots where recordDelete_timeMillis is null and lotId in (select lotId from Lots l where recordDelete_timeMillis is null' +
lotNameFilters.sqlWhereClause + lotNameFilters.sqlWhereClause +
"))"; '))'
sqlParameters.push(...lotNameFilters.sqlParameters); sqlParameters.push(...lotNameFilters.sqlParameters)
} }
if (filters.lotOccupancyId) { if (filters.lotOccupancyId) {
sqlWhereClause += sqlWhereClause +=
" and w.workOrderId in (select workOrderId from WorkOrderLotOccupancies where recordDelete_timeMillis is null and lotOccupancyId = ?)"; ' and w.workOrderId in (select workOrderId from WorkOrderLotOccupancies where recordDelete_timeMillis is null and lotOccupancyId = ?)'
sqlParameters.push(filters.lotOccupancyId); sqlParameters.push(filters.lotOccupancyId)
} }
return { return {
sqlWhereClause, sqlWhereClause,
sqlParameters sqlParameters
}; }
} }
export function getWorkOrders( export function getWorkOrders(
@ -94,57 +104,66 @@ export function getWorkOrders(
options?: GetWorkOrdersOptions, options?: GetWorkOrdersOptions,
connectedDatabase?: sqlite.Database connectedDatabase?: sqlite.Database
): { ): {
count: number; count: number
workOrders: recordTypes.WorkOrder[]; workOrders: recordTypes.WorkOrder[]
} { } {
const database = const database =
connectedDatabase || connectedDatabase ??
sqlite(databasePath, { sqlite(databasePath, {
readonly: true readonly: true
}); })
database.function("userFn_dateIntegerToString", dateIntegerToString); database.function('userFn_dateIntegerToString', dateIntegerToString)
const { sqlWhereClause, sqlParameters } = buildWhereClause(filters); const { sqlWhereClause, sqlParameters } = buildWhereClause(filters)
const count: number = database const count: number = database
.prepare("select count(*) as recordCount from WorkOrders w" + sqlWhereClause) .prepare(
.get(sqlParameters).recordCount; 'select count(*) as recordCount from WorkOrders w' + sqlWhereClause
)
.get(sqlParameters).recordCount
let workOrders: recordTypes.WorkOrder[] = []; let workOrders: recordTypes.WorkOrder[] = []
if (count > 0) { if (count > 0) {
workOrders = database workOrders = database
.prepare( .prepare(
"select w.workOrderId," + 'select w.workOrderId,' +
" w.workOrderTypeId, t.workOrderType," + ' w.workOrderTypeId, t.workOrderType,' +
" w.workOrderNumber, w.workOrderDescription," + ' w.workOrderNumber, w.workOrderDescription,' +
" w.workOrderOpenDate, userFn_dateIntegerToString(w.workOrderOpenDate) as workOrderOpenDateString," + ' w.workOrderOpenDate, userFn_dateIntegerToString(w.workOrderOpenDate) as workOrderOpenDateString,' +
" w.workOrderCloseDate, userFn_dateIntegerToString(w.workOrderCloseDate) as workOrderCloseDateString," + ' w.workOrderCloseDate, userFn_dateIntegerToString(w.workOrderCloseDate) as workOrderCloseDateString,' +
" ifnull(m.workOrderMilestoneCount, 0) as workOrderMilestoneCount," + ' ifnull(m.workOrderMilestoneCount, 0) as workOrderMilestoneCount,' +
" ifnull(m.workOrderMilestoneCompletionCount, 0) as workOrderMilestoneCompletionCount" + ' ifnull(m.workOrderMilestoneCompletionCount, 0) as workOrderMilestoneCompletionCount' +
" from WorkOrders w" + ' from WorkOrders w' +
" left join WorkOrderTypes t on w.workOrderTypeId = t.workOrderTypeId" + ' left join WorkOrderTypes t on w.workOrderTypeId = t.workOrderTypeId' +
(" left join (select workOrderId," + (' left join (select workOrderId,' +
" count(workOrderMilestoneId) as workOrderMilestoneCount," + ' count(workOrderMilestoneId) as workOrderMilestoneCount,' +
" sum(case when workOrderMilestoneCompletionDate is null then 0 else 1 end) as workOrderMilestoneCompletionCount" + ' sum(case when workOrderMilestoneCompletionDate is null then 0 else 1 end) as workOrderMilestoneCompletionCount' +
" from WorkOrderMilestones" + ' from WorkOrderMilestones' +
" where recordDelete_timeMillis is null" + ' where recordDelete_timeMillis is null' +
" group by workOrderId) m on w.workOrderId = m.workOrderId") + ' group by workOrderId) m on w.workOrderId = m.workOrderId') +
sqlWhereClause + sqlWhereClause +
" order by w.workOrderOpenDate desc, w.workOrderNumber desc" + ' order by w.workOrderOpenDate desc, w.workOrderNumber desc' +
(options ? " limit " + options.limit + " offset " + options.offset : "") (options
? ` limit ${options.limit} offset ${options.offset}`
: '')
) )
.all(sqlParameters); .all(sqlParameters)
} }
if ( if (
options && options &&
(options.includeComments || options.includeLotsAndLotOccupancies || options.includeMilestones) (options.includeComments ||
options.includeLotsAndLotOccupancies ||
options.includeMilestones)
) { ) {
for (const workOrder of workOrders) { for (const workOrder of workOrders) {
if (options.includeComments) { if (options.includeComments) {
workOrder.workOrderComments = getWorkOrderComments(workOrder.workOrderId as number, database); workOrder.workOrderComments = getWorkOrderComments(
workOrder.workOrderId as number,
database
)
} }
if (options.includeLotsAndLotOccupancies) { if (options.includeLotsAndLotOccupancies) {
@ -157,7 +176,7 @@ export function getWorkOrders(
offset: 0 offset: 0
}, },
database database
).lots; ).lots
workOrder.workOrderLotOccupancies = getLotOccupancies( workOrder.workOrderLotOccupancies = getLotOccupancies(
{ {
@ -169,7 +188,7 @@ export function getWorkOrders(
includeOccupants: true includeOccupants: true
}, },
database database
).lotOccupancies; ).lotOccupancies
} }
if (options.includeMilestones) { if (options.includeMilestones) {
@ -178,22 +197,22 @@ export function getWorkOrders(
workOrderId: workOrder.workOrderId workOrderId: workOrder.workOrderId
}, },
{ {
orderBy: "date" orderBy: 'date'
}, },
database database
); )
} }
} }
} }
if (!connectedDatabase) { if (!connectedDatabase) {
database.close(); database.close()
} }
return { return {
count, count,
workOrders workOrders
}; }
} }
export default getWorkOrders; export default getWorkOrders

View File

@ -1,10 +1,10 @@
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';
import { clearCacheByTableName } from "../functions.cache.js"; import { clearCacheByTableName } from '../functions.cache.js';
import { updateRecordOrderNumber } from "./updateRecordOrderNumber.js"; import { updateRecordOrderNumber } from './updateRecordOrderNumber.js';
function getCurrentField(lotTypeFieldId, connectedDatabase) { function getCurrentField(lotTypeFieldId, connectedDatabase) {
const currentField = connectedDatabase const currentField = connectedDatabase
.prepare("select lotTypeId, orderNumber from LotTypeFields where lotTypeFieldId = ?") .prepare('select lotTypeId, orderNumber from LotTypeFields where lotTypeFieldId = ?')
.get(lotTypeFieldId); .get(lotTypeFieldId);
return currentField; return currentField;
} }
@ -17,9 +17,9 @@ export function moveLotTypeFieldDown(lotTypeFieldId) {
where recordDelete_timeMillis is null where recordDelete_timeMillis is null
and lotTypeId = ? and orderNumber = ? + 1`) and lotTypeId = ? and orderNumber = ? + 1`)
.run(currentField.lotTypeId, currentField.orderNumber); .run(currentField.lotTypeId, currentField.orderNumber);
const success = updateRecordOrderNumber("LotTypeFields", lotTypeFieldId, currentField.orderNumber + 1, database); const success = updateRecordOrderNumber('LotTypeFields', lotTypeFieldId, currentField.orderNumber + 1, database);
database.close(); database.close();
clearCacheByTableName("LotTypeFields"); clearCacheByTableName('LotTypeFields');
return success; return success;
} }
export function moveLotTypeFieldDownToBottom(lotTypeFieldId) { export function moveLotTypeFieldDownToBottom(lotTypeFieldId) {
@ -32,7 +32,7 @@ export function moveLotTypeFieldDownToBottom(lotTypeFieldId) {
and lotTypeId = ?`) and lotTypeId = ?`)
.get(currentField.lotTypeId).maxOrderNumber; .get(currentField.lotTypeId).maxOrderNumber;
if (currentField.orderNumber !== maxOrderNumber) { if (currentField.orderNumber !== maxOrderNumber) {
updateRecordOrderNumber("LotTypeFields", lotTypeFieldId, maxOrderNumber + 1, database); updateRecordOrderNumber('LotTypeFields', lotTypeFieldId, maxOrderNumber + 1, database);
database database
.prepare(`update LotTypeFields .prepare(`update LotTypeFields
set orderNumber = orderNumber - 1 set orderNumber = orderNumber - 1
@ -42,7 +42,7 @@ export function moveLotTypeFieldDownToBottom(lotTypeFieldId) {
.run(currentField.lotTypeId, currentField.orderNumber); .run(currentField.lotTypeId, currentField.orderNumber);
} }
database.close(); database.close();
clearCacheByTableName("LotTypeFields"); clearCacheByTableName('LotTypeFields');
return true; return true;
} }
export function moveLotTypeFieldUp(lotTypeFieldId) { export function moveLotTypeFieldUp(lotTypeFieldId) {
@ -59,16 +59,16 @@ export function moveLotTypeFieldUp(lotTypeFieldId) {
and lotTypeId = ? and lotTypeId = ?
and orderNumber = ? - 1`) and orderNumber = ? - 1`)
.run(currentField.lotTypeId, currentField.orderNumber); .run(currentField.lotTypeId, currentField.orderNumber);
const success = updateRecordOrderNumber("LotTypeFields", lotTypeFieldId, currentField.orderNumber - 1, database); const success = updateRecordOrderNumber('LotTypeFields', lotTypeFieldId, currentField.orderNumber - 1, database);
database.close(); database.close();
clearCacheByTableName("LotTypeFields"); clearCacheByTableName('LotTypeFields');
return success; return success;
} }
export function moveLotTypeFieldUpToTop(lotTypeFieldId) { export function moveLotTypeFieldUpToTop(lotTypeFieldId) {
const database = sqlite(databasePath); const database = sqlite(databasePath);
const currentField = getCurrentField(lotTypeFieldId, database); const currentField = getCurrentField(lotTypeFieldId, database);
if (currentField.orderNumber > 0) { if (currentField.orderNumber > 0) {
updateRecordOrderNumber("LotTypeFields", lotTypeFieldId, -1, database); updateRecordOrderNumber('LotTypeFields', lotTypeFieldId, -1, database);
database database
.prepare(`update LotTypeFields .prepare(`update LotTypeFields
set orderNumber = orderNumber + 1 set orderNumber = orderNumber + 1
@ -78,6 +78,6 @@ export function moveLotTypeFieldUpToTop(lotTypeFieldId) {
.run(currentField.lotTypeId, currentField.orderNumber); .run(currentField.lotTypeId, currentField.orderNumber);
} }
database.close(); database.close();
clearCacheByTableName("LotTypeFields"); clearCacheByTableName('LotTypeFields');
return true; return true;
} }

View File

@ -1,25 +1,28 @@
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'
import { clearCacheByTableName } from "../functions.cache.js"; import { clearCacheByTableName } from '../functions.cache.js'
import { updateRecordOrderNumber } from "./updateRecordOrderNumber.js"; import { updateRecordOrderNumber } from './updateRecordOrderNumber.js'
function getCurrentField( function getCurrentField(
lotTypeFieldId: number | string, lotTypeFieldId: number | string,
connectedDatabase: sqlite.Database connectedDatabase: sqlite.Database
): { lotTypeId?: number; orderNumber: number } { ): { lotTypeId?: number; orderNumber: number } {
const currentField: { lotTypeId?: number; orderNumber: number } = connectedDatabase const currentField: { lotTypeId?: number; orderNumber: number } =
.prepare("select lotTypeId, orderNumber from LotTypeFields where lotTypeFieldId = ?") connectedDatabase
.get(lotTypeFieldId); .prepare(
'select lotTypeId, orderNumber from LotTypeFields where lotTypeFieldId = ?'
)
.get(lotTypeFieldId)
return currentField; return currentField
} }
export function moveLotTypeFieldDown(lotTypeFieldId: number | string): boolean { export function moveLotTypeFieldDown(lotTypeFieldId: number | string): boolean {
const database = sqlite(databasePath); const database = sqlite(databasePath)
const currentField = getCurrentField(lotTypeFieldId, database); const currentField = getCurrentField(lotTypeFieldId, database)
database database
.prepare( .prepare(
@ -28,26 +31,28 @@ export function moveLotTypeFieldDown(lotTypeFieldId: number | string): boolean {
where recordDelete_timeMillis is null where recordDelete_timeMillis is null
and lotTypeId = ? and orderNumber = ? + 1` and lotTypeId = ? and orderNumber = ? + 1`
) )
.run(currentField.lotTypeId, currentField.orderNumber); .run(currentField.lotTypeId, currentField.orderNumber)
const success = updateRecordOrderNumber( const success = updateRecordOrderNumber(
"LotTypeFields", 'LotTypeFields',
lotTypeFieldId, lotTypeFieldId,
currentField.orderNumber + 1, currentField.orderNumber + 1,
database database
); )
database.close(); database.close()
clearCacheByTableName("LotTypeFields"); clearCacheByTableName('LotTypeFields')
return success; return success
} }
export function moveLotTypeFieldDownToBottom(lotTypeFieldId: number | string): boolean { export function moveLotTypeFieldDownToBottom(
const database = sqlite(databasePath); lotTypeFieldId: number | string
): boolean {
const database = sqlite(databasePath)
const currentField = getCurrentField(lotTypeFieldId, database); const currentField = getCurrentField(lotTypeFieldId, database)
const maxOrderNumber: number = database const maxOrderNumber: number = database
.prepare( .prepare(
@ -56,10 +61,15 @@ export function moveLotTypeFieldDownToBottom(lotTypeFieldId: number | string): b
where recordDelete_timeMillis is null where recordDelete_timeMillis is null
and lotTypeId = ?` and lotTypeId = ?`
) )
.get(currentField.lotTypeId).maxOrderNumber; .get(currentField.lotTypeId).maxOrderNumber
if (currentField.orderNumber !== maxOrderNumber) { if (currentField.orderNumber !== maxOrderNumber) {
updateRecordOrderNumber("LotTypeFields", lotTypeFieldId, maxOrderNumber + 1, database); updateRecordOrderNumber(
'LotTypeFields',
lotTypeFieldId,
maxOrderNumber + 1,
database
)
database database
.prepare( .prepare(
@ -69,24 +79,24 @@ export function moveLotTypeFieldDownToBottom(lotTypeFieldId: number | string): b
and lotTypeId = ? and lotTypeId = ?
and orderNumber > ?` and orderNumber > ?`
) )
.run(currentField.lotTypeId, currentField.orderNumber); .run(currentField.lotTypeId, currentField.orderNumber)
} }
database.close(); database.close()
clearCacheByTableName("LotTypeFields"); clearCacheByTableName('LotTypeFields')
return true; return true
} }
export function moveLotTypeFieldUp(lotTypeFieldId: number | string): boolean { export function moveLotTypeFieldUp(lotTypeFieldId: number | string): boolean {
const database = sqlite(databasePath); const database = sqlite(databasePath)
const currentField = getCurrentField(lotTypeFieldId, database); const currentField = getCurrentField(lotTypeFieldId, database)
if (currentField.orderNumber <= 0) { if (currentField.orderNumber <= 0) {
database.close(); database.close()
return true; return true
} }
database database
@ -97,29 +107,31 @@ export function moveLotTypeFieldUp(lotTypeFieldId: number | string): boolean {
and lotTypeId = ? and lotTypeId = ?
and orderNumber = ? - 1` and orderNumber = ? - 1`
) )
.run(currentField.lotTypeId, currentField.orderNumber); .run(currentField.lotTypeId, currentField.orderNumber)
const success = updateRecordOrderNumber( const success = updateRecordOrderNumber(
"LotTypeFields", 'LotTypeFields',
lotTypeFieldId, lotTypeFieldId,
currentField.orderNumber - 1, currentField.orderNumber - 1,
database database
); )
database.close(); database.close()
clearCacheByTableName("LotTypeFields"); clearCacheByTableName('LotTypeFields')
return success; return success
} }
export function moveLotTypeFieldUpToTop(lotTypeFieldId: number | string): boolean { export function moveLotTypeFieldUpToTop(
const database = sqlite(databasePath); lotTypeFieldId: number | string
): boolean {
const database = sqlite(databasePath)
const currentField = getCurrentField(lotTypeFieldId, database); const currentField = getCurrentField(lotTypeFieldId, database)
if (currentField.orderNumber > 0) { if (currentField.orderNumber > 0) {
updateRecordOrderNumber("LotTypeFields", lotTypeFieldId, -1, database); updateRecordOrderNumber('LotTypeFields', lotTypeFieldId, -1, database)
database database
.prepare( .prepare(
@ -129,12 +141,12 @@ export function moveLotTypeFieldUpToTop(lotTypeFieldId: number | string): boolea
and lotTypeId = ? and lotTypeId = ?
and orderNumber < ?` and orderNumber < ?`
) )
.run(currentField.lotTypeId, currentField.orderNumber); .run(currentField.lotTypeId, currentField.orderNumber)
} }
database.close(); database.close()
clearCacheByTableName("LotTypeFields"); clearCacheByTableName('LotTypeFields')
return true; return true
} }

View File

@ -1,10 +1,10 @@
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';
import { clearCacheByTableName } from "../functions.cache.js"; import { clearCacheByTableName } from '../functions.cache.js';
export function moveOccupancyTypePrintDown(occupancyTypeId, printEJS) { export function moveOccupancyTypePrintDown(occupancyTypeId, printEJS) {
const database = sqlite(databasePath); const database = sqlite(databasePath);
const currentOrderNumber = database const currentOrderNumber = database
.prepare(`select orderNumber from OccupancyTypePrints where occupancyTypeId = ? and printEJS = ?`) .prepare('select orderNumber from OccupancyTypePrints where occupancyTypeId = ? and printEJS = ?')
.get(occupancyTypeId, printEJS).orderNumber; .get(occupancyTypeId, printEJS).orderNumber;
database database
.prepare(`update OccupancyTypePrints .prepare(`update OccupancyTypePrints
@ -14,16 +14,16 @@ export function moveOccupancyTypePrintDown(occupancyTypeId, printEJS) {
and orderNumber = ? + 1`) and orderNumber = ? + 1`)
.run(occupancyTypeId, currentOrderNumber); .run(occupancyTypeId, currentOrderNumber);
const result = database const result = database
.prepare(`update OccupancyTypePrints set orderNumber = ? + 1 where occupancyTypeId = ? and printEJS = ?`) .prepare('update OccupancyTypePrints set orderNumber = ? + 1 where occupancyTypeId = ? and printEJS = ?')
.run(currentOrderNumber, occupancyTypeId, printEJS); .run(currentOrderNumber, occupancyTypeId, printEJS);
database.close(); database.close();
clearCacheByTableName("OccupancyTypePrints"); clearCacheByTableName('OccupancyTypePrints');
return result.changes > 0; return result.changes > 0;
} }
export function moveOccupancyTypePrintDownToBottom(occupancyTypeId, printEJS) { export function moveOccupancyTypePrintDownToBottom(occupancyTypeId, printEJS) {
const database = sqlite(databasePath); const database = sqlite(databasePath);
const currentOrderNumber = database const currentOrderNumber = database
.prepare(`select orderNumber from OccupancyTypePrints where occupancyTypeId = ? and printEJS = ?`) .prepare('select orderNumber from OccupancyTypePrints where occupancyTypeId = ? and printEJS = ?')
.get(occupancyTypeId, printEJS).orderNumber; .get(occupancyTypeId, printEJS).orderNumber;
const maxOrderNumber = database const maxOrderNumber = database
.prepare(`select max(orderNumber) as maxOrderNumber .prepare(`select max(orderNumber) as maxOrderNumber
@ -47,7 +47,7 @@ export function moveOccupancyTypePrintDownToBottom(occupancyTypeId, printEJS) {
.run(occupancyTypeId, currentOrderNumber); .run(occupancyTypeId, currentOrderNumber);
} }
database.close(); database.close();
clearCacheByTableName("OccupancyTypePrints"); clearCacheByTableName('OccupancyTypePrints');
return true; return true;
} }
export default moveOccupancyTypePrintDown; export default moveOccupancyTypePrintDown;

View File

@ -1,20 +1,20 @@
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'
import { clearCacheByTableName } from "../functions.cache.js"; import { clearCacheByTableName } from '../functions.cache.js'
export function moveOccupancyTypePrintDown( export function moveOccupancyTypePrintDown(
occupancyTypeId: number | string, occupancyTypeId: number | string,
printEJS: string printEJS: string
): boolean { ): boolean {
const database = sqlite(databasePath); const database = sqlite(databasePath)
const currentOrderNumber = database const currentOrderNumber = database
.prepare( .prepare(
`select orderNumber from OccupancyTypePrints where occupancyTypeId = ? and printEJS = ?` 'select orderNumber from OccupancyTypePrints where occupancyTypeId = ? and printEJS = ?'
) )
.get(occupancyTypeId, printEJS).orderNumber; .get(occupancyTypeId, printEJS).orderNumber
database database
.prepare( .prepare(
@ -24,32 +24,32 @@ export function moveOccupancyTypePrintDown(
and occupancyTypeId = ? and occupancyTypeId = ?
and orderNumber = ? + 1` and orderNumber = ? + 1`
) )
.run(occupancyTypeId, currentOrderNumber); .run(occupancyTypeId, currentOrderNumber)
const result = database const result = database
.prepare( .prepare(
`update OccupancyTypePrints set orderNumber = ? + 1 where occupancyTypeId = ? and printEJS = ?` 'update OccupancyTypePrints set orderNumber = ? + 1 where occupancyTypeId = ? and printEJS = ?'
) )
.run(currentOrderNumber, occupancyTypeId, printEJS); .run(currentOrderNumber, occupancyTypeId, printEJS)
database.close(); database.close()
clearCacheByTableName("OccupancyTypePrints"); clearCacheByTableName('OccupancyTypePrints')
return result.changes > 0; return result.changes > 0
} }
export function moveOccupancyTypePrintDownToBottom( export function moveOccupancyTypePrintDownToBottom(
occupancyTypeId: number | string, occupancyTypeId: number | string,
printEJS: string printEJS: string
): boolean { ): boolean {
const database = sqlite(databasePath); const database = sqlite(databasePath)
const currentOrderNumber = database const currentOrderNumber = database
.prepare( .prepare(
`select orderNumber from OccupancyTypePrints where occupancyTypeId = ? and printEJS = ?` 'select orderNumber from OccupancyTypePrints where occupancyTypeId = ? and printEJS = ?'
) )
.get(occupancyTypeId, printEJS).orderNumber; .get(occupancyTypeId, printEJS).orderNumber
const maxOrderNumber: number = database const maxOrderNumber: number = database
.prepare( .prepare(
@ -58,7 +58,7 @@ export function moveOccupancyTypePrintDownToBottom(
where recordDelete_timeMillis is null where recordDelete_timeMillis is null
and occupancyTypeId = ?` and occupancyTypeId = ?`
) )
.get(occupancyTypeId).maxOrderNumber; .get(occupancyTypeId).maxOrderNumber
if (currentOrderNumber !== maxOrderNumber) { if (currentOrderNumber !== maxOrderNumber) {
database database
@ -68,7 +68,7 @@ export function moveOccupancyTypePrintDownToBottom(
where occupancyTypeId = ? where occupancyTypeId = ?
and printEJS = ?` and printEJS = ?`
) )
.run(maxOrderNumber, occupancyTypeId, printEJS); .run(maxOrderNumber, occupancyTypeId, printEJS)
database database
.prepare( .prepare(
@ -78,14 +78,14 @@ export function moveOccupancyTypePrintDownToBottom(
and occupancyTypeId = ? and occupancyTypeId = ?
and orderNumber > ?` and orderNumber > ?`
) )
.run(occupancyTypeId, currentOrderNumber); .run(occupancyTypeId, currentOrderNumber)
} }
database.close(); database.close()
clearCacheByTableName("OccupancyTypePrints"); clearCacheByTableName('OccupancyTypePrints')
return true; return true
} }
export default moveOccupancyTypePrintDown; export default moveOccupancyTypePrintDown

View File

@ -1,10 +1,10 @@
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';
import { clearCacheByTableName } from "../functions.cache.js"; import { clearCacheByTableName } from '../functions.cache.js';
export function moveOccupancyTypePrintUp(occupancyTypeId, printEJS) { export function moveOccupancyTypePrintUp(occupancyTypeId, printEJS) {
const database = sqlite(databasePath); const database = sqlite(databasePath);
const currentOrderNumber = database const currentOrderNumber = database
.prepare(`select orderNumber from OccupancyTypePrints where occupancyTypeId = ? and printEJS = ?`) .prepare('select orderNumber from OccupancyTypePrints where occupancyTypeId = ? and printEJS = ?')
.get(occupancyTypeId, printEJS).orderNumber; .get(occupancyTypeId, printEJS).orderNumber;
if (currentOrderNumber <= 0) { if (currentOrderNumber <= 0) {
database.close(); database.close();
@ -18,16 +18,16 @@ export function moveOccupancyTypePrintUp(occupancyTypeId, printEJS) {
and orderNumber = ? - 1`) and orderNumber = ? - 1`)
.run(occupancyTypeId, currentOrderNumber); .run(occupancyTypeId, currentOrderNumber);
const result = database const result = database
.prepare(`update OccupancyTypePrints set orderNumber = ? - 1 where occupancyTypeId = ? and printEJS = ?`) .prepare('update OccupancyTypePrints set orderNumber = ? - 1 where occupancyTypeId = ? and printEJS = ?')
.run(currentOrderNumber, occupancyTypeId, printEJS); .run(currentOrderNumber, occupancyTypeId, printEJS);
database.close(); database.close();
clearCacheByTableName("OccupancyTypePrints"); clearCacheByTableName('OccupancyTypePrints');
return result.changes > 0; return result.changes > 0;
} }
export function moveOccupancyTypePrintUpToTop(occupancyTypeId, printEJS) { export function moveOccupancyTypePrintUpToTop(occupancyTypeId, printEJS) {
const database = sqlite(databasePath); const database = sqlite(databasePath);
const currentOrderNumber = database const currentOrderNumber = database
.prepare(`select orderNumber from OccupancyTypePrints where occupancyTypeId = ? and printEJS = ?`) .prepare('select orderNumber from OccupancyTypePrints where occupancyTypeId = ? and printEJS = ?')
.get(occupancyTypeId, printEJS).orderNumber; .get(occupancyTypeId, printEJS).orderNumber;
if (currentOrderNumber > 0) { if (currentOrderNumber > 0) {
database database
@ -45,7 +45,7 @@ export function moveOccupancyTypePrintUpToTop(occupancyTypeId, printEJS) {
.run(occupancyTypeId, currentOrderNumber); .run(occupancyTypeId, currentOrderNumber);
} }
database.close(); database.close();
clearCacheByTableName("OccupancyTypePrints"); clearCacheByTableName('OccupancyTypePrints');
return true; return true;
} }
export default moveOccupancyTypePrintUp; export default moveOccupancyTypePrintUp;

View File

@ -1,24 +1,24 @@
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'
import { clearCacheByTableName } from "../functions.cache.js"; import { clearCacheByTableName } from '../functions.cache.js'
export function moveOccupancyTypePrintUp( export function moveOccupancyTypePrintUp(
occupancyTypeId: number | string, occupancyTypeId: number | string,
printEJS: string printEJS: string
): boolean { ): boolean {
const database = sqlite(databasePath); const database = sqlite(databasePath)
const currentOrderNumber = database const currentOrderNumber = database
.prepare( .prepare(
`select orderNumber from OccupancyTypePrints where occupancyTypeId = ? and printEJS = ?` 'select orderNumber from OccupancyTypePrints where occupancyTypeId = ? and printEJS = ?'
) )
.get(occupancyTypeId, printEJS).orderNumber; .get(occupancyTypeId, printEJS).orderNumber
if (currentOrderNumber <= 0) { if (currentOrderNumber <= 0) {
database.close(); database.close()
return true; return true
} }
database database
@ -29,32 +29,32 @@ export function moveOccupancyTypePrintUp(
and occupancyTypeId = ? and occupancyTypeId = ?
and orderNumber = ? - 1` and orderNumber = ? - 1`
) )
.run(occupancyTypeId, currentOrderNumber); .run(occupancyTypeId, currentOrderNumber)
const result = database const result = database
.prepare( .prepare(
`update OccupancyTypePrints set orderNumber = ? - 1 where occupancyTypeId = ? and printEJS = ?` 'update OccupancyTypePrints set orderNumber = ? - 1 where occupancyTypeId = ? and printEJS = ?'
) )
.run(currentOrderNumber, occupancyTypeId, printEJS); .run(currentOrderNumber, occupancyTypeId, printEJS)
database.close(); database.close()
clearCacheByTableName("OccupancyTypePrints"); clearCacheByTableName('OccupancyTypePrints')
return result.changes > 0; return result.changes > 0
} }
export function moveOccupancyTypePrintUpToTop( export function moveOccupancyTypePrintUpToTop(
occupancyTypeId: number | string, occupancyTypeId: number | string,
printEJS: string printEJS: string
): boolean { ): boolean {
const database = sqlite(databasePath); const database = sqlite(databasePath)
const currentOrderNumber = database const currentOrderNumber = database
.prepare( .prepare(
`select orderNumber from OccupancyTypePrints where occupancyTypeId = ? and printEJS = ?` 'select orderNumber from OccupancyTypePrints where occupancyTypeId = ? and printEJS = ?'
) )
.get(occupancyTypeId, printEJS).orderNumber; .get(occupancyTypeId, printEJS).orderNumber
if (currentOrderNumber > 0) { if (currentOrderNumber > 0) {
database database
@ -64,7 +64,7 @@ export function moveOccupancyTypePrintUpToTop(
where occupancyTypeId = ? where occupancyTypeId = ?
and printEJS = ?` and printEJS = ?`
) )
.run(occupancyTypeId, printEJS); .run(occupancyTypeId, printEJS)
database database
.prepare( .prepare(
@ -74,14 +74,14 @@ export function moveOccupancyTypePrintUpToTop(
and occupancyTypeId = ? and occupancyTypeId = ?
and orderNumber < ?` and orderNumber < ?`
) )
.run(occupancyTypeId, currentOrderNumber); .run(occupancyTypeId, currentOrderNumber)
} }
database.close(); database.close()
clearCacheByTableName("OccupancyTypePrints"); clearCacheByTableName('OccupancyTypePrints')
return true; return true
} }
export default moveOccupancyTypePrintUp; export default moveOccupancyTypePrintUp

View File

@ -1,4 +1,4 @@
declare type RecordTable = "FeeCategories" | "LotOccupantTypes" | "LotStatuses" | "LotTypes" | "OccupancyTypes" | "WorkOrderMilestoneTypes" | "WorkOrderTypes"; declare type RecordTable = 'FeeCategories' | 'LotOccupantTypes' | 'LotStatuses' | 'LotTypes' | 'OccupancyTypes' | 'WorkOrderMilestoneTypes' | 'WorkOrderTypes';
export declare function moveRecordDown(recordTable: RecordTable, recordId: number): boolean; export declare function moveRecordDown(recordTable: RecordTable, recordId: number): boolean;
export declare function moveRecordDownToBottom(recordTable: RecordTable, recordId: number): boolean; export declare function moveRecordDownToBottom(recordTable: RecordTable, recordId: number): boolean;
export declare function moveRecordUp(recordTable: RecordTable, recordId: number): boolean; export declare function moveRecordUp(recordTable: RecordTable, recordId: number): boolean;

View File

@ -1,15 +1,15 @@
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';
import { clearCacheByTableName } from "../functions.cache.js"; import { clearCacheByTableName } from '../functions.cache.js';
import { updateRecordOrderNumber } from "./updateRecordOrderNumber.js"; import { updateRecordOrderNumber } from './updateRecordOrderNumber.js';
const recordIdColumns = new Map(); const recordIdColumns = new Map();
recordIdColumns.set("FeeCategories", "feeCategoryId"); recordIdColumns.set('FeeCategories', 'feeCategoryId');
recordIdColumns.set("LotOccupantTypes", "lotOccupantTypeId"); recordIdColumns.set('LotOccupantTypes', 'lotOccupantTypeId');
recordIdColumns.set("LotStatuses", "lotStatusId"); recordIdColumns.set('LotStatuses', 'lotStatusId');
recordIdColumns.set("LotTypes", "lotTypeId"); recordIdColumns.set('LotTypes', 'lotTypeId');
recordIdColumns.set("OccupancyTypes", "occupancyTypeId"); recordIdColumns.set('OccupancyTypes', 'occupancyTypeId');
recordIdColumns.set("WorkOrderMilestoneTypes", "workOrderMilestoneTypeId"); recordIdColumns.set('WorkOrderMilestoneTypes', 'workOrderMilestoneTypeId');
recordIdColumns.set("WorkOrderTypes", "workOrderTypeId"); recordIdColumns.set('WorkOrderTypes', 'workOrderTypeId');
function getCurrentOrderNumber(recordTable, recordId, database) { function getCurrentOrderNumber(recordTable, recordId, database) {
const currentOrderNumber = database const currentOrderNumber = database
.prepare(`select orderNumber .prepare(`select orderNumber

View File

@ -1,26 +1,26 @@
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'
import { clearCacheByTableName } from "../functions.cache.js"; import { clearCacheByTableName } from '../functions.cache.js'
import { updateRecordOrderNumber } from "./updateRecordOrderNumber.js"; import { updateRecordOrderNumber } from './updateRecordOrderNumber.js'
type RecordTable = type RecordTable =
| "FeeCategories" | 'FeeCategories'
| "LotOccupantTypes" | 'LotOccupantTypes'
| "LotStatuses" | 'LotStatuses'
| "LotTypes" | 'LotTypes'
| "OccupancyTypes" | 'OccupancyTypes'
| "WorkOrderMilestoneTypes" | 'WorkOrderMilestoneTypes'
| "WorkOrderTypes"; | 'WorkOrderTypes'
const recordIdColumns: Map<RecordTable, string> = new Map(); const recordIdColumns: Map<RecordTable, string> = new Map()
recordIdColumns.set("FeeCategories", "feeCategoryId"); recordIdColumns.set('FeeCategories', 'feeCategoryId')
recordIdColumns.set("LotOccupantTypes", "lotOccupantTypeId"); recordIdColumns.set('LotOccupantTypes', 'lotOccupantTypeId')
recordIdColumns.set("LotStatuses", "lotStatusId"); recordIdColumns.set('LotStatuses', 'lotStatusId')
recordIdColumns.set("LotTypes", "lotTypeId"); recordIdColumns.set('LotTypes', 'lotTypeId')
recordIdColumns.set("OccupancyTypes", "occupancyTypeId"); recordIdColumns.set('OccupancyTypes', 'occupancyTypeId')
recordIdColumns.set("WorkOrderMilestoneTypes", "workOrderMilestoneTypeId"); recordIdColumns.set('WorkOrderMilestoneTypes', 'workOrderMilestoneTypeId')
recordIdColumns.set("WorkOrderTypes", "workOrderTypeId"); recordIdColumns.set('WorkOrderTypes', 'workOrderTypeId')
function getCurrentOrderNumber( function getCurrentOrderNumber(
recordTable: RecordTable, recordTable: RecordTable,
@ -31,17 +31,24 @@ function getCurrentOrderNumber(
.prepare( .prepare(
`select orderNumber `select orderNumber
from ${recordTable} from ${recordTable}
where ${recordIdColumns.get(recordTable)} = ?` where ${recordIdColumns.get(recordTable)!} = ?`
) )
.get(recordId).orderNumber; .get(recordId).orderNumber
return currentOrderNumber; return currentOrderNumber
} }
export function moveRecordDown(recordTable: RecordTable, recordId: number): boolean { export function moveRecordDown(
const database = sqlite(databasePath); recordTable: RecordTable,
recordId: number
): boolean {
const database = sqlite(databasePath)
const currentOrderNumber = getCurrentOrderNumber(recordTable, recordId, database); const currentOrderNumber = getCurrentOrderNumber(
recordTable,
recordId,
database
)
database database
.prepare( .prepare(
@ -50,21 +57,33 @@ export function moveRecordDown(recordTable: RecordTable, recordId: number): bool
where recordDelete_timeMillis is null where recordDelete_timeMillis is null
and orderNumber = ? + 1` and orderNumber = ? + 1`
) )
.run(currentOrderNumber); .run(currentOrderNumber)
const success = updateRecordOrderNumber(recordTable, recordId, currentOrderNumber + 1, database); const success = updateRecordOrderNumber(
recordTable,
recordId,
currentOrderNumber + 1,
database
)
database.close(); database.close()
clearCacheByTableName(recordTable); clearCacheByTableName(recordTable)
return success; return success
} }
export function moveRecordDownToBottom(recordTable: RecordTable, recordId: number): boolean { export function moveRecordDownToBottom(
const database = sqlite(databasePath); recordTable: RecordTable,
recordId: number
): boolean {
const database = sqlite(databasePath)
const currentOrderNumber = getCurrentOrderNumber(recordTable, recordId, database); const currentOrderNumber = getCurrentOrderNumber(
recordTable,
recordId,
database
)
const maxOrderNumber: number = database const maxOrderNumber: number = database
.prepare( .prepare(
@ -72,10 +91,10 @@ export function moveRecordDownToBottom(recordTable: RecordTable, recordId: numbe
from ${recordTable} from ${recordTable}
where recordDelete_timeMillis is null` where recordDelete_timeMillis is null`
) )
.get().maxOrderNumber; .get().maxOrderNumber
if (currentOrderNumber !== maxOrderNumber) { if (currentOrderNumber !== maxOrderNumber) {
updateRecordOrderNumber(recordTable, recordId, maxOrderNumber + 1, database); updateRecordOrderNumber(recordTable, recordId, maxOrderNumber + 1, database)
database database
.prepare( .prepare(
@ -84,24 +103,31 @@ export function moveRecordDownToBottom(recordTable: RecordTable, recordId: numbe
where recordDelete_timeMillis is null where recordDelete_timeMillis is null
and orderNumber > ?` and orderNumber > ?`
) )
.run(currentOrderNumber); .run(currentOrderNumber)
} }
database.close(); database.close()
clearCacheByTableName(recordTable); clearCacheByTableName(recordTable)
return true; return true
} }
export function moveRecordUp(recordTable: RecordTable, recordId: number): boolean { export function moveRecordUp(
const database = sqlite(databasePath); recordTable: RecordTable,
recordId: number
): boolean {
const database = sqlite(databasePath)
const currentOrderNumber = getCurrentOrderNumber(recordTable, recordId, database); const currentOrderNumber = getCurrentOrderNumber(
recordTable,
recordId,
database
)
if (currentOrderNumber <= 0) { if (currentOrderNumber <= 0) {
database.close(); database.close()
return true; return true
} }
database database
@ -111,24 +137,36 @@ export function moveRecordUp(recordTable: RecordTable, recordId: number): boolea
where recordDelete_timeMillis is null where recordDelete_timeMillis is null
and orderNumber = ? - 1` and orderNumber = ? - 1`
) )
.run(currentOrderNumber); .run(currentOrderNumber)
const success = updateRecordOrderNumber(recordTable, recordId, currentOrderNumber - 1, database); const success = updateRecordOrderNumber(
recordTable,
recordId,
currentOrderNumber - 1,
database
)
database.close(); database.close()
clearCacheByTableName(recordTable); clearCacheByTableName(recordTable)
return success; return success
} }
export function moveRecordUpToTop(recordTable: RecordTable, recordId: number): boolean { export function moveRecordUpToTop(
const database = sqlite(databasePath); recordTable: RecordTable,
recordId: number
): boolean {
const database = sqlite(databasePath)
const currentOrderNumber = getCurrentOrderNumber(recordTable, recordId, database); const currentOrderNumber = getCurrentOrderNumber(
recordTable,
recordId,
database
)
if (currentOrderNumber > 0) { if (currentOrderNumber > 0) {
updateRecordOrderNumber(recordTable, recordId, -1, database); updateRecordOrderNumber(recordTable, recordId, -1, database)
database database
.prepare( .prepare(
@ -137,12 +175,12 @@ export function moveRecordUpToTop(recordTable: RecordTable, recordId: number): b
where recordDelete_timeMillis is null where recordDelete_timeMillis is null
and orderNumber < ?` and orderNumber < ?`
) )
.run(currentOrderNumber); .run(currentOrderNumber)
} }
database.close(); database.close()
clearCacheByTableName(recordTable); clearCacheByTableName(recordTable)
return true; return true
} }